Столкнулся с непонятным поведение PIC16F690. Имеется следующий код (только часть с непонятным поведением):
Файл Main.asm:
Код
....
EXTERN UARTHnd
EXTERN InitADC,ResetADC
GLOBAL MainLoop,InitMCU
Reset: CODE
GOTO InitMCU
Int: CODE
GOTO UARTHnd
Main: CODE
InitMCU:
INTERRUPT_OFF
CALL InitSFR
CALL InitADC
;отправляем что-нибудь по uart-у для проверки работоспособности
;----------------------------------------------
BANKSEL TXREG
MOVLW 0xAA
MOVWF TXREG
WT1:
BTFSS PIR1,TXIF
GOTO WT1
;----------------------------------------------
MOVLW cINTCON
MOVWF INTCON
MainLoop:
CALL StartTimeOut
CALL UpDateADC
WaitTimeOut:
BANKSEL PIR1
BTFSS PIR1,TMR1IF
GOTO WaitTimeOut
GOTO MainLoop
StartTimeOut:
.....
RETURN
InitSFR:
....
RETURN
END
EXTERN UARTHnd
EXTERN InitADC,ResetADC
GLOBAL MainLoop,InitMCU
Reset: CODE
GOTO InitMCU
Int: CODE
GOTO UARTHnd
Main: CODE
InitMCU:
INTERRUPT_OFF
CALL InitSFR
CALL InitADC
;отправляем что-нибудь по uart-у для проверки работоспособности
;----------------------------------------------
BANKSEL TXREG
MOVLW 0xAA
MOVWF TXREG
WT1:
BTFSS PIR1,TXIF
GOTO WT1
;----------------------------------------------
MOVLW cINTCON
MOVWF INTCON
MainLoop:
CALL StartTimeOut
CALL UpDateADC
WaitTimeOut:
BANKSEL PIR1
BTFSS PIR1,TMR1IF
GOTO WaitTimeOut
GOTO MainLoop
StartTimeOut:
.....
RETURN
InitSFR:
....
RETURN
END
Файл CMD.asm
Код
...
EXTERN MainLoop
GLOBAL UARTHnd
;нужный буду топом
GenRegs: UDATA_OVR
R6: RES 1
R5: RES 1
R4: RES 1
R3: RES 1
R2: RES 1
R1: RES 1
R0: RES 1
;нужный буду топом
UARTData: UDATA
Temp: RES d'1'
Counter: RES d'1'
NBytes: RES d'1'
CmdBuf RES MAX_CMD_LENGTH
ChekSum: RES d'2'
Interface: CODE
;Обработчик прерываний от UART, возникающего при получении очередного байта
UARTHnd:
BANKSEL RCREG
MOVF RCREG,W
MOVWF TXREG
WT:
BTFSS PIR1,TXIF
GOTO WT
RETFIE
END
EXTERN MainLoop
GLOBAL UARTHnd
;нужный буду топом
GenRegs: UDATA_OVR
R6: RES 1
R5: RES 1
R4: RES 1
R3: RES 1
R2: RES 1
R1: RES 1
R0: RES 1
;нужный буду топом
UARTData: UDATA
Temp: RES d'1'
Counter: RES d'1'
NBytes: RES d'1'
CmdBuf RES MAX_CMD_LENGTH
ChekSum: RES d'2'
Interface: CODE
;Обработчик прерываний от UART, возникающего при получении очередного байта
UARTHnd:
BANKSEL RCREG
MOVF RCREG,W
MOVWF TXREG
WT:
BTFSS PIR1,TXIF
GOTO WT
RETFIE
END
Файл Comp.asm
Код
...
GLOBAL InitADC,ResetADC,SetGain,UpDateADC,WrByteADC,WrCommReg
....
Comp: CODE
; Description: Отправка байта на АЦП
WrByteADC:
BANKSEL ADC_CS_PORT
BCF ADC_CS
SEL_BANK0
MOVWF R3;отправляемые данные
MOVLW d'8'
MOVWF R2;кол-во отправляемых бит
WBAL0: ;цикл отправки бит
BANKSEL ADC_SCLK_PORT
BCF ADC_SCLK
SEL_BANK0
RLF R3,F
;ДОЛЖНО БЫТЬ (В этом случае начинаются глюки)
;------------------------------------------------------------
;BANKSEL ADC_DIN_PORT
;BCF ADC_DIN
;BTFSC STATUS,C
;BSF ADC_DIN
;------------------------------------------------------------
;ТАК РАБОТАЕТ (Хотя это форменный изврат)
;------------------------------------------------------------
BANKSEL ADC_DIN_PORT
BCF ADC_DIN
BTFSC STATUS,C
GOTO tmp
tmp:
BSF ADC_DIN
;------------------------------------------------------------
BANKSEL ADC_SCLK_PORT
BSF ADC_SCLK
SEL_BANK0
DECFSZ R2,F
GOTO WBAL0
BANKSEL ADC_CS_PORT
BSF ADC_CS
RETURN
;Инициализация АЦП
InitADC:
INTERRUPT_OFF
CALL ResetADC
WR_CLOCK_REG
MOVLW b'00010010'
CALL WrByteADC
CALL SetGain
RETURN
....
GLOBAL InitADC,ResetADC,SetGain,UpDateADC,WrByteADC,WrCommReg
....
Comp: CODE
; Description: Отправка байта на АЦП
WrByteADC:
BANKSEL ADC_CS_PORT
BCF ADC_CS
SEL_BANK0
MOVWF R3;отправляемые данные
MOVLW d'8'
MOVWF R2;кол-во отправляемых бит
WBAL0: ;цикл отправки бит
BANKSEL ADC_SCLK_PORT
BCF ADC_SCLK
SEL_BANK0
RLF R3,F
;ДОЛЖНО БЫТЬ (В этом случае начинаются глюки)
;------------------------------------------------------------
;BANKSEL ADC_DIN_PORT
;BCF ADC_DIN
;BTFSC STATUS,C
;BSF ADC_DIN
;------------------------------------------------------------
;ТАК РАБОТАЕТ (Хотя это форменный изврат)
;------------------------------------------------------------
BANKSEL ADC_DIN_PORT
BCF ADC_DIN
BTFSC STATUS,C
GOTO tmp
tmp:
BSF ADC_DIN
;------------------------------------------------------------
BANKSEL ADC_SCLK_PORT
BSF ADC_SCLK
SEL_BANK0
DECFSZ R2,F
GOTO WBAL0
BANKSEL ADC_CS_PORT
BSF ADC_CS
RETURN
;Инициализация АЦП
InitADC:
INTERRUPT_OFF
CALL ResetADC
WR_CLOCK_REG
MOVLW b'00010010'
CALL WrByteADC
CALL SetGain
RETURN
....
Глюк заключается в следующим, если восстановить подпрограмму WrByteADC согласно приведенным, в ней комментариям, то в главной программе (Main) при попытке отправить байт по UART-у вместо 0xAA приходит, например, 0xFE (или еще что-нибудь, но не то что хотим). В обработчике прерывания от UART-а также вместо отправки принятого байта отправляется полная чушь.
Подскажить в каком направлении искать правду.