![]() |
|
|
Продукция MICROCHIP Технические вопросы по всей продукции Microchip |
![]() |
|
Опции темы | Опции просмотра |
![]() |
#1 |
Senior Member
|
![]()
Приветствую.
Уже много дней борюсь с проблемой, но только сегодня поймал "откуда ноги растут". Прибор предназначен для приёма DMX-512 передачи принятого пакета на PCA9685. В общих чертах проблема в заголовке, подробности такие... Проц стабильно инициализируется; по TMR1 в прерывании обслуживается 3х-разрядный индикатор, там же обрабатывается USART1 и TimeOUT (при пропадании сигнала DMX). В теле "MCU_ini" есть 17 скачков "rcall/return 0" - всё работает чудесно. Дальше - обработка DMX-сигнала "DMX_serv" - тоже без нареканий. Потом "SEND_I2C" - подпрограмма посылки по I2C в PCA9685 (вместо самой подпрограммы - код задержки 1,94мс, эмуляция на время отладки), вот тут начинается полтергейст... Если вместо команды "rcall DUMMY_TO" поставить сами строчки кода задержки на TMR3 - то всё работает на "УРА", но если оставить как в коде (вызов подпрограммы) - то происходит 30 нормальных вызовов а на 31 устанавливается флаг STKPTR:STKFUL и проц уходит в перезагрузку, ибо в CONFIG4L: STVREN=1. Но ведь так не должно же быть, на каждый PUSH есть свой POP. Или я где-то накосячил и не вижу? Код:
LIST P=PIC18F24K22 #include <P18F24K22.inc> CONFIG FOSC=HSMP,PLLCFG=OFF,PRICLKEN=ON,FCMEN=OFF,IESO=OFF CONFIG PWRTEN=ON,BOREN=SBORDIS,BORV=285,WDTEN=OFF,WDTPS=512 CONFIG CCP2MX=PORTC1,PBADEN=OFF,CCP3MX=PORTB5,HFOFST=ON,T3CMX=PORTC0,P2BMX=PORTB5,MCLRE=INTMCLR CONFIG STVREN=ON,LVP=OFF,XINST=OFF,DEBUG=OFF CONFIG CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF CONFIG WRT0=OFF,WRT1=OFF,WRTC=OFF,WRTB=OFF,WRTD=OFF CONFIG EBTR0=OFF,EBTR1=OFF,EBTRB=OFF ;HS_OSC=16MHz ; flags ;7 - Terminator_OFF=0 / Terminator_ON=1 ;6 - Lin=0 / Log=1 ;5 - Ready I2C ; ;0 - ;========================================================== org 0xF00000 ;preSET flags & start DMX-address DE 0x00,0x01 ;Trm_OFF, Lin, start_ADDR =001 ;========================================================== cblock 0x100 ADDR_H,ADDR_L,Dig_1,Dig_2,Dig_3,_i,_j,flags,I2C_DATA ADDR_Htmp,ADDR_Ltmp,LED_cnt,RX_cnt,RX_tmp,C_out,BTN_reg endc ;========================================================== org 0 goto MCU_ini ;=========================== org 8 INT clrwdt btfsc PIR1,RCIF,0 ;прерывание от USARTа? bra RX_ ; да, переход к обработке USARTa btfss PIR1,TMR1IF,0 ; нет, прерывание от TMR1? bra TimeOUT ; нет, переход к TimeOUT ;=========================== TMR1_INT ; да, тогда TMR1 bcf PIR1,TMR1IF,0 ;сброс флага TMR1IF movlw 0xC0 movwf TMR1H,0 ;период TMR1=4.1ms movf LED_cnt,W,1 addwf PCL,F,0 bra DIG1 bra DIG2 DIG3 clrf LATA,0 movff Dig_3,LATB bsf LATA,2,0 clrf LED_cnt,1 retfie 1 DIG1 clrf LATA,0 movff Dig_1,LATB bsf LATA,0,0 incf LED_cnt,F,1 incf LED_cnt,F,1 retfie 1 DIG2 clrf LATA,0 movff Dig_2,LATB bsf LATA,1,0 incf LED_cnt,F,1 incf LED_cnt,F,1 retfie 1 ;=========================== RX_ btfss RCSTA1,FERR,0 ;проверка ошибки кадра btfsc RCSTA1,OERR,0 ; нет, проверка переполнения bra Err ; да-да переход на Err movff RCREG1,RX_tmp ; нет, RCREG1 =>RX_tmp movf ADDR_Htmp,W,1 iorwf ADDR_Ltmp,W,1 bz RX_next ;ADDR_tmp =0 decf ADDR_Ltmp,F,1 ;ADDR_tmp >0 btfss STATUS,C,0 decf ADDR_Htmp,F,1 lfsr FSR0,0x000 retfie 1 Err movff RCREG1,RX_tmp ;сброс флага RC1IF bcf RCSTA1,SPEN,0 ;выключаем USART1 clrf RX_cnt,1 retfie 1 RX_next movlw 0x02 mulwf RX_tmp,1 movff PRODL,POSTINC0 movlw 0x3C btfss flags,6,1 bra not_log movlw 0x3E not_log addwf PRODH,W,0 movff WREG,POSTINC0 decf RX_cnt,F,1 retfie 1 ;=========================== TimeOUT bcf INTCON,TMR0IF,0 bcf RCSTA1,SPEN,0 ;выключаем USART1 clrf RX_cnt,1 retfie 1 ;=========================================================== MCU_ini movlb d'15' ;15-bank clrf ANSELA,1 ; clrf ANSELB,1 ;все порты цифровые clrf ANSELC,1 ; movlw b'10111010' ; movwf PMD0,1 ;включаем USART1,TMP3 и TMR1 movlw b'10011111' movwf PMD1,1 ;включаем MSSP1 setf PMD2,1 ; movlb d'1' ;1-bank clrf SLRCON,0 ;slew rate стандартный clrf LATA,0 ; clrf LATB,0 ;настройка портов clrf LATC,0 ; clrf TRISA,0 ;RAx выходы clrf TRISB,0 ;RBx выходы movlw b'10011000' ;RC0-RC2,RC5-RC6 выходы movwf TRISC,0 ;RC3-RC4,RC7 входы clrf EECON1,0 ;доступ к EEPROM movlw b'00000110' movwf TXSTA1,0 ;BRGH=1 movlw b'01010000' ;USART1=OFF,9-bitRx, movwf RCSTA1,0 ; Continuous_RX,ADDEN=OFF bsf BAUDCON1,BRG16,0 ;BRG16=1 movlw d'15' movwf SPBRG1,0 clrf SPBRGH1,0 ;USART=250kBd movlw b'00101000' movwf SSP1CON1,0 ;SSP1=EN,I2C=master movlw b'00001000' movwf SSP1CON3,0 ;HOLDt=300ns movlw 0x09 movwf SSP1ADD,0 ;BRclk=400kHz TMR0_INI movlw b'10010101' ;TMR0=ON,16-bit,T0_clk=16us movwf T0CON,0 ; T0_r.o=1.05s clrf TMR0H,0 clrf TMR0L,0 DLY_bStart btfss INTCON,TMR0IF,0 ; bra DLY_bStart ;задержка перед стартом 1.05s bcf INTCON,TMR0IF,0 ; сброс флага TMR0IF TMR1_INI movlw b'00000001' ;T1clk=0.25us movwf T1CON,0 ; T1_2x8bit,T1=ON clrf TMR1H,0 clrf TMR1L,0 ;TMR1 - таймер индикации RD_EEPROM clrf EEADR,0 bsf EECON1,RD,0 ;чтение 0-ячейки EEPROM movf EEDATA,W,0 andlw b'11000000' movwf flags,1 ;переносим из EEPROM в flags bsf EECON1,RD,0 ;чтение 0-ячейки EEPROM movf EEDATA,W,0 andlw b'00000011' movwf ADDR_H,1 ;переносим из EEPROM в ADDR_H incf EEADR,F,0 bsf EECON1,RD,0 ;чтение 1-ячейки EEPROM movf EEDATA,W,0 movwf ADDR_L,1 ;переносим из EEPROM в ADDR_L btfsc flags,7,1 bsf LATC,6,0 rcall GET_DIGIT PCA9685_INI rcall BSTART movlw 0x80 movwf I2C_DATA,1 rcall TX_BYTE ; Send SLAVE_ADDR movlw 0x00 movwf I2C_DATA,1 rcall TX_BYTE ; Send № of register (00h) movlw 0x30 movwf I2C_DATA,1 rcall TX_BYTE ; Send MODE1 movlw 0x04 movwf I2C_DATA,1 rcall TX_BYTE ; Send MODE2 rcall BSTOP rcall BSTART movlw 0x80 movwf I2C_DATA,1 rcall TX_BYTE ; Send SLAVE_ADDR movlw 0xFE movwf I2C_DATA,1 rcall TX_BYTE ; Send № of register (FEh) movlw d'15' movwf I2C_DATA,1 rcall TX_BYTE ; Send PRE_SCALE (Urate=381Hz) rcall BSTOP rcall BSTART movlw 0x80 movwf I2C_DATA,1 rcall TX_BYTE ; Send SLAVE_ADDR movlw 0x00 movwf I2C_DATA,1 rcall TX_BYTE ; Send № of register (00h) movlw 0x20 movwf I2C_DATA,1 rcall TX_BYTE ; Send MODE1 rcall BSTOP clrf LED_cnt,1 bsf PIE1,RC1IE,0 ;разрешены прерывания Rx1 bsf PIE1,TMR1IE,0 ;разрешены прерывания TMR1 movlw b'11100000' ;разрешены прерывания: movwf INTCON,0 ; GIE,PEIE,TMR0 ;=========================================================== DMX_serv btfsc PORTC,7,0 ;ожидание начала [BREAK] импульса bra DMX_serv clrf TMR0H,0 clrf TMR0L,0 END_Br btfss PORTC,7,0 ;ожидание конца [BREAK] импульса bra END_Br movf TMR0L,W,0 tstfsz TMR0H,0 bra DMX_data_in ; [BREAK] > 4.1ms movlw d'4' cpfsgt TMR0L,0 ;проверка длительности [BREAK] bra DMX_serv ; [BREAK] < 80us DMX_data_in ; [BREAK] > 80us movlw d'16' movwf RX_cnt,1 ;16-байт принимаемых данных movff ADDR_H,ADDR_Htmp ;переносим из ADDR_ movff ADDR_L,ADDR_Ltmp ; в ADDR_tmp bsf RCSTA1,SPEN,0 ;включаем USART1 LOOP_RX tstfsz RX_cnt,1 ;проверка конца посылки bra LOOP_RX btfss RCSTA1,SPEN,0 bra DMX_serv bcf RCSTA1,SPEN,0 ;выключаем USART1 ;=========================================================== SEND_I2C bcf T1CON,TMR1ON,0 ;TMR1=OFF ; bsf LATC,6,0 rcall DUMMY_TO ; bcf LATC,6,0 bsf T1CON,TMR1ON,0 ;TMR1=ON bra DMX_serv ;*************************** DUMMY_TO bcf PIR2,TMR3IF,0 movlw 0xE1 movwf TMR3H,0 movlw 0xBA movwf TMR3L,0 bsf T3CON,TMR3ON,0 btfss PIR2,TMR3IF,0 bra $-2 bcf T3CON,TMR3ON,0 return 0 ;*************************** BSTART bcf PIR1,SSP1IF,0 ; Clear SSP interrupt flag bsf SSP1CON2,SEN,0 ; Generate Start condition bstart_wait btfss PIR1,SSP1IF,0 ; Check if operation completed bra bstart_wait ; If not, keep checking return 0 ;*************************** TX_BYTE bcf PIR1,SSP1IF,0 ; Clear SSP interrupt flag movff I2C_DATA,SSP1BUF ; Write I2C_DATA to PCA9685 tx_wait btfss PIR1,SSP1IF,0 ; Check if operation completed bra tx_wait ; If not, keep checking return 0 ;*************************** BSTOP bcf PIR1,SSP1IF,0 ; Clear SSP interrupt flag bsf SSP1CON2,PEN,0 ; Generate Stop condition bstop_wait btfss PIR1,SSP1IF,0 ; Check if operation completed bra bstop_wait ; If not, keep checking return 0 ;=========================================================== GET_DIGIT movff ADDR_H,ADDR_Htmp movff ADDR_L,ADDR_Ltmp clrf Dig_1,1 clrf Dig_2,1 clrf Dig_3,1 movlw 0x10 movwf _i,1 bra lab1 next1 movf Dig_3,W,1 rcall corr1 movwf Dig_3,1 movf Dig_2,W,1 rcall corr1 movwf Dig_2,1 movf Dig_1,W,1 rcall corr1 movwf Dig_1,1 lab1 rlcf ADDR_Ltmp,F,1 rlcf ADDR_Htmp,F,1 rlcf Dig_3,F,1 rlcf Dig_2,F,1 rlcf Dig_1,F,1 decfsz _i,F,1 bra next1 movlw 0x3B movwf TBLPTRH,0 movf Dig_2,W,1 andlw b'00000111' movwf TBLPTRL,0 tblrd* movff TABLAT,Dig_1 swapf Dig_3,W,1 andlw b'00001111' movwf TBLPTRL,0 tblrd* movff TABLAT,Dig_2 movf Dig_3,W,1 andlw b'00001111' movwf TBLPTRL,0 tblrd* movff TABLAT,Dig_3 movlw b'11101011' xorwf Dig_1,W,1 btfss STATUS,Z,0 return 0 ;Dig_1 > 0 clrf Dig_1,1 ;Dig_1 = 0 movlw b'11101011' xorwf Dig_2,W,1 btfss STATUS,Z,0 return 0 ;Dig_2 > 0 clrf Dig_2,1 ;Dig_2 = 0 return 0 corr1 movwf _j,1 movlw 0x03 addwf _j,F,1 btfss _j,3,1 subwf _j,F,1 movlw 0x30 addwf _j,F,1 btfss _j,7,1 subwf _j,F,1 movf _j,W,1 return 0 ;=========================== CONV_LED org 0x3B00 dw 0x28EB, 0xBAB3, 0xDA78, 0xA8DB ;1:0 3:2 5:4 7:6 dw 0xFAFB, 0x1B43, 0x5341, 0x0019 ;9:8 o:L t:I none:n ;===========================
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#2 |
Senior Member
Регистрация: 12.07.2012
Возраст: 34
Сообщений: 2,685
Вес репутации: 4859/106 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]()
Проводили отладку по шагам? Если нет - проведите.
|
![]() |
![]() |
![]() |
#3 |
Senior Member
|
![]()
Три недели! В симуляторе всё ОК, на каждый rcall стекпоинтер увеличивается на единицу, потом, по return 0 - обратно уменьшается. Даже когда уходим в прерывание на обслуживание индикатора из DUMMY_TO, то стекпоинтер увеличивается максимум до двух и потом обратно в ноль.
Т.Е. в симуляторе переполнения стека никогда не происходит. П.С. Обратите внимание, в подпрограмме инициализации, до разрешения прерываний от периферии и таймеров, скачкИ rcall-return (17 штук) не уменьшают количества вызовов DUMMY_TO, их по прежнему 31. Что заставляет задуматься...
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#4 |
Member
Регистрация: 05.02.2012
Адрес: г.Саяногорск
Возраст: 45
Сообщений: 89
Вес репутации: 255/35 ![]() ![]() ![]() |
![]()
movf LED_cnt,W,1
addwf PCL,F,0 bra DIG1 bra DIG2 DIG3 clrf LATA,0 Опасный участок может после bra DIG2 несколько nop поставить . |
![]() |
![]() |
![]() |
#5 |
Senior Member
|
![]()
Вообще не вижу там проблем; PCL через FF-00 в этом месте ни при каких обстоятельствах не перескочит.
Да и в обработчике прерываний всё исправно работает, не туда копаем.
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#6 |
Member
Регистрация: 05.02.2012
Адрес: г.Саяногорск
Возраст: 45
Сообщений: 89
Вес репутации: 255/35 ![]() ![]() ![]() |
![]()
Если LED_cnt равно один идет переход на DIG2. Так прибавляется LED_cnt два раза до трёх. На следующий заход не попадаем на DIG3 и теряем строчку clrf LATA,0 .
|
![]() |
![]() |
![]() |
#7 |
Senior Member
|
![]()
LED_cnt - всегда чётное число (0;2;4), обратите внимание - там всегда идёт двойное инкременирование...
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#8 |
Member
Регистрация: 18.01.2014
Возраст: 42
Сообщений: 60
Вес репутации: 213/28 ![]() ![]() ![]() |
![]()
А если сделать так:
Код:
TMR1_INT ; да, тогда TMR1 bcf PIR1,TMR1IF,0 ;сброс флага TMR1IF movlw 0xC0 movwf TMR1H,0 ;период TMR1=4.1ms movf PCL, W ; обновляем значение PCLATH movf LED_cnt,W,1 addwf PCL,F,0 bra DIG1 bra DIG2 |
![]() |
![]() |
![]() |
#9 |
Senior Member
|
![]()
Чего-то не вижу логики, по которой РСLATH может содержать некорректное значение.
Подпрограмма обработки прерываний располагается в самом начале PROGRAM_MEMORY и, соответственно, он (РСLATU и РСLATH) всегда в нуле. Я в процессе отладки обнаружил, что в теле [MCU_ini] вызовы "rcall" прибавляет счётчк "STKPTR" а "return" уменьшает на единицу. А вот в "SEND_I2C" вызовы "rcall" инкриментируют, а "return" не уменьшают. Получается 30 вызовов работают нормально, а на 31-м происходит ролловер, STKFUL=1 и уход на перезагрузку.
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Регистрация: 09.11.2012
Адрес: SPB
Возраст: 52
Сообщений: 2,406
Вес репутации: 1047/65 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() Цитата:
|
|
![]() |
![]() |
![]() |
#11 |
Senior Member
|
![]()
В прерываниях совсем отказался от модификации "программного счётчика", т.о. rcall-return остался только в блоке вывода на I2C - проблема осталась, всё равно переполняется стекпоинтер.
Ок. В понедельник поковыряю эту тему...
__________________
конденсатор оказал сопротивление |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Регистрация: 26.02.2007
Адрес: SPb
Сообщений: 1,231
Вес репутации: 1853/81 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() Цитата:
если смотреть lst файл, опкод rcall\return адекватный? когда-то было чуесатое поведение контроллеров PIC18F6525 серии (см. Errata, п.12), там лечение описано - вставить команду с опкодом FFFF (nop) на 0, 8, 18, адреса (старта и прерываний), на адреса источников call, goto, сразу после return, retfie и при табличном чтении. Самое прикольное, что с применением Си компилятора такое "решение проблемы" сделать весьма проблематично. Но тогда на HiTech удалось заставить компилятор поставить nop на 0 и 08/18 адреса и это исправляло "неадекватное поведение" программы. (точнее в большинстве случаев было все ОК, но иногда добавление/смещение кода рушило работу и "патч" эту проблему исправлял. Обнаружилось у серийного изделия при очередной модификации программы )) |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Регистрация: 18.10.2016
Сообщений: 148
Вес репутации: 386/20 ![]() ![]() ![]() ![]() |
![]()
Забыли END в конце текста программы.
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Регистрация: 18.10.2016
Сообщений: 148
Вес репутации: 386/20 ![]() ![]() ![]() ![]() |
![]() Код:
TMR1_INT ; да, тогда TMR1 bcf PIR1,TMR1IF,0 ;сброс флага TMR1IF movlw 0xC0 movwf TMR1H,0 ;период TMR1=4.1ms movf LED_cnt,W,1 addwf PCL,F,0 bra DIG1 bra DIG2 Цитата:
|
|
![]() |
![]() |
![]() |
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
Опции темы | |
Опции просмотра | |
|
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Имитатор DS18B20 | Filya44 | Вопросы начинающих | 14 | 12.03.2012 17:39 |