| |
Осциллограф на PIC18
автор Геннадий Чернов
В этом разделе описан алгоритм и
приведена схемотехника построения осциллографа с применением дисплея на
контроллере SED1520.
В приведенном примере использовался
контроллер PIC18F452 и
дисплей AG-12232B. Для получения напряжения
отрицательного напряжения применялся преобразователь TC962EPA.
За основу взят проект
Audio Spectrum Monitor
схема для тестирования осциллографа
приведена на рисунке 1.
рис.1
программа на ASM.
;******************************************************************************
; *
; Filename: Oscilloscope *
; Date: *
; File Version: 01 *
; *
; Author: Chernov Gennadij *
; Company: invent-2006 *
; start 31/07/08 *
; end *
;******************************************************************************
; *
; Files required: P18F452.INC *
; *
;******************************************************************************
LIST P=18F452 ;directive to define processor
#include <P18F452.INC> ;processor specific variable
definitions
ERRORLEVEL 2
;******************************************************************************
;Configuration bits
CONFIG OSC = HSPLL ; Выбор Генератора:
CONFIG OSCS = OFF ; переключение
генератора (разрешено/неразрешено)
CONFIG PWRT = ON ; Задежка
запуска процессора при подаче питания (включена)
CONFIG BOR = ON
; Сброс по понижению питания
CONFIG BORV = 42
; Уровень напряжения срабатывания сброс при понижении питания 4,2В
CONFIG WDT = OFF ;
сторожевой таймер включен
CONFIG WDTPS = 128 ; 1:128 задежка
страбатывания сторожевого таймера.
CONFIG CCP2MUX = ON ; Разрешение переключения
вывода CCP2 OFF-на вывод RB3; ON-на вывод RC1
CONFIG STVR = ON
; сброс при переполнении стека
CONFIG LVP = OFF
; низковольное программирование ICSP
CONFIG DEBUG = OFF ; Работа
отладчика
CONFIG CP0 = ON
; защита кода блока 0 активирована
CONFIG CP1 = ON
; защита кода блока 1 активирована
CONFIG CP2 = ON
; защита кода блока 2 активирована
CONFIG CP3 = ON
; защита кода блока 3 активирована
CONFIG CPB = ON
; защита блока загрузки активирована
CONFIG CPD = ON
; защита EEPROM данных активирована
CONFIG WRT0 = ON
; защита записи в блок 0
CONFIG WRT1 = ON
; защита записи в блок 1
CONFIG WRT2 = ON
; защита записи в блок 2
CONFIG WRT3 = ON
; защита записи в блок 3
CONFIG WRTB = ON
; Защита записи в блок загрузки
CONFIG WRTC = ON
; Защита записи в регистр конфирураций
CONFIG WRTD = OFF ;
Защита записи в EEPROM память
CONFIG EBTR0 = OFF ;
Защита от табличного чтения блока памяти 0
CONFIG EBTR1 = OFF ;
Защита от табличного чтения блока памяти 1
CONFIG EBTR2 = OFF ;
Защита от табличного чтения блока памяти 2
CONFIG EBTR3 = OFF ;
Защита от табличного чтения блока памяти 3
;******************************************************************************
;Variable definitions
; These variables are only needed if low priority interrupts are used.
; More variables may be needed to store other special function registers used
; in the interrupt routines.
CBLOCK 0x00A
;========================================
flag_01
; флаги управления
;========================================
Ah,Al
; число_А
Bh,Bl
; число_Б
Ch,Cl
; число_C
Dh,Dl
; число_D
;========================================
chet_sr
;
chet_sb
;
BUFER
;
shrdis
; ширина дисплея
zadergka
;
zadergka1 ;
zadergka2 ;
urovensyn ;
уровень синхронизации осцилографа
;========================================
ENDC ;
#define FFT_N .128 ;количество измерений АЦП
CBLOCK
0x060 ; буфер загрузки данных с АЦП (+0х100)
CaptBuf: FFT_N*2 ; размер 256 байт (0x060) (128*2=256)(буфер измерений АЦП)
BflyBuf: FFT_N*4 ; размер 512 байт (0x160)
ENDC ;
;============================================================================================
; описание портов подключения дисплеев
; графический
#define LCG_D0 PORTD, 0 ; "08" LCD байт данных
#define LCG_D1 PORTD, 1 ; "09"
#define LCG_D2 PORTD, 2 ; "10"
#define LCG_D3 PORTD, 3 ; "11"
#define LCG_D4 PORTD, 4 ; "12"
#define LCG_D5 PORTD, 5 ; "13"
#define LCG_D6 PORTD, 6 ; "14"
#define LCG_D7 PORTD, 7 ; "15"
#define PA4 PORTA, 4 ; управление кнопкой
#define LCG_CL PORTC, 2 ; "04" синхронизация
#define _A0 LATB, 0 ; "01" 0 - команда, 1 - данные
#define _CS2 LATB, 1 ; "02- выбор кристала
#define _CS1 LATB, 2 ; "03"
#define _E LATB, 3 ; "05"
#define _R_W LATB, 4 ; "06"
#define _RES LATB, 5 ; "17"
;============================================================================================
; условие для регистров
; FSR0 -> X
; FSR1 -> Y
; FSR2 -> Z
#define LCD_W .122 ;Размер дисплея LCD 122x32 точки
#define LCD_H .32 ;/
#define SH_DISP .121 ; ширина дисплея 0-121/0-3
#define CIKIZM flag_01,0 ;
#define BNV flag_01,1 ;
#define BNVs flag_01,2 ;
;============================================================================================
;Reset vector
ORG 0x0000
goto Main
;============================================================================================
Main
;============================================================================================
; очистка всей памяти данных
lfsr FSR0,0
; после сброса. Установить адрес 0
ClfMem clrf
POSTINC0 ; очистить регистр и
увеличит указатель на 1
movlw 0x06
; проверить достигнут конец памяти рег. пользователя
subwf FSR0H,w
;
; movlw 0x21 ;
проверить достигнут конец памяти рег. пользователя
; subwf FSR0L,w ;
BNZ ClfMem
; если нет повторить очистку следующего регистра
;============================================================================================
clrwdt
; сброс сторожевого таймера++++++
;============================================================================================
;=========== настройка АЦП
movlw b'10000001' ; вход 0, АЦП включен.
movwf ADCON0 ;
movlw b'01001110' ; опорное AVdd
и AVss. включены вход AD0
movwf ADCON1 ;
;========================================
; настройка регистров портов
clrf PORTA ;
clrf PORTB ;
clrf PORTC ;
clrf PORTD ;
clrf PORTE ;
movlw b'00010001' ;0-аналоговый вход
movwf TRISA ;
movlw b'00000000' ;
movwf TRISB ;
movlw b'00000000' ;
movwf TRISC ;
movlw b'00000000' ;
movwf TRISD ;
movlw b'00000000' ;
movwf TRISE ;
;============================================================================================
; настройка модуля CCP1 в режиме ШИМ для формирования частоты 6-10 кГц
;для формирования тактовой частоты для LCD
; настройка таймера TMP2 ;
movlw b'00000110' ; установить предделитель на 16, и включить таймер
movwf T2CON ;
; настройка модуля CCP1 ; Режим ШИМ
#define urCCP .70 ;
movlw urCCP ; выходная 8.8 кГц
movwf PR2 ;
movlw b'00001100' ; режим шим
movwf CCP1CON ;
movlw (urCCP/2) ; скважность сигнала (меандр)
movwf CCPR1L ;
;============================================================================================
movlw SH_DISP ;
movwf shrdis ;
;============================================================================================
rcall LCDinit ; инциализация дисплея
rcall GLCD_clear ; ОЧИСТКА ДИСПЛЕЯ
;============================================================================================
;============================================================================================
movlw 0x7F ; загрузка уровня синхронизации
movwf urovensyn ;
ADC_cikl
movlw FFT_N ;
movwf Bl ; загрузить счетчик измерений
clrwdt ; сброс сторожевого таймера++++++
lfsr FSR0,CaptBuf ; инициализация указателя буфера записи
clrf Bh ; инициализация счетчика ожидания сигнала
bcf BNV ; бит значение ниже точки синхронизации найлено
bcf BNVs ; бит поиск точки синхронизации выполнен
izacp
clrwdt ; сброс сторожевого таймера++++++
bsf ADCON0,GO ; запустить преобразование АЦП
btfsc ADCON0,GO ; ожидать окончание
bra $-.2 ;
incfsz Bh,f ;
bra $+.4 ; проверить згачение достигло 128 измерений
bsf BNVs ; переполнение счеткика ожидания сигнала
btfsc BNVs ;
bra zagruz ;
btfsc BNV ;
bra bol ;
movf urovensyn,w ;ищем значение ниже точки синхронизации
subwf ADRESH,w ;
btfss STATUS,C ;
bsf BNV ;
bra izacp ;
bol
movf urovensyn,w ;затем значение выше точки синхронизации
subwf ADRESH,w ;
btfss STATUS,C ;
bra izacp ;
bsf BNVs ;
zagruz
movlw 0x80 ; формирование данных в виде сигнала с нулем в середине
subwf ADRESH,f ; диапазонна
movff ADRESL,POSTINC0 ; загрузка данных
movff ADRESH,POSTINC0 ;(младший байт с начала)
; clrf Bh ;
; decfsz Bh,f ; растяжка
; bra $-.2 ;
; movlw .50 ;
; movwf Bh ;
; decfsz Bh,f ;
; bra $-.2 ;
; decfsz Bh,f ;
; bra $-.2 ;
; decfsz Bh,f ;
; bra $-.2 ;
decfsz Bl,f ; увеличить счетчик записей проверить згачение достигло
128 измерений
bra izacp ; нет не достишло повторить измерение
; movlw .3 ; задержка вывода на экран
; movwf zadergka ;
; decfsz zadergka2 ;
; bra $-.2 ;
; decfsz zadergka1 ;
; bra $-.6 ;
; decfsz zadergka ;
; bra $-.10 ;
;----------------------------------------
rcall make_wave ;формирование сигнала графика осцилограммы (389 us)
rcall rfsh_wave ;вывод информации на дисплей (403 us)
;----------------------------------------
clrwdt ; сброс сторожевого таймера++++++
bra ADC_cikl
;============================================================================================
;============================================================================================
;-----------------------------------------
;Осцилограф
make_wave
; загрузка 122 значений из буфера АЦП для обработки на вывод на экран
lfsr FSR2,CaptBuf ;Z загрузть адрес начала CaptBuf
lfsr FSR1,BflyBuf ;Y загрузть адрес начала BflyBuf
movlw LCD_W ;загрузить значение счетчика (0х3A -- .58)
movwf Cl ;/
predA
movff POSTINC2,Al ; Чтение Z+ - > A
movff POSTINC2,Ah ;/
movlw 0x80 ;суммировать значение А с 32768
addwf Ah,f ;преобразование в положительные значения
;предразования данных к размеру индикатора
;данные в диапазоне 0-255, диапазон индикатора 0-31 (делим на 8)
bcf STATUS,C ;
rrcf Ah ;AL /= 2048 (LCD Y position)
bcf STATUS,C ;
rrcf Ah ;
bcf STATUS,C ;
rrcf Ah ;/
movff Ah,POSTINC1 ; Запись Al - > Y+
decfsz Cl,f ;Repeat times
bra predA ;
;-----------------------------------------
;Очистка буфера для формирования рисунка осцилограммы
;очищается буфер размером 122*2, что соответствует области
;выделенной для индикации осцилограммы на LCD
movlw (LCD_W*2) ;
movwf Cl ;
clrf POSTINC1 ; clrf -> Y+
decfsz Cl, f ;
bra $-.4 ;/
movlw (LCD_W*2) ;
movwf Cl ;
clrf POSTINC1 ; clrf -> Y+
decfsz Cl, f ;
bra $-.4 ;/
;-----------------------------------------
;Вернуть указатель в начало первой строки индикатора
;указатель находиться в конце буфера очистки
movlw LCD_W ; найти разницу FSR1-LCD_W -> FSR1
subwf FSR1L,f ; установка указателя на начало сторки )
btfss STATUS,C ;
decf FSR1H,f ;/
;-----------------------------------------
;Преобразование данных в форму графика
lfsr FSR2,BflyBuf ; Z загрузть адрес начала BflyBuf
movff INDF2,Al ; Чтение Al - > Z
movff Al,Ah ; Al->Ah
movlw .7 ; рисование положения точки
andwf Al ; (Bl) в зависимости от данных
movlw 0x80 ; значение имеют только 3 младших разрядя
movwf Bl ;
bra $+.4 ; значение 128 делиться на значение Al**2
rrncf Bl,f ;
decf Al,f ;
BC $-.4 ;
rrncf Ah ;определение положения строки (0 нижняя 3 верняя)
rrncf Ah ;деление на 8
rrncf Ah ;/
movlw .3 ;ограничение величины в диапазоне
andwf Ah ;0-3 (количество строк в индикаторе)
movlw LCD_W ;умножение текущей строки на количество точек в строке
mulwf Ah ;для нахождения смещения первой ячейки осцилограммы
;-----------------------------------------
; нахождение кординаты первой ячейки памяти для записи
; отнимем от начала коортдинат смещение положения первой ячейки
; получаем адрес в памяти для записи данных (указатель Y)
movf PRODL,w ; найти разницу A-D -> A
subwf FSR1L,f ;
movf PRODH,w ;
subwfb FSR1H,f ;/
; установить счетчик заисываемых ячеек (на единицу меньше)
movlw (LCD_W-.1) ;
movwf Dh ;
;-----------------------------------------
dn_l1:
; загрузим текущее и сделующее значение для вычисления растояния между точками
; загрузка
movff POSTINC2,Cl ;Z
movff INDF2,Ch ;
;находим растояние
movf Ch,w ;
subwf Cl,f ;
;сохраним полученное значение в регистре Dl
movff Cl,Dl ; значение растояния
;если величина отрицательна, преобразовать в положительную
BC $+.4 ;
negf Cl ;
;сохранить растояние в регистре Ch и разделить на 2
movff Cl,Ch ;
bcf STATUS,C ;
RRCF Ch ; значение половинного растояния
;-----------------------------------------
dn_l2:
;Наложение полученной прорисовки точки на текущюю ячейку
movff INDF1,Al ; Чтение Y - > AL
movf Bl,w ;
iorwf Al,f ;
movff Al,INDF1 ; Чтение AL - > Y
;-----------------------------------------
; если Ch = 0
decf Ch,f ; уменьшить сшетчик половинного интервала
btfss STATUS,C ; если выполнент перенос
movf PREINC1,w ; увеличить указатель Y
;-----------------------------------------
movlw .0 ; сравнить растояние между точками равно 0
cpfseq Dl ;
bra $+.4
bra subiCL ; если Dl=нулю
btfsc Dl,7 ; если Dl отрицательно
bra lsrBL ;
bcf STATUS,C ;
rlcf Bl,f ; сдвиг в лево
BNZ subiCL ;
movlw .1 ;
movwf Bl ;
movlw LCD_W ;
addwf FSR1L,f ;
btfsc STATUS,C ;
incf FSR1H,f ;
bra subiCL ;
lsrBL
bcf STATUS,C ;
rrcf Bl,f ; сдвиг в право
BNZ subiCL ;
movlw 0x80 ;
movwf Bl ;
movlw LCD_W ;
subwf FSR1L,f ;
btfss STATUS,C ;
decf FSR1H,f ;
subiCL
decf Cl,f ;
BNC $+.4 ;
BNZ dn_l2 ;
decfsz Dh,f ;
bra dn_l1 ;
return ;
;============================================================================================
rfsh_wave ; вывод на LCD графика осцилографа
clrf Bl ; инницализация счетчика цикла
clrf Bh ;
clrf chet_sb ; счетчик столбца для вывода на индикатор
lfsr FSR1, BflyBuf+LCD_W ; начало буфера осцилограммы
movlw b'10111000' ; указатель страниц в ноль
movwf chet_sr ; счетчик страниц
movwf LATD ;
movlw b'00101000' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
nop ; необходимая задержка
bcf _E ; активировать процедуру
movlw b'00111111' ; вернуть сигналы в исходное
iorwf LATB ;
clrf LATD ; указатель столбца в ноль
movlw b'00101000' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
nop ; необходимая задержка
bcf _E ;
movlw b'00111111' ; активировать процедуру
iorwf LATB ;
;цикл вывода на дисплей
povt
movf POSTINC1,w ; чтение данных из буфера
rcall Zap_bayta ;
ertwer
incf Bl,f ;
btfsc STATUS,C ;
incf Bh,f ;
movlw HIGH (LCD_W*4) ;размер буфера данных 58*4=232
cpfseq Bh ;сравнить на окончания чтения буфера
bra povt ;
movlw LOW (LCD_W*4) ;размер буфера данных 58*4=232
cpfseq Bl ;сравнить на окончания чтения буфера
bra povt ;
return ;
;============================================================================================
;============================================================================================
Zap_bayta ; запись байта с инкрементом
movwf BUFER ;
movf chet_sr,w ; выбор следующей страницы
andlw b'00000011' ; коррекция значения страницы в диапазоне 0-3
movwf chet_sr ;/
iorlw b'10111000' ; загрузка адреса страницы
rcall Wr_com ;/
;-------------------------------------------
movf shrdis,w ;если значение столбца больше ширины дисплея
cpfsgt chet_sb ;прировнять его значение к ширине дисплея
bra $+.4 ;
movwf chet_sb ; /
;-------------------------------------------
movlw .61 ; выбор чипа для записи
cpfslt chet_sb ; пропустить следующую команду, если f < WREG
bra zp2ch ; /
;-------------------------------------------
movf chet_sb,w ; загрузить значение столбца
rcall Wr_com ;/
movf BUFER,w ;записать данные изображения в чип1
rcall Wr_dat1 ;/
bra incmch1 ;
;-------------------------------------------
zp2ch movlw .61 ;корректировать
адрес для загрузки
subwf chet_sb,w ;
rcall Wr_com ;/
movf BUFER,w ;записать данные изображения в чип2
rcall Wr_dat2 ;/
;-------------------------------------------
incmch1 incf chet_sb,f ;инкремирование счетчиков
movf shrdis,w ;стобца и строки (ширины дисплея)
cpfsgt chet_sb ; > 121
return ;
clrf chet_sb ; вернуть адрес столбца в ноль
incf chet_sr,f ;
movlw .3 ; проверить счетчик страницы =4
cpfsgt chet_sr ;> 3
return ;
clrf chet_sr ; вернуть адрес строки в ноль
return ;
;============================================================================================
LCDinit ; инициализация дисплея
; сброс и установка интерфейса (80)
bsf _RES ;
bsf _A0 ;
bsf _E ;
bsf _R_W ;
bsf _CS1 ;
bsf _CS2 ;
; Настройка SED1520 LCD ;
;a. Reset
; movlw b'11100010' ;
; call Wr_com ;
;a. Изображение выкл.
movlw b'10101110' ;
rcall Wr_com ;
;c. Статическое управление выкл.
movlw b'10100100' ;
rcall Wr_com ;
;b. Регистр начальной строки вывода изображения: Первая строка.
movlw b'11000000' ;
rcall Wr_com ;
;d. Счётчик адреса столбца: Адрес 0.
movlw b'00000000' ;
rcall Wr_com ;
;e. Регистр адреса страницы: Страница 0.
movlw b'10111000' ;
rcall Wr_com ;
;f. Выбрать скважность: 1/32.
movlw b'10101001' ;
rcall Wr_com ;
;g. Выбрать ADC: Вперёд "слева на право" (Команда ADC D0 = "0", флаг состояния
ADC = "1").
movlw b'10100000' ;
rcall Wr_com ;
;h. Чтение модификация запись выкл.
movlw b'11101110' ; выкл
; movlw b'11100000' ; вкл
rcall Wr_com ;
;a. Изображение вкл.
movlw b'10101111' ;
rcall Wr_com ;
return ;
;============================================================================================
;============================================================================================
GLCD_clear ; Очистка дисплея
;Команда Чтение/модификация/запись выкл.
movlw b'11101110' ; команда - "Завершить"
rcall Wr_com ;
clrf chet_sr ; очистка счетчика страниц
; установить курсор на нулевую сраницу в нулевой столбец
movlw b'00000000' ; установить адрес столбца = 0 (адрес 0-79/6-бит)
rcall Wr_com ;
movlw b'10111000' ; установить адрес страницы = 0 (0-3/2-бита)
rcall Wr_com ;
;========================================
poct
incf chet_sr,f ;
movlw .61 ;
movwf chet_sb ;
syclj
clrwdt ; сброс сторожевого таймера++++++
movlw 0x00 ; очистка страницы
rcall Wr_dat ;
decfsz chet_sb ;
bra syclj ;
movlw b'00000000' ; вернуть адрес столбца в ноль
rcall Wr_com ;
movf chet_sr,w ; выбор следующей страницы
iorlw b'10111000' ;
rcall Wr_com ;
movlw .4 ; проверить счетчик страницы =4
cpfseq chet_sr ;
bra poct ;
; установить курсор на нулевую сраницу в нулевой столбец
movlw b'00000000' ;
rcall Wr_com ;
movlw b'10111000' ;
rcall Wr_com ;
return ;
;============================================================================================
;============================================================================================
Wr_com ; запись команды в оба чипа
movwf LATD ;
movlw b'00101000' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
nop ; необходимая задержка
bcf _E ; активировать процедуру
movlw b'00111111' ; вернуть сигналы в исходное
orwf LATB ;
return ;
;============================================================================================
;============================================================================================
Wr_dat ; запись изображения в оба чипа
movwf LATD ;
movlw b'00101001' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
; nop ; необходимая задержка
bcf _E ; активировать процедуру
movlw b'00111111' ; вернуть сигналы в исходное
iorwf LATB ;
return ;
;============================================================================================
;============================================================================================
Wr_dat2 ; запись в чипа 2
movwf LATD ;
movlw b'00101101' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
; nop ; необходимая задержка
bcf _E ; активировать процедуру
movlw b'00111111' ;
iorwf LATB ;
return ;
;============================================================================================
;============================================================================================
Wr_dat1 ; запись в чипа 1
movwf LATD ;
movlw b'00101011' ; n/n/_RES/_R_W/_E/_CS1/_CS2/_A0
andwf LATB ;
bcf _E ; активировать процедуру
movlw b'00111111' ;
iorwf LATB ;
return ;
;============================================================================================
;============================================================================================
;End of program
END
За дополнительной информацией обращайтесь на
Форум
Invent-Systems
Для получения дополнительной информации используйте:
MAGETEX
Ukraine
Телефон: +380-50-575-98-63
Факс: +380-50-575-98-63
Интернет:
invent-systems@ya.ru
|