📄 ka.asm
字号:
MOVLW bSLAVE ; Move bSLAVE address
MOVWF TXBUF ; into buffer (R/W = 0)
CALL ICSTART ; Generate START bit
CALL ICTX ; Output bSLAVE address. Check ACK.
;;;;
btfsc meter_error,E2PROM_error ; Skip if OK
retlw 0FFh ; Error Return
MOVF address,W ; Get WORD address
MOVWF TXBUF
CALL ICTX ; Output WORD address. Check ACK.
;;;;
btfsc meter_error,E2PROM_error ; Skip if OK
retlw 0FFh ; Error Return
CALL ICSTART ; START READ (if only one device is
MOVLW bSLAVE ; connected to the I2C bus)
MOVWF TXBUF
BSF TXBUF,0 ; Specify READ mode (R/W = 1)
CALL ICTX ; Output bSLAVE address
;;;;
btfsc meter_error,E2PROM_error ; Skip if OK
retlw 0FFh ; Error Return
ICRd_loop:
CALL ICRX ; READ in data and acknowledge
MOVFW RXBUF ; Move data
MOVWF INDF ; into dataio
INCF FSR,1
RegBnk1
MOVLW B'00000001' ; Set bSDA, bSCL as outputs
MOVWF TRISA
RegBnk0 ;01. 8.6
BSF RA,bSDA ; Output bit 1 to STOP further input
DECFSZ byte_num,1
BCF RA,bSDA ; Output bit 0 to continue further input
BSF RA,bSCL
NOPn 5
BCF RA,bSCL ; Return bSCL to low
TSTF byte_num
SKPZ
goto ICRd_loop
CALL ICSTOP ; Generate STOP bit
RETLW 0
;---------------------------------------------------------
;---------------------------------------------------------
;---------------------------------------------------------
; 485接收设定
;---------------------------------------------------------
RC485MODE: ;RC485MODE
RegBnk1
BSF TRISC,RXD485 ;MOVLW B'11111001' ; RXD485 I / TXD485 O
BCF TRISC,TXD485 ;MOVWF TRISC ; SWRT O
BCF TRISB,RB2_485 ;RB2-->OUTPUT MODE
MOVLW .51 ; SET BAUD RATE 1200 BPS
MOVWF SPBRG
BCF TXSTA,BRGH ; BRGH LOW SPEED
BCF TXSTA,SYNC ; ASYNC MODE
RegBnk0
BSF RCSTA,SPEN ; STEP 2
BSF RB,RB2_485 ; RB2,CHANGE RECEIVE MODE
RegBnk1
BSF PIE1,RCIE ; STEP 3
RegBnk0
BSF RCSTA, RC89 ; RX9 9BIT ; STEP 4
BSF RCSTA,CREN ; STEP 5
; STEP 6 IF RCIF BE SET WILL GENERATE AN INTERRUPT
; STEP 7 READ RCSTA TO GET 9TH BIT
; AND DETERMINE IF ANY ERROR
; STEP 8 READ RCREG DATA
; STEP 9 IF ANY ERROR OCCURRED, CLEAR
RETLW 0
;-----------------------------------------------------------------
; RS485 和 IrDA共用模块
;-----------------------------------------------------------------
MKEVENBIT:
RegBnk0
CLRF STATUS ;EVEN CHECK
MOVWF temp_2 ;要检测(校验)的数据.
MOVLW .8
MOVWF temp_3
CLRF temp_4 ;CLEAR RS485CNT
MKEVENLP1:
RRF temp_2
BTFSC STATUS,C ; IF C = 0 NOT COUNT
INCF temp_4 ;"1"的个数+1
DECFSZ temp_3
GOTO MKEVENLP1
RRF temp_2
RETLW 0
;======================================================================
;====================== Main Program ================================== ;电表上电/WDT溢出复位.
; ;电表上电/WDT溢出复位.
; ;恢复基本设置(设置T1,T2,INT,UAST...)需转此.
;======================================================================
main:
;;btfss STATUS,TO ;"TO--0: WDT timeout"
;;goto mainloop ;"TO--1: POWER ON..."
bsf PCLATH,3 ;页1
goto meter_initer
;---------------恢复被"破坏的数据"时到此-------------------------
RDepm1:
;----------------------------------------------------------------
;----------------------------------------------------------------
mainloop:
RegBnk1 ; "逐显按键"检测.
bsf TRISA,RA0_SW ; 设制"RB0"为输入方式
bcf TRISA,RA1_LED ; 读卡指示"LED".
bcf TRISB,RB6_PW ;IC卡电源
NOPn 5
RegBnk0
;----------------------------------------------
btfsc RA,RA0_SW ; IC卡开关 = low ?
goto No_press_butn ; No,is high,no press button.
;-----------2004.4.7--------------------------
;bcf RB,RB6_PW
;bcf RA,RA1_LED ; 读卡指示"LED".
;---------------------------------------------
bcf RB,RB6_PW ;电源
bcf RA,RA1_LED ; 读卡指示"LED".
;-----------icrd------------------------------
;movlw IR_TXcv_Buf+.14 ; read special_card_flag
;movwf FSR ; from IC_Card
;movlw 2Ch ;2Ch ; to IC_RW_Buf -- IC_RW_Buf+3
;movwf address ; /
;movlw 4 ; total 4 bytes
;movwf byte_num ; /
;call ICRd ; /
;-------icwt------------------------
;RegBnk0
;movlw IR_TXcv_Buf+.12 ; write kWh_invalid_flag to IC card
;movwf FSR ; total 2 bytes
;movlw 2Ch ; /
;movwf address ; /
;movlw 4 ; /
;movwf byte_num ; /
;call ICWt ; okk/2004.5.3
;------------2004.4.7---------------------
;bsf CONTROL485,speaker ;蜂鸣器,1--响,0-不响.
;---------------------------------------------------
No_press_butn:
RegBnk0
bsf RB,RB6_PW ;IC卡电源
bsf RA,RA1_LED ; 读卡指示"LED".
movlw .200 ;delay=12*10=120ms
movwf press_sw_delay ;按键延时80ms
bcf prs_but_stat,press_sw ;0--无键"按下"
;------------------------------------------------------
Lcd_end_iR_Rec_prs: ;(接收)数据是否需处理检测.
;-------
RegBnk1
btfsc CONTROL485,ir_Txing ;1--在"发送数据,"不接收/不处理".
goto process_kWh ;0--已"发送完数据"可以接收.
;;---
RegBnk1
btfss CONTROL485,ir_Recing ;0--"接收数据完毕".
;; ;1--处在"接收数据状态"不去处理.
btfsc CONTROL485,ir_prs_end ;0--接收的"数据未处理".
goto process_kWh ;1--接收的"数据已处理".
;;---
bsf PCLATH,3 ;选页1.
goto ir_Rc_data ;转红外接收的"数据处理".
process_kWh: ;红外发送在10mS中断中处理.
goto mainloop
;------------------------------------------------------------
;---------------------外围中断处理---------------------------
;------------------------------------------------------------
;------------------------------------------------------------
;-----------TMR0 10ms 中断----------------------------------
MAIN_DELA:
BCF INTCON,T0IF ;clear tmro int flags
RegBnk1
MOVLW 85H ;85H OPTION_REG 64分频
MOVWF OPTION1 ;用于TMR0分频
;-------------------
RegBnk0
MOVLW .98 ;156*64=9984uS
MOVWF TMR0
;---------按键检测-------------------------------
;btfss RA,RA0_SW ; RB0.press = high?
;decf press_sw_delay,1 ; delay 50ms,(按键延时计数).
;--------循显时间--------------------------------
disp_test:
;------------1秒时间到?--------------------------
decfsz disp_time+1,1 ;为"00"时1秒时间到.
goto disp_timer_No
decf timer_Acount,1 ;广播表地址30S计时.
bcf RA,RA1_LED ;指示MPU"正常".
RegBnk1
bcf broadcast_stat,communct_okey ; 清"0"通讯成功指示.
;----------------------
bcf kWh_stat,kWhsgn_impuls ;LCD脉冲指示,1-有脉冲,0-没有脉冲
;----------------------
bsf TRISC,RC0_met_clear ; 设制"RC0"为输入方式
RegBnk0
;btfss RC,RC0_met_clear ; RC0 = high ?
;decf clear_met_sw,1 ; 清零电表键检测
;----------------------
movlw .250 ;100 = 1S
movwf disp_time+1
bsf RWepmSTA,Rd_Current_time ;set 1S read RTC_8563 flags bit.
;---------------------------------------------------------
power_on_deli:
btfss display_stat,disp_mode ;0--->按键方式,1-->循显方式
goto disp_timer_No
decfsz disp_ti_count,1 ;检测掌机设置的"XX秒"时间"到否?
goto disp_timer_No
movfw disp_time ;"00",恢复正确数据.
movwf disp_ti_count ;XX秒的循显时间
bsf display_stat,dip_loop_time ;1---循显时间到标志.
bcf dsp_flag3,disp_No_updata ;0-->1秒到,更新显示数据项.
disp_timer_No:
;;-------------------蜂鸣器"开/关"控制--------------------
RegBnk1
btfss CONTROL485,speaker ;蜂鸣器,1--响,0-不响.
goto TX485
bcf TRISB, RB1_buzzer ;RB2-->OUTPUT MODE
incf buzzer,1
movlw .25 ;15
SUBWF buzzer,W ;时间(10mS*15)
skpc
GOTO $+6
clrf buzzer ;大于0.15秒.
bcf CONTROL485,speaker ;蜂鸣器,1--响,0-不响.
RegBnk0
BSF RB,RB1_buzzer ;蜂鸣器不鸣叫.
goto TX485
RegBnk0
BCF RB,RB1_buzzer ;蜂鸣器鸣叫.
bsf RA,RA1_LED ;指示MPU"正常".
;-----------------------------------------------------------
;---------485发送模块(10ms中断),每隔10ms发送一个字节--------
;-----------------------------------------------------------
TX485:
clrwdt
RegBnk1
INCF CSCOM485,1 ;"485"超时控制字".
;;;;
BTFSS CONTROL485,ir_prs_end ;1--接收的数据处理完毕(可以发送).
GOTO TX485OUT ;0--红外接收的数据未处理
BTFSS CONTROL485,ir_Recing ;1--485处在接收状态,不可以发送
btfss CONTROL485,ir_Txing ;1--正"在发送"数据!
goto TX485END ;0--"已发送完"数据.
;;;;;;;;;
INCF COUNT485 ;已发送的"子节数"+1.
bsf PCLATH,3 ;选中页1
call ir_Tx_send ;********取"要发的数据".
bsf PCLATH,3
CALL TX485MODE ;设置为发送模式.
bcf PCLATH,3
;;;;;;;;;
RegBnk1
movfw TX_data ;要发的数据
bcf PCLATH,3 ;选择页面0
CALL MKEVENBIT ;偶检验
BTFSS temp_4,0 ;"1"的个数是奇数跳
GOTO ppdb
RegBnk1
BSF TXSTA,0 ;偶检验位置1
GOTO ppdb1
ppdb:
RegBnk1
BCF TXSTA,0 ;偶检验位清0
ppdb1:
RegBnk1
MOVFW TX_data
RegBnk0
MOVWF TXREG ;要发的数据给"TXREG"
GOTO TX485OUT
;-----------------------------------------------------
TX485END:
;10ms中断中,检测有无"接收错误",有则清除.
RegBnk1 ;??????????
BCF TXSTA,TXEN ;2003.2.18
RegBnk0 ;??????
MOVF RCSTA,W ;RCSTA---接收状态寄存器.
movwf temp_1
btfss temp_1,1 ;1---越位错误.
goto $+2
goto $+3
btfss temp_1,2 ;1---格式错误.
goto No_RC_err
bcf RCSTA,CREN ;清"0"越位溢出错误.
nop
bsf RCSTA,CREN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -