Например TDA7294

Форум РадиоКот • Просмотр темы - 16F876A Вольтамперметр. Проблемы Исходника
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пн дек 22, 2025 02:36:00

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 16:01:35 
Встал на лапы
Аватар пользователя

Карма: 9
Рейтинг сообщений: 53
Зарегистрирован: Чт авг 16, 2012 10:41:42
Сообщений: 99
Рейтинг сообщения: 0
Пишу свою первую прошивку на 16F876A. Вольтамперметр. Написал для начала исходник для вольтметра. Результаты показаний на дисплее отображаются корректно. Вот исходник.

Код:
         LIST     p=16F876A
         #include <P16F876A.inc>
         __CONFIG (_LVP_OFF & _CP_OFF & _CPD_OFF & _PWRTE_OFF & _WDT_ON & _XT_OSC & _BODEN_ON & _DEBUG_OFF )

cblock     0x20
LCD_tmp
LCD_tmp1
Reg_tmp1
Reg_tmp2
lcd_load
Reg_tmpL
Reg_tmpH
bin1
bin2
bcd1
bcd2
bcd3
TenK
Thou
Hund
Tens
Ones
ctr
endc   

#define RS_LCD         LCD_tmp1,RA4 ; назначаем вывод команд RS на PORTA для LCD
#define E_LCD         LCD_tmp1,RA5 ; назначаем вывод команд E на PORTA для LCD
#define LCD_PORT_E_RS PORTA         ; назначаем порт для вывода данных PORTB для LCD
#define LCD_PORT     PORTC         ; назначаем порт для вывода данных PORTC для LCD (8 разрядов)
                         ;;;;;;;;;;;;;;;;;;;
                         ; старт программы ;
                         ;;;;;;;;;;;;;;;;;;;
         org         0
         goto     START
                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                         ; инициализация контроллера ;
                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START     bcf         STATUS,RP0 ; переход в банк 0
         banksel     OPTION_REG ; переходим в регистр OPTION_REG
         movlw     b'10001110' ; отключаем подтягивающие резисторы PORTB, включаем предделитель перед WDT 1:64
         movwf     OPTION_REG ; -//-
         banksel     INTCON     ; переходим в регистр INTCON
         movlw     b'00000000' ; глобальный запрет прерываний
         movwf     INTCON     ; -//-
         banksel     PIE1         ; переходим в регистр PIE1
         movlw     b'00000000' ; глобальный запрет периферийных прерываний
         movwf     PIE1         ; -//-
         banksel     PIE2         ; переходим в регистр PIE2
         movlw     b'00000000' ; глобальный запрет прерываний EEPROM, CCP2
         movwf     PIE2         ; -//-
         banksel     TRISA         ; переходим в регистр PORTA
         movlw     b'00000011' ; настраиваем все порты на выход, AN0, AN1 на вход
         movwf     TRISA         ; -//-
         banksel     TRISB         ; переходим в регистр PORTB
         movlw     b'00000000' ; настраиваем все порты на выход
         movwf     TRISB         ; -//-
         banksel     TRISC         ; переходим в регистр PORTC
         movlw     b'00000000' ; настраиваем все порты на выход
         movwf     TRISC         ; -//-
         banksel     T1CON         ; переходим в регистр T1CON
         movlw     b'00000000' ; отключаем модуль T1CON
         movwf     T1CON         ; -//-
         banksel     T2CON         ; переходим в регистр T2CON
         movlw     b'00000000' ; отключаем модуль T2CON
         movwf     T2CON         ; -//-
         banksel     CCP1CON     ; переходим в регистр CCP1CON
         movlw     b'00000000' ; отключаем модуль CCP1
         movwf     CCP1CON     ; -//-
         banksel     CCP2CON     ; переходим в регистр CCP2CON
         movlw     b'00000000' ; отключаем модуль CCP2
         movwf     CCP2CON     ; -//-
         banksel     SSPSTAT     ; переходим в регистр SSPSTAT
         movlw     b'00000000' ; отключаем модуль SSPSTAT
         movwf     SSPSTAT     ; -//-
         banksel     SSPCON     ; переходим в регистр SSPCON
         movlw     b'00000000' ; отключаем модуль SSPCON
         movwf     SSPCON     ; -//-
         banksel     SSPCON2     ; переходим в регистр SSPCON2
         movlw     b'00000000' ; отключаем модуль SSPCON2
         movwf     SSPCON2     ; -//-
         banksel     TXSTA         ; переходим в регистр TXSTA
         movlw     b'00000000' ; отключаем модуль TXSTA
         movwf     TXSTA         ; -//-
         banksel     RCSTA         ; переходим в регистр RCSTA
         movlw     b'00000000' ; отключаем модуль RCSTA
         movwf     RCSTA         ; -//-
         banksel     ADCON0     ; переходим в регистр ADCON0
         movlw     b'00000000' ; отключаем модуль АЦП
         movwf     ADCON0     ; -//-
         banksel     ADCON1     ; переходим в регистр ADCON1
         movlw     b'00000000' ; отключаем модуль АЦП
         movwf     ADCON1     ; -//-
         bsf         STATUS,RP0 ; переход в банк 1
         bcf         STATUS,RP0 ; переход в банк 0
         clrwdt
                         ;;;;;;;;;;;;;;;;;;;;;;;;;
                         ; инициализация дисплея ;
                         ;;;;;;;;;;;;;;;;;;;;;;;;;
         call     del_100ms     ; начальная задержка 100 милисекунд
         movlw     b'00000001' ; очищаем дисплей
         call     LCD_com     ; загружаем команду
         call     del_5ms
         movlw     b'00000110' ; сдвиг курсора вправо
         call     LCD_com     ; загружаем команду
         movlw     b'00001100' ; отключаем курсор
         call     LCD_com     ; загружаем команду
         movlw     b'00010100' ; двигаем курсор вправо
         call     LCD_com     ; загружаем команду
         movlw     b'00111000' ; вкл 8 разрядный ввод данных, размер символа 5х8 символов
         call     LCD_com     ; загружаем команду   
gooo   
         call     OUT_U         ; отправляемся читать данные АЦП, и вывод данных на дисплей
;         call     OUT_I         ; отправляемся читать данные АЦП, и вывод данных на дисплей
         call     del_100ms
         call     del_100ms
         clrwdt
         goto     gooo

OUT_U ; выводим U на дисплей содержимое регистров Thou, Hund, Tens, Ones (тысячи, сотни, десятки, единицы)
         banksel     ADCON0     ; переходим в регистр ADCON0
         movlw     b'01000001' ; включаем модуль АЦП, RA0 - вход, Fosc/8
         movwf     ADCON0     ; -//-
         banksel     ADCON1     ; переходим в регистр ADCON1
         movlw     b'10000000' ; включаем правое выравнивание
         movwf     ADCON1     ; -//-
         bcf         STATUS,RP0 ; переход в банк 0
         bsf         ADCON0,2     ; включаем преобразование АЦП
         call     del_20mcs
         btfsc     ADCON0,2     ; ожидаем завершения
         goto     $-1         ; преобразования
         movfw     ADRESH     ; перепишем результат преобразования
         movwf     Reg_tmpH     ; в старший временный регистр
         banksel     ADRESL     ; переходим в регистр ADRESL
         movfw     ADRESL     ; перепишем результат преобразования
         bcf         STATUS,RP0 ; переход в банк 0
         movwf     Reg_tmpL     ; в младший временный регистр

         call     TRANSFORMER_dig ; перекодируем двоичное число результата преобразования в десятичное
         movlw     0x80         ; курсор в пределах первой строки ( 0x80 - начало )
         call     LCD_com     ; загружаем команду
         movlw     0x55         ; U
         call     LCD_dig     ; загружаем данные
         movlw     0x3D         ; =
         call     LCD_dig     ; загружаем данные
         movf     Thou,W     ; копируем в W содержимое Thou
         btfsc     Thou,0     ; проверяем значение регистра тысячных показаний, если 1, значит переполнение показаний
         goto     overflow_U ; отправляемся отображать 9,99V
         movf     Hund,W     ; копируем в W содержимое Hund
         call     TABL_dig     ; отправляем на дисплей содержимое Hund
         call     LCD_dig     ; загружаем данные
         movlw     0x2C         ; ,
         call     LCD_dig     ; загружаем данные
         movf     Tens,W     ; копируем в W содержимое Tens
         call     TABL_dig     ; отправляем на дисплей содержимое Tens
         call     LCD_dig     ; загружаем данные
         movf     Ones,W     ; копируем в W содержимое Ones
         call     TABL_dig     ; отправляем на дисплей содержимое Ones
         call     LCD_dig     ; загружаем данные
         movlw     0x56         ; V
         call     LCD_dig     ; загружаем данные
         return
overflow_U movlw     0x39         ; 9 (выводим 9,99V вместо 10,23V)
         call     LCD_dig     ; загружаем данные
         movlw     0x2C         ; ,
         call     LCD_dig     ; -//-
         movlw     0x39         ; 9
         call     LCD_dig     ; загружаем данные
         movlw     0x39         ; 9
         call     LCD_dig     ; загружаем данные
         movlw     0x56         ; V
         call     LCD_dig     ; загружаем данные
         return

                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                         ; Подпрограмма трансформации двоичного числа в десятичное ;
                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TRANSFORMER_dig
         movf     Reg_tmpL,W ; копируем младший байт результата преобразования АЦП в
         movwf     bin2         ; в bin2           
         movf     Reg_tmpH,W ; копируем старший байт результата преобразования АЦП в
         movwf     bin1         ; в bin1
;bin2 = младший байт преобразуемого числа
;bin1 = старший байт преобразуемого числа
;bcd3 ( младший полубайт ) = единицы
;bcd3 ( старший полубайт ) = десятки
;bcd2 ( младший полубайт ) = сотни
;bcd2 ( старший полубайт ) = тысячи
;bcd1 ( младший полубайт ) = десятки тысяч                                       
         movlw     .16
         movwf     ctr
         clrf     bcd1
         clrf     bcd2
         clrf     bcd3
         goto     start
adjdec     movlw     0x33
         addwf     bcd1,f
         addwf     bcd2,f
         addwf     bcd3,f
         movlw     0x03
         btfss     bcd1,3
         subwf     bcd1,f
         btfss     bcd2,3
         subwf     bcd2,f
         btfss     bcd3,3
         subwf     bcd3,f
         movlw     0x30
         btfss     bcd1,7
         subwf     bcd1,f
         btfss     bcd2,7
         subwf     bcd2,f
         btfss     bcd3,7
         subwf     bcd3,f
start     rlf         bin2,f
         rlf         bin1,f
         rlf         bcd3,f
         rlf         bcd2,f
         rlf         bcd1,f
         decfsz     ctr,f
         goto     adjdec     ; окончание конвертирования               
         movf     bcd1,w     ; распределение результата по регистрам   
         movwf     TenK         ; десятки тысяч
         swapf     bcd2,w
         movwf     Thou         ; тысячи
         movf     bcd2,w
         movwf     Hund         ; сотни
         swapf     bcd3,w
         movwf     Tens         ; десятки
         movf     bcd3,w
         movwf     Ones         ; единицы
         return   
TABL_dig andlw     b'00001111' ; маскируем старший полубайт W (обнуляем 4 старших байта)
         addwf     PCL,f         ; Содержимое счетчика команд PC увеличивается на величину содержимого аккумулятора W.
         retlw     0x30         ; 0
         retlw     0x31         ; 1
         retlw     0x32         ; 2
         retlw     0x33         ; 3
         retlw     0x34         ; 4
         retlw     0x35         ; 5
         retlw     0x36         ; 6
         retlw     0x37         ; 7
         retlw     0x38         ; 8
         retlw     0x39         ; 9
         retlw     0x41         ; A
         retlw     0x42         ; B
         retlw     0x43         ; C
         retlw     0x44         ; D
         retlw     0x45         ; E
         retlw     0x46         ; F
                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                         ; Подпрограмма вывода данных на HD44780 ;
                         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; загрузка комманды
LCD_com     movwf     LCD_tmp       
         call     E_0
         call     RS_0
         call     LCD_load
         return   
; загрузка цифры
LCD_dig     movwf     LCD_tmp       
         call     E_0
         call     RS_1
         call     LCD_load
         return

; загрузка данных непосредственно в дисплей со стробированием
LCD_load movf     LCD_tmp,W       
         movwf     LCD_PORT
         call     del_1ms
         call     E_1
         call     del_1ms
         call     E_0
         call     del_1ms
         return
E_0         bcf         E_LCD
         movf     LCD_tmp1,W
         movwf     LCD_PORT_E_RS       
         return
E_1         bsf         E_LCD
         movf     LCD_tmp1,W
         movwf     LCD_PORT_E_RS       
         return
RS_0     bcf         RS_LCD
         movf     LCD_tmp1,W
         movwf     LCD_PORT_E_RS       
         return
RS_1     bsf         RS_LCD
         movf     LCD_tmp1,W
         movwf     LCD_PORT_E_RS       
         return
; ЗАДЕРЖКА 5 ms
del_5ms     call     del_1ms
         call     del_1ms
         call     del_1ms
         call     del_1ms
         call     del_1ms
         return
; ЗАДЕРЖКА 100 ms
del_100ms call del_50ms
         call del_50ms
         return

; ЗАДЕРЖКА 50 ms
del_50ms movlw     .238
         movwf     Reg_tmp1
         movlw     .65
         movwf     Reg_tmp2
wr1         decfsz     Reg_tmp1, F
         goto     wr1
         decfsz     Reg_tmp2, F
         goto     wr1
         return                               
; ЗАДЕРЖКА 1 ms
del_1ms     movlw     .75
         movwf     Reg_tmp1
         movlw     .2
         movwf     Reg_tmp2
wr2         decfsz     Reg_tmp1, F
         goto     wr2
         decfsz     Reg_tmp2, F
         goto     wr2
         return
;delay = 20 machine cycles
del_20mcs movlw     .6
         movwf     Reg_tmp1
wr3         decfsz     Reg_tmp1, F
         goto     wr3
         return
         end

Но при попытке добавить в исходник OUT_I подпрограмму для вывода показаний амперметра - программа неимоверно глючит. На дисплее моргает U= и ничего не происходит. Все виснет даже если я не вызываю подпрограмму OUT_I... Но если я убираю из исходника подпрограмму OUT_U то все работает но уже в режиме показаний амперметра. Подпрограммы OUT_U и OUT_I никак не хотят вместе дружить. А по отдельности все прекрасно работает. Помогите - не знаю куда копать!!! Метки менял. Среда разработки MPLAB IDE v8.66. Прошиваю PICkit 2
Вот подпрограмма.

Код:
OUT_I ; выводим I на дисплей содержимое регистров Thou, Hund, Tens, Ones (тысячи, сотни, десятки, единицы)
         banksel     ADCON0     ; переходим в регистр ADCON0
         movlw     b'01001001' ; включаем модуль АЦП, RA1 - вход, Fosc/8
         movwf     ADCON0     ; -//-
         banksel     ADCON1     ; переходим в регистр ADCON1
         movlw     b'10000000' ; включаем правое выравнивание
         movwf     ADCON1     ; -//-
         bcf         STATUS,RP0 ; переход в банк 0
         bsf         ADCON0,2     ; включаем преобразование АЦП
         call     del_20mcs
         btfsc     ADCON0,2     ; ожидаем завершения
         goto     $-1         ; преобразования
         movfw     ADRESH     ; перепишем результат преобразования
         movwf     Reg_tmpH     ; в старший временный регистр
         banksel     ADRESL     ; переходим в регистр ADRESL
         movfw     ADRESL     ; перепишем результат преобразования
         bcf         STATUS,RP0 ; переход в банк 0
         movwf     Reg_tmpL     ; в младший временный регистр

         call     TRANSFORMER_dig ; перекодируем двоичное число результата преобразования в десятичное
         movlw     0xC0         ; курсор в пределах второй строки ( 0xС0 - начало )
         call     LCD_com     ; загружаем команду
         movlw     0x49         ; I
         call     LCD_dig     ; загружаем данные
         movlw     0x3D         ; =
         call     LCD_dig     ; загружаем данные
         movf     Thou,W     ; копируем в W содержимое Thou
         btfsc     Thou,0     ; проверяем значение регистра тысячных показаний, если 1, значит переполнение показаний
goto overflow_I ; отправляемся отображать 9,99А
         movf     Hund,W     ; копируем в W содержимое Hund
         call     TABL_dig     ; отправляем на дисплей содержимое Hund
         call     LCD_dig     ; загружаем данные
         movlw     0x2C         ; ,
         call     LCD_dig     ; загружаем данные
         movf     Tens,W     ; копируем в W содержимое Tens
         call     TABL_dig     ; отправляем на дисплей содержимое Tens
         call     LCD_dig     ; загружаем данные
         movf     Ones,W     ; копируем в W содержимое Ones
         call     TABL_dig     ; отправляем на дисплей содержимое Ones
         call     LCD_dig     ; загружаем данные
         movlw     0x41         ; A
         call     LCD_dig     ; загружаем данные
         return
overflow_I movlw 0x39 ; 9 (выводим 9,99А вместо 10,23А)
         call     LCD_dig     ; загружаем данные
         movlw     0x2C         ; ,
         call     LCD_dig     ; -//-
         movlw     0x39         ; 9
         call     LCD_dig     ; загружаем данные
         movlw     0x39         ; 9
         call     LCD_dig     ; загружаем данные
         movlw     0x41         ; A
         call     LCD_dig     ; загружаем данные
         return


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 17:02:49 
Друг Кота

Карма: 27
Рейтинг сообщений: 1283
Зарегистрирован: Ср фев 11, 2009 20:35:58
Сообщений: 7853
Рейтинг сообщения: 0
Цитата:
Пишу свою первую прошивку

Может переписываеш у ЗАЕЦа ?
Не вижу переход на OUT_I. :shock:
Оформи CBLOCK через EQU, замени $ на метки и выкладывай весь проект.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 17:13:50 
Грызет канифоль

Зарегистрирован: Вт окт 08, 2013 07:38:59
Сообщений: 256
Откуда: СПб
Рейтинг сообщения: -1
Пока вижу у Вас неправильный вызов ПП "TABL_dig".
Почитайте внимательно про организацию памяти ОЗУ в 16-х ПИКах.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 17:41:29 
Встал на лапы
Аватар пользователя

Карма: 9
Рейтинг сообщений: 53
Зарегистрирован: Чт авг 16, 2012 10:41:42
Сообщений: 99
Рейтинг сообщения: 0
Не знаю я никакого ЗАЕЦа :o . Единственное что я использовал из чужих трудов в разработке своей программы лежит в прикрепленном Файле. Автор Blaze. Если Вам не трудно - дайте ссылку на труды ЗАЕЦа в разработке аналогичного устройства.
Не видите перехода на OUT_I потому что даже без перехода в эту ПП все глючит. Глюки исчезают при полном удалении ПП OUT_I или OUT_U. Работают они по отдельности, а вместе не хотят.
Smen поищу. А как правильно вызвать ПП?
Вот полный проект.
Код:
            LIST      p=16F876A
            #include  <P16F876A.inc>
            __CONFIG  (_LVP_OFF & _CP_OFF & _CPD_OFF & _PWRTE_OFF & _WDT_ON & _XT_OSC & _BODEN_ON & _DEBUG_OFF )
 

LCD_tmp   EQU       0x20
LCD_tmp1  EQU       0x21
Reg_tmp1  EQU       0x22
Reg_tmp2  EQU       0x23
lcd_load  EQU       0x24
Reg_tmpL  EQU       0x25
Reg_tmpH  EQU       0x26
bin1      EQU       0x27
bin2      EQU       0x28
bcd1      EQU       0x29
bcd2      EQU       0x2A
bcd3      EQU       0x2B
TenK      EQU       0x2C
Thou      EQU       0x2D
Hund      EQU       0x2E
Tens      EQU       0x2F
Ones      EQU       0x30
ctr       EQU       0x31
   


#define RS_LCD          LCD_tmp1,RB4  ; назначаем вывод команд RS на PORTA для LCD
#define E_LCD           LCD_tmp1,RB5  ; назначаем вывод команд E на PORTA для LCD
#define LCD_PORT_E_RS   PORTB         ; назначаем порт для вывода данных PORTB для LCD
#define LCD_PORT        PORTC         ; назначаем порт для вывода данных PORTC для LCD (8 разрядов)

                            ;;;;;;;;;;;;;;;;;;;
                            ; старт программы ;
                            ;;;;;;;;;;;;;;;;;;;
            org         0
            goto        START
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ; инициализация контроллера ;
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START       bcf         STATUS,RP0    ; переход в банк 0
            banksel     OPTION_REG    ; переходим в регистр OPTION_REG
            movlw       b'10001110'   ; отключаем подтягивающие резисторы PORTB, включаем предделитель перед WDT 1:64
            movwf       OPTION_REG    ; -//-
            banksel     INTCON        ; переходим в регистр INTCON
            movlw       b'00000000'   ; глобальный запрет прерываний
            movwf       INTCON        ; -//-
            banksel     PIE1          ; переходим в регистр PIE1
            movlw       b'00000000'   ; глобальный запрет периферийных прерываний
            movwf       PIE1          ; -//-
            banksel     PIE2          ; переходим в регистр PIE2
            movlw       b'00000000'   ; глобальный запрет прерываний EEPROM, CCP2
            movwf       PIE2          ; -//-
            banksel     TRISA         ; переходим в регистр PORTA
            movlw       b'00000011'   ; настраиваем все порты на выход, AN0, AN1 на вход
            movwf       TRISA         ; -//-
            banksel     TRISB         ; переходим в регистр PORTB
            movlw       b'00000000'   ; настраиваем все порты на выход
            movwf       TRISB         ; -//-
            banksel     TRISC         ; переходим в регистр PORTC
            movlw       b'00000000'   ; настраиваем все порты на выход
            movwf       TRISC         ; -//-
            banksel     T1CON         ; переходим в регистр T1CON
            movlw       b'00000000'   ; отключаем модуль T1CON
            movwf       T1CON         ; -//-
            banksel     T2CON         ; переходим в регистр T2CON
            movlw       b'00000000'   ; отключаем модуль T2CON
            movwf       T2CON         ; -//-
            banksel     CCP1CON       ; переходим в регистр CCP1CON
            movlw       b'00000000'   ; отключаем модуль CCP1
            movwf       CCP1CON       ; -//-
            banksel     CCP2CON       ; переходим в регистр CCP2CON
            movlw       b'00000000'   ; отключаем модуль CCP2
            movwf       CCP2CON       ; -//-
            banksel     SSPSTAT       ; переходим в регистр SSPSTAT
            movlw       b'00000000'   ; отключаем модуль SSPSTAT
            movwf       SSPSTAT       ; -//-
            banksel     SSPCON        ; переходим в регистр SSPCON
            movlw       b'00000000'   ; отключаем модуль SSPCON
            movwf       SSPCON        ; -//-
            banksel     SSPCON2       ; переходим в регистр SSPCON2
            movlw       b'00000000'   ; отключаем модуль SSPCON2
            movwf       SSPCON2       ; -//- 
            banksel     TXSTA         ; переходим в регистр TXSTA
            movlw       b'00000000'   ; отключаем модуль TXSTA
            movwf       TXSTA         ; -//- 
            banksel     RCSTA         ; переходим в регистр RCSTA
            movlw       b'00000000'   ; отключаем модуль RCSTA
            movwf       RCSTA         ; -//-
            banksel     ADCON0        ; переходим в регистр ADCON0
            movlw       b'00000000'   ; отключаем модуль АЦП
            movwf       ADCON0        ; -//-
            banksel     ADCON1        ; переходим в регистр ADCON1
            movlw       b'00000000'   ; отключаем модуль АЦП
            movwf       ADCON1        ; -//-
            bsf         STATUS,RP0    ; переход в банк 1
            bcf         STATUS,RP0    ; переход в банк 0
            clrwdt

                            ;;;;;;;;;;;;;;;;;;;;;;;;;
                            ; инициализация дисплея ;
                            ;;;;;;;;;;;;;;;;;;;;;;;;;
            call        del_100ms     ; начальная задержка 100 милисекунд
            movlw       b'00000001'   ; очищаем дисплей
            call        LCD_com       ; загружаем команду
            call        del_5ms
            movlw       b'00000110'   ; сдвиг курсора вправо
            call        LCD_com       ; загружаем команду
            movlw       b'00001100'   ; отключаем курсор
            call        LCD_com       ; загружаем команду
            movlw       b'00010100'   ; двигаем курсор вправо
            call        LCD_com       ; загружаем команду
            movlw       b'00111000'   ; вкл 8 разрядный ввод данных, размер символа 5х8 символов
            call        LCD_com       ; загружаем команду     

gooo       
            call        OUT_U         ; отправляемся читать данные АЦП, и вывод данных на дисплей
            call        OUT_I         ; отправляемся читать данные АЦП, и вывод данных на дисплей
            call        del_100ms
            call        del_100ms
            clrwdt
            goto        gooo


OUT_U ; выводим U на дисплей содержимое регистров Thou, Hund, Tens, Ones (тысячи, сотни, десятки, единицы)
            banksel     ADCON0        ; переходим в регистр ADCON0
            movlw       b'01000001'   ; включаем модуль АЦП, RA0 - вход, Fosc/8
            movwf       ADCON0        ; -//- 
            banksel     ADCON1        ; переходим в регистр ADCON1
            movlw       b'10000000'   ; включаем правое выравнивание
            movwf       ADCON1        ; -//-
            bcf         STATUS,RP0    ; переход в банк 0
            bsf         ADCON0,2      ; включаем преобразование АЦП
            call        del_20mcs
werf        btfsc       ADCON0,2      ; ожидаем завершения
            goto        werf          ; преобразования
            movfw       ADRESH        ; перепишем результат преобразования
            movwf       Reg_tmpH      ; в старший временный регистр
            banksel     ADRESL        ; переходим в регистр ADRESL
            movfw       ADRESL        ; перепишем результат преобразования
            bcf         STATUS,RP0    ; переход в банк 0
            movwf       Reg_tmpL      ; в младший временный регистр


            call        TRANSFORMER_dig ; перекодируем двоичное число результата преобразования в десятичное
            movlw       0x80          ; курсор в пределах первой строки ( 0x80 - начало )
            call        LCD_com       ; загружаем команду
            movlw       0x55          ; U
            call        LCD_dig       ; загружаем данные
            movlw       0x3D          ; =
            call        LCD_dig       ; загружаем данные
            movf        Thou,W        ; копируем в W содержимое Thou
            btfsc       Thou,0        ; проверяем значение регистра тысячных показаний, если 1, значит переполнение показаний
            goto        overflowU    ; отправляемся отображать 9,99V
            movf        Hund,W        ; копируем в W содержимое Hund
            call        TABL_dig      ; отправляем на дисплей содержимое Hund
            call        LCD_dig       ; загружаем данные
            movlw       0x2C          ; ,
            call        LCD_dig       ; загружаем данные
            movf        Tens,W        ; копируем в W содержимое Tens
            call        TABL_dig      ; отправляем на дисплей содержимое Tens
            call        LCD_dig       ; загружаем данные
            movf        Ones,W        ; копируем в W содержимое Ones
            call        TABL_dig      ; отправляем на дисплей содержимое Ones
            call        LCD_dig       ; загружаем данные
            movlw       0x56          ; V
            call        LCD_dig       ; загружаем данные
            return
overflowU  movlw       0x39          ; 9 (выводим 9,99V вместо 10,23V)
            call        LCD_dig       ; загружаем данные
            movlw       0x2C          ; ,
            call        LCD_dig       ; -//-
            movlw       0x39          ; 9
            call        LCD_dig       ; загружаем данные
            movlw       0x39          ; 9
            call        LCD_dig       ; загружаем данные
            movlw       0x56          ; V
            call        LCD_dig       ; загружаем данные
            return


OUT_I ; выводим I на дисплей содержимое регистров Thou, Hund, Tens, Ones (тысячи, сотни, десятки, единицы)
            banksel     ADCON0        ; переходим в регистр ADCON0
            movlw       b'01001001'   ; включаем модуль АЦП, RA1 - вход, Fosc/8
            movwf       ADCON0        ; -//- 
            banksel     ADCON1        ; переходим в регистр ADCON1
            movlw       b'10000000'   ; включаем правое выравнивание
            movwf       ADCON1        ; -//-
            bcf         STATUS,RP0    ; переход в банк 0
            bsf         ADCON0,2      ; включаем преобразование АЦП
            call        del_20mcs
desa        btfsc       ADCON0,2      ; ожидаем завершения
            goto        desa          ; преобразования
            movfw       ADRESH        ; перепишем результат преобразования
            movwf       Reg_tmpH      ; в старший временный регистр
            banksel     ADRESL        ; переходим в регистр ADRESL
            movfw       ADRESL        ; перепишем результат преобразования
            bcf         STATUS,RP0    ; переход в банк 0
            movwf       Reg_tmpL      ; в младший временный регистр


            call        TRANSFORMER_dig ; перекодируем двоичное число результата преобразования в десятичное
            movlw       0xC0          ; курсор в пределах второй строки ( 0xС0 - начало )
            call        LCD_com       ; загружаем команду
            movlw       0x49          ; I
            call        LCD_dig       ; загружаем данные
            movlw       0x3D          ; =
            call        LCD_dig       ; загружаем данные
            movf        Thou,W        ; копируем в W содержимое Thou
            btfsc       Thou,0        ; проверяем значение регистра тысячных показаний, если 1, значит переполнение показаний
            goto        overflowI    ; отправляемся отображать 9,99A
            movf        Hund,W        ; копируем в W содержимое Hund
            call        TABL_dig      ; отправляем на дисплей содержимое Hund
            call        LCD_dig       ; загружаем данные
            movlw       0x2C          ; ,
            call        LCD_dig       ; загружаем данные
            movf        Tens,W        ; копируем в W содержимое Tens
            call        TABL_dig      ; отправляем на дисплей содержимое Tens
            call        LCD_dig       ; загружаем данные
            movf        Ones,W        ; копируем в W содержимое Ones
            call        TABL_dig      ; отправляем на дисплей содержимое Ones
            call        LCD_dig       ; загружаем данные
            movlw       0x41          ; A
            call        LCD_dig       ; загружаем данные
            return
overflowI  movlw       0x39          ; 9 (выводим 9,99A вместо 10,23A)
            call        LCD_dig       ; загружаем данные
            movlw       0x2C          ; ,
            call        LCD_dig       ; -//-
            movlw       0x39          ; 9
            call        LCD_dig       ; загружаем данные
            movlw       0x39          ; 9
            call        LCD_dig       ; загружаем данные
            movlw       0x41          ; A
            call        LCD_dig       ; загружаем данные
            return


                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ; Подпрограмма трансформации двоичного числа в десятичное ;
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TRANSFORMER_dig
            movf        Reg_tmpL,W    ; копируем младший байт результата преобразования АЦП в   
            movwf       bin2          ; в bin2               
            movf        Reg_tmpH,W    ; копируем старший байт результата преобразования АЦП в   
            movwf       bin1          ; в bin1
;bin2 = младший байт преобразуемого числа
;bin1 = старший байт преобразуемого числа
;bcd3 ( младший полубайт ) = единицы
;bcd3 ( старший полубайт ) = десятки
;bcd2 ( младший полубайт ) = сотни
;bcd2 ( старший полубайт ) = тысячи
;bcd1 ( младший полубайт ) = десятки тысяч                                         
            movlw       .16
            movwf       ctr
            clrf        bcd1
            clrf        bcd2
            clrf        bcd3
            goto        start
adjdec      movlw       0x33
            addwf       bcd1,f
            addwf       bcd2,f
            addwf       bcd3,f
            movlw       0x03
            btfss       bcd1,3
            subwf       bcd1,f
            btfss       bcd2,3
            subwf       bcd2,f
            btfss       bcd3,3
            subwf       bcd3,f
            movlw       0x30
            btfss       bcd1,7
            subwf       bcd1,f
            btfss       bcd2,7
            subwf       bcd2,f
            btfss       bcd3,7
            subwf       bcd3,f
start       rlf         bin2,f
            rlf         bin1,f
            rlf         bcd3,f
            rlf         bcd2,f
            rlf         bcd1,f
            decfsz      ctr,f
            goto        adjdec        ; окончание конвертирования                 
            movf        bcd1,w        ; распределение результата по регистрам       
            movwf       TenK          ; десятки тысяч
            swapf       bcd2,w
            movwf       Thou          ; тысячи
            movf        bcd2,w
            movwf       Hund          ; сотни
            swapf       bcd3,w
            movwf       Tens          ; десятки
            movf        bcd3,w
            movwf       Ones          ; единицы
            return     

TABL_dig    andlw       b'00001111'   ; маскируем старший полубайт W (обнуляем 4 старших байта)
            addwf       PCL,f         ; Содержимое счетчика команд PC увеличивается на величину содержимого аккумулятора W.
            retlw       0x30          ; 0
            retlw       0x31          ; 1
            retlw       0x32          ; 2
            retlw       0x33          ; 3
            retlw       0x34          ; 4
            retlw       0x35          ; 5 
            retlw       0x36          ; 6
            retlw       0x37          ; 7
            retlw       0x38          ; 8
            retlw       0x39          ; 9
            retlw       0x41          ; A
            retlw       0x42          ; B
            retlw       0x43          ; C
            retlw       0x44          ; D
            retlw       0x45          ; E
            retlw       0x46          ; F

                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ; Подпрограмма вывода данных на HD44780 ;
                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; загрузка комманды
LCD_com     movwf       LCD_tmp           
            call        E_0
            call        RS_0
            call        LCD_load
            return     

; загрузка цифры
LCD_dig     movwf       LCD_tmp           
            call        E_0
            call        RS_1
            call        LCD_load
            return
 
; загрузка данных непосредственно в дисплей со стробированием
LCD_load    movf        LCD_tmp,W         
            movwf       LCD_PORT
            call        del_1ms
            call        E_1
            call        del_1ms
            call        E_0
            call        del_1ms
            return

E_0         bcf         E_LCD
            movf        LCD_tmp1,W   
            movwf       LCD_PORT_E_RS         
            return

E_1         bsf         E_LCD
            movf        LCD_tmp1,W   
            movwf       LCD_PORT_E_RS         
            return

RS_0        bcf         RS_LCD
            movf        LCD_tmp1,W   
            movwf       LCD_PORT_E_RS         
            return

RS_1        bsf         RS_LCD
            movf        LCD_tmp1,W   
            movwf       LCD_PORT_E_RS         
            return

; ЗАДЕРЖКА 5 ms
del_5ms     call        del_1ms
            call        del_1ms
            call        del_1ms
            call        del_1ms
            call        del_1ms
            return

; ЗАДЕРЖКА 100 ms
del_100ms   call   del_50ms
            call   del_50ms
            return
 
; ЗАДЕРЖКА 50 ms
del_50ms    movlw       .238
            movwf       Reg_tmp1
            movlw       .65
            movwf       Reg_tmp2
wr1         decfsz      Reg_tmp1, F
            goto        wr1
            decfsz      Reg_tmp2, F
            goto        wr1
            return                                   

; ЗАДЕРЖКА 1 ms
del_1ms     movlw       .75
            movwf       Reg_tmp1
            movlw       .2
            movwf       Reg_tmp2
wr2         decfsz      Reg_tmp1, F
            goto        wr2
            decfsz      Reg_tmp2, F
            goto        wr2
            return

;delay = 20 machine cycles
del_20mcs   movlw       .6
            movwf       Reg_tmp1
wr3         decfsz      Reg_tmp1, F
            goto        wr3
            return

            end


Вложения:
HD44780.asm [26.26 KiB]
Скачиваний: 408
Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 18:07:47 
Друг Кота

Карма: 27
Рейтинг сообщений: 1283
Зарегистрирован: Ср фев 11, 2009 20:35:58
Сообщений: 7853
Рейтинг сообщения: 0
Ищи в сети книги и диск.
Подсчитывать адрес регистров через CBLOCK и переходы через $ ни каждому захочется.
Если хочеш помощи, выкладывай проект МПЛАБ , а не куски кода.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 18:23:38 
Встал на лапы
Аватар пользователя

Карма: 9
Рейтинг сообщений: 53
Зарегистрирован: Чт авг 16, 2012 10:41:42
Сообщений: 99
Рейтинг сообщения: 0
Проект


Вложения:
16F876A.rar [17.53 KiB]
Скачиваний: 191
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 18:50:06 
Друг Кота

Карма: 27
Рейтинг сообщений: 1283
Зарегистрирован: Ср фев 11, 2009 20:35:58
Сообщений: 7853
Рейтинг сообщения: 0
Попробуй отключить WDT.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 18:59:50 
Встал на лапы
Аватар пользователя

Карма: 9
Рейтинг сообщений: 53
Зарегистрирован: Чт авг 16, 2012 10:41:42
Сообщений: 99
Рейтинг сообщения: 0
Пробовал - бестолку! Прямо мистика какая то. Подпрограммы по отдельности работают прекрасно(с удалением из кода одной или другой подпрограммы). Но строит подпрограммы оставить вместе в коде и даже не вызывать мешающую подпрограмму - все равно глюк! Как? Если подпрограмма не вызывается, а просто стоит невостребованная???


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Пн дек 09, 2013 19:36:39 
Друг Кота

Карма: 27
Рейтинг сообщений: 1283
Зарегистрирован: Ср фев 11, 2009 20:35:58
Сообщений: 7853
Рейтинг сообщения: 0
Не нужно паники, нужен анализ.
Когда задаёш вопросы , то читай внимательно ответы.
Цитата:
Пока вижу у Вас неправильный вызов ПП "TABL_dig".

Это 1-й глюк. Перенеси таблицу в начало программы.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Вт дек 10, 2013 11:27:13 
Грызет канифоль

Зарегистрирован: Вт окт 08, 2013 07:38:59
Сообщений: 256
Откуда: СПб
Рейтинг сообщения: -1
4uvak писал(а):
Пробовал - бестолку! Прямо мистика какая то. Подпрограммы по отдельности работают прекрасно(с удалением из кода одной или другой подпрограммы). Но строит подпрограммы оставить вместе в коде и даже не вызывать мешающую подпрограмму - все равно глюк! Как? Если подпрограмма не вызывается, а просто стоит невостребованная???
Никакой мистики.
Для начала, Вас не смущают сообщения компилятора, типа:
Код:
Message[302] D:\PROV\16F876A\16F876A.ASM 196 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Warning[203] D:\PROV\16F876A\16F876A.ASM 297 : Found opcode in column 1. (andlw)

Ладно, это - мелочи.
Что, например, за код?
Код:
E_0         bcf         E_LCD
            movf        LCD_tmp1,W   
            movwf       LCD_PORT_E_RS         
            return

Почему просто нельзя ногой дрыгать?
Если вы хотите байтом выводить, так тогда его сперва считать нужно, затем выставить нужные биты, а уж затем только выводить.
Ну, и вся программа такая, в общем.
Глюк сидел, как и говорил выше.
Подправил программу (см. аттач)
Кстати, а в чём Вы вообще программу отлаживали? Это же сразу должно быть заметно.
Заодно приложил проект для Протеуса, и для МПЛАБа с Протеусом.
Учитесь с отладкой работать.
P.S.: Ещё Протеус ругается, что время АЦП не выдержано. Он, конечно, может и ошибаться, но я не проверял. Это уж сами как-нибудь.


otest писал(а):
Перенеси таблицу в начало программы.
Можно, конечно, и так, но это - половинчатая мера.
Лучше сразу правильно делать.


Вложения:
16F876A.zip [43.13 KiB]
Скачиваний: 219
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Вт дек 10, 2013 14:52:57 
Встал на лапы
Аватар пользователя

Карма: 9
Рейтинг сообщений: 53
Зарегистрирован: Чт авг 16, 2012 10:41:42
Сообщений: 99
Рейтинг сообщения: 0
Всем большое спасибо за помощь и правильные наводки! Разобраться помогла статья http://chipmk.ru/index.php?option=com_c ... 5-10-13-47 где все толково описано насчет организации памяти.
Smen дрыгал ногами я раньше пока не наткнулся на отрицательные нюансы эффекта чтения-модификации-записи. После этого я и стал использовать переменную, вместо правки порта. Правлю переменную, потом запись в порт!
Если честно я отладочными средствами пользоваться не умею. Отладку производил в готовом устройстве.
Если не трудно - дайте ссылку где грамотно описан процесс отладки...
Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 16F876A Вольтамперметр. Проблемы Исходника
СообщениеДобавлено: Вт дек 10, 2013 16:52:36 
Грызет канифоль

Зарегистрирован: Вт окт 08, 2013 07:38:59
Сообщений: 256
Откуда: СПб
Рейтинг сообщения: -1
4uvak писал(а):
пока не наткнулся на отрицательные нюансы эффекта чтения-модификации-записи.
Так не надо на него "натыкаться" и всего делов.

4uvak писал(а):
я отладочными средствами пользоваться не умею. Отладку производил в готовом устройстве.
Так Вы никогда ничего не отладите.
В МПЛАБе выбираете подходящий дебагер.
Включаете симуляцию (зелёная кнопочка).
F7 - пошаговая отладка
F9 - "воспроизведение"
Точки останова - двойной клик ЛКМ на нужной строке.
Откройте проект, который в аттаче, всё поймёте. Там, в качестве дебагера Протеус, поэтому его сперва установить надо.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y