pic16f627键盘显示+E2PROM存取+模拟I2C总线通信等模块
扫描二维码
随时随地手机看文章
;pIC16f627键盘显示+E2PROM存取+模拟I2C总线通信等模块示例程序
;已经调试通过,愿与各位初学者共享
listp=16f627;listdirectivetodefineprocessor
#include
;__CONFIG(_INCRC_OSC_NOCLKOUT&_MCLRE_OFF&_LVP_OFF&_PWRTE_ON&_BODEN_ON&_WDT_ON);
;数据寄存器及标号定义:
SDAEQU2;PA2
SCLEQU3;PA3
DSLEQU4;PA4,LED低位
DSHEQU7;PB7,LED高位
S1EQU1;PA1,UP
S2EQU0;PA0,DOWN
LED_LEQU20H;LED低位数据积存器
LED_HEQU21H;LED高位数据积存器
LED_NLEQU22H;LED低位计数器
LED_NHEQU23H;LED高位计数器
CH_XEQU24H;频道值寄存器
ADDREQU25H;EEPROM读写地址
VALUEQU26H;EEPROM写入值
REC_EQU27H;EEPROM读计数
WRC_EQU28H;EEPROM写计数
DATA0EQU29H;EEPROM读出值
MD_ADDR_WEQU0C8H;3050ADDRESS/WRITE
MD_ADDR_REQU0C9H;3050ADDRESSREAD
DATA1EQU2AH;3050寄存器组
DATA2EQU2BH;
DATA3EQU2CH;
DATA4EQU2DH;
SG_S1EQU2FH;SIGN_S1
SG_S2EQU30H;SIGN_S2
W_TEMPEQU31H
;W_TEMPEQU0B1H
STATUS_TEMPEQU32H
;STATUS_TEMPEQU0B2H
WWEQU33H;通用寄存器
WW_TEMPEQU34H
SG_DISEQU35H;LED高低位显示标志
UVHFEQU36H;
BIT_SGEQU37H;
F0EQU0;I2C通信中应答信号正常(0)与不正常(1)标志
KEY_UEQU1
KEY_DEQU2
KEY_UOKEQU3
KEY_DOKEQU4
CUNT1EQU38H
CUNT2EQU39H
TIM_CUNT1EQU3AH;
TIM_CUNT2EQU3BH;
CUNT3EQU3EH
CUNT4EQU3FH
;////////////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////
;---------------PROGRAMFILE-------------------
ORG00H;processorresetvector
GOTOSTART
ORG04H
BTFSCPIR1,TMR1IF
GOTOT0_INT
RETFIE
ORG10H
;////////////////////////////////////////////////////////////////
LED_VALU:MOVWFPCL;
LED_TAB:RETLW10H;0
RETLW73H;1
RETLW44H;2
RETLW41H;3
RETLW23H;4
RETLW09H;5
RETLW08H;6
RETLW53H;7
RETLW00H;8
RETLW01H;9
;/////////////////////////////////////////////////////////////////
CXA_VALU1:MOVWFPCL
CXA_TAB1:DT19H,24H;CH0DATA2,DATA3
DT19H,24H;CH1
……
DT38H,04H;CH12
CXA_VALU2:MOVWFPCL
CXA_TAB2:DT75H,0C4H;CH21DATA2,DATA3
DT77H,0C4H;CH22
……
DT0D5H,0C4H;CH69
CXA_VALU3:MOVWFPCL
CXA_TAB3:DT0ECH,62H;CH21DATA1,DATA4
DT0ECH,62H;CH22
……
DT0ECH,62H;CH69
START:
;CALL3FFH
;MOVWFOSCCAL
CLRWDT
BSFSTATUS,RP0;BANK1
BCFSTATUS,RP1
BSFPCON,OSCF;选择内部4MRC震荡器
BCFSTATUS,RP0;BANK0
CLRFPORTA;I/O口设置
CLRFPORTB
MOVLW07H
MOVWFCMCON
BSFSTATUS,RP0;BANK1
MOVLW0E3H;PA.0.1.5.6.7为输入,其余为输出
MOVWFTRISA
MOVLW00H
MOVWFTRISB
BCFSTATUS,RP0;BANK0
MOVLW20H;寄存器20H/7FH清零
MOVWFFSR
LOOP:CLRFINDF
INCFFSR
BTFSSFSR,7
GOTOLOOP
;首次开机判别
NOP
NOP
MOVLW00H;检测EEPROM地址00H是否为55H
MOVWFADDR;EEPROM地址→ADDR
CALLEEPROM_R;ADDR内容读至DATA0
MOVFDATA0,W
ANDLW0AAH
BTFSCSTATUS,Z
GOTOOLD_CH
NOP;首次开机21频道设定
MOVLW00H;EEPROM的00H地址放首次开机标志
MOVWFADDR
MOVLW55H
MOVWFVALU
CALLEEPROM_W
MOVLW01H;EEPROM的01H地址放频道值CH_X
MOVWFADDR
MOVLW15H;05H;
MOVWFVALU
CALLEEPROM_W
NOP
MOVLW02H;02H地址做CH_X备份,以防出错
MOVWFADDR
MOVLW05H
MOVWFVALU
CALLEEPROM_W
MOVLW15H;05H;首次开机选择CH5频道
MOVWFCH_X
GOTOCH_SET
NOP
OLD_CH:MOVLW01H
MOVWFADDR
CALLEEPROM_R
MOVWFCH_X
CH_SET:CALLLED_HL
NOP
NOP
CALLCXA
NOP
;定时器1初始化
BSFINTCON,GIE;总中断使能
BSFINTCON,PEIE;
BCFPIR1,TMR1IF;
BSFSTATUS,RP0;BANK1
BSFPIE1,TMR1IE;开定时器1中断
BCFSTATUS,RP0;BANK0
MOVLW0D8H;TIM1中断周期10ms
MOVWFTMR1H;
MOVLW0EFH
MOVWFTMR1L
CLRFT1CON
BSFT1CON,TMR1ON;定时器1启动
GOTOMAIN
MAIN:NOP
NOP
CLRWDT
NOP
NOP
;GOTOMAIN
;CALLDELAY;延时10毫秒
NOP
NOP
NOP
NOP
BTFSCBIT_SG,KEY_U
CALLKEY_INC
NOP
NOP
NOP
NOP
BTFSCBIT_SG,KEY_D
CALLKEY_DEC
NOP
NOP
NOP
NOP
BTFSCBIT_SG,KEY_DOK
GOTOKEY_DEC_OK
NOP
NOP
NOP
NOP
BTFSCBIT_SG,KEY_UOK
GOTOKEY_INC_OK
NOP
NOP
NOP
NOP
GOTOMAIN
KEY_DEC_OK:NOP
CALLKEY_DEC;确认有DOWN键按下并放开
NOP
BCFBIT_SG,KEY_DOK
GOTOCH_NEW
KEY_INC_OK:NOP
CALLKEY_INC;确认有UP键按下并放开
NOP
BCFBIT_SG,KEY_UOK
CH_NEW:CLRFSG_S1
CLRFSG_S2
NOP
CALLLED_HL;显示新频道
NOP
NOP
CALLCXA;设定新频道
NOP
NOP
MOVFCH_X,W
MOVWFVALU
MOVLW01H
MOVWFADDR
NOP
CALLEEPROM_W;保存新频道
NOP
NOP
GOTOMAIN
KEY_INC:MOVFCH_X,W
MOVWFWW
MOVLW0CH;
SUBWFWW,W
BTFSCSTATUS,Z
GOTOCH21;CH_X=CH12加1转CH_21
MOVLW45H;
SUBWFWW,W
BTFSCSTATUS,Z
GOTOCH21;CH5;CH_X=CH69加1转CH_5
INCFCH_X,F;其它正常加1
GOTOINC_RET
CH21:MOVLW15H
MOVWFCH_X
GOTOINC_RET
CH5:MOVLW05H
MOVWFCH_X
NOP
INC_RET:NOP
CALLLED_HL
BCFBIT_SG,KEY_U
RETURN
KEY_DEC:NOP
MOVFCH_X,W;确认有DOWN键按下
MOVWFWW
MOVLW05H
SUBWFWW,W
BTFSCSTATUS,Z
GOTOCH69;CH_X=CH5减1转CH_68
MOVLW15H
SUBWFWW,W
BTFSCSTATUS,Z
GOTOCH69;CH12;CH_X=CH21减1转CH_12
DECFCH_X,F;其它正常减1
GOTODEC_RET
CH69:MOVLW45H;CH_69
MOVWFCH_X
GOTODEC_RET
CH12:MOVLW0CH;CH_12
MOVWFCH_X
NOP
DEC_RET:CALLLED_HL
BCFBIT_SG,KEY_D
NOP
RETURN
;////////////////////////////////////////////////////////////////////////
T0_INT:
MOVWFW_TEMP
SWAPFSTATUS,W
MOVWFSTATUS_TEMP
MOVFWW,W
MOVWFWW_TEMP
BCFSTATUS,RP0
BCFPIR1,TMR1IF
MOVLW0D8H;TIM1中断周期10ms
MOVWFTMR1H;
MOVLW0EFH
MOVWFTMR1L
CLRWDT
MOVFTIM_CUNT1,W;计数器TIM_CUNT1
BTFSCSTATUS,Z
GOTOINT00
DECFTIM_CUNT1,F
INT00:NOP
NOP
MOVFTIM_CUNT2,W;计数器TIM_CUNT2
BTFSCSTATUS,Z
GOTOINT01
DECFTIM_CUNT2,F
INT01:NOP
NOP
CALLDISPLAY;显示LED
NOP
NOP
CALLKEYBOARD;检测键盘
NOP
NOP
NOP
NOP;
MOVFWW_TEMP,W
MOVWFWW
SWAPFSTATUS_TEMP,W
MOVWFSTATUS
SWAPFW_TEMP,F
SWAPFW_TEMP,W
RETFIE
;////////////////////////////////////////////////////////////////////////
KEYBOARD:
BCFSTATUS,RP0
BCFSTATUS,RP1;BANK0
BTFSSPORTA,S1
GOTODOWN
NOP
BTFSSPORTA,S2
GOTOUP
GOTOKEY_SCH
;去抖动
DOWN:BTFSSSG_S1,0
GOTODOWN1;第一次有DOWN键按下
BTFSCSG_S1,1
GOTODOWN2;长按键
BSFSG_S1,1;确认有DOWN键按下
GOTOKEY_RET
DOWN1:BSFSG_S1,0;第一次有DOWN键按下标志
GOTOKEY_RET
NOP
DOWN2:BTFSCSG_S1,2
GOTODOWN3
MOVLW14H;确认有长键延时200ms
MOVWFTIM_CUNT1
BSFSG_S1,2
GOTOKEY_RET
DOWN3:MOVFTIM_CUNT1,W
BTFSSSTATUS,Z
GOTOKEY_RET
BSFBIT_SG,KEY_D;
MOVLW14H;长按键周期200ms
MOVWFTIM_CUNT1
GOTOKEY_RET
UP:BTFSSSG_S2,0
GOTOUP1;第一次有UP键按下
BTFSCSG_S2,1
GOTOUP2;长按键
BSFSG_S2,1;确认有UP键按下
GOTOKEY_RET
UP1:BSFSG_S2,0;第一次有UP键按下标志
GOTOKEY_RET
NOP
UP2:BTFSCSG_S2,2
GOTOUP3
MOVLW14H;确认有长键延时200ms
MOVWFTIM_CUNT2
BSFSG_S2,2
GOTOKEY_RET
UP3:MOVFTIM_CUNT2,W
BTFSSSTATUS,Z
GOTOKEY_RET
BSFBIT_SG,KEY_U;
MOVLW14H;长按键周期200ms
MOVWFTIM_CUNT2
GOTOKEY_RET
;
KEY_SCH:BTFSSSG_S1,1
GOTOKEY_SCH1
BSFBIT_SG,KEY_DOK;确认有DOWN键按下并放开
GOTOKEY_RET
KEY_SCH1:BTFSSSG_S2,1
GOTONOKEY
BSFBIT_SG,KEY_UOK;确认有UP键按下并放开
GOTOKEY_RET
NOKEY:CLRFSG_S1;排除干扰
CLRFSG_S2
KEY_RET:NOP
NOP
RETURN
;////////////////;LED显示/////////////////////////////////////////////////////////
DISPLAY:NOP
BTFSCSG_DIS,0
GOTODIS_H
DIS_L:BCFPORTB,DSH;显示低位
MOVFLED_L,W
MOVWFPORTB
BSFPORTA,DSL
BSFSG_DIS,0
GOTODIS_RET
DIS_H:BCFPORTA,DSL;显示高位
MOVFLED_H,W
MOVWFPORTB
BSFPORTB,DSH
BCFSG_DIS,0
DIS_RET:NOP
RETURN
;////////////////LED显示值获取/////////////////////////////////////////////////////////
LED_HL:CLRFLED_NH
CLRFLED_NL
MOVFCH_X,W
MOVWFWW
LED0:MOVLW0AH
SUBWFWW,W
BTFSSSTATUS,C;SKPC
GOTOLED_OK;WW小于10
MOVWFWW
INCFLED_NH;高位加一
GOTOLED0
LED_OK:MOVFWW,W
MOVWFLED_NL;余数做低位
MOVLWLED_TAB;取表LED_TAB
MOVWFWW
MOVFLED_NL,W
ADDWFWW,W;
CALLLED_VALU
MOVWFLED_L
MOVLWLED_TAB;取表LED_TAB
MOVWFWW
MOVFLED_NH,W
ADDWFWW,W;
CALLLED_VALU
MOVWFLED_H
RETURN
;//////////////////////////////////////////////////////////////////////////////////
;///////////////频道设定///////////////////////////////////////////////////////////
CXA:BCFSTATUS,RP0
BCFSTATUS,RP1;BANK0
CLRWDT
MOVFCH_X,W;VHF/UHF判断
MOVWFUVHF
SUBLW0DH;CH_X是否小于13?
BTFSCSTATUS,C;SKPC
GOTOVHF_GET;小于则转VHF_GET
MOVLW15H;21
SUBWFUVHF,F;频道值入UVHF
UHF_GET:MOVLWCXA_TAB2;取表CXA_TAB2
MOVWFWW
BCFSTATUS,C;CLRC
RLFUVHF,F
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU2
MOVWFDATA2
INCFUVHF
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU2
MOVWFDATA3
GOTOI2C_SEND
DECFUVHF;DATA1,DATA4
MOVLWCXA_TAB3;取表CXA_TAB3
MOVWFWW
;BCFSTATUS,C;CLRC
;RLFUVHF,F
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU3
MOVWFDATA1
INCFUVHF
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU3
MOVWFDATA4
GOTOI2C_SEND
;////////////////////////////////////////////////////////////
VHF_GET:MOVLWCXA_TAB1;取表CXA_TAB1
MOVWFWW
BCFSTATUS,C;CLRC
RLFUVHF,F
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU1
MOVWFDATA2
INCFUVHF
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU1
MOVWFDATA3
GOTOI2C_SEND
DECFUVHF;DATA1,DATA4
MOVLWCXA_TAB3;取表CXA_TAB4
MOVWFWW
;BCFSTATUS,C;CLRC
;RLFUVHF,F
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU3
MOVWFDATA1
INCFUVHF
MOVFUVHF,W
ADDWFWW,W;
CALLCXA_VALU3
MOVWFDATA4
GOTOI2C_SEND
;/////////////////////////////////////////////////////////////////////////////
I2C_SEND:NOP
MOVLWB’11101100’
MOVWFDATA1
MOVLW00H;B’01100010’
MOVWFDATA4
I2C_START:NOP
CLRWDT
BCFINTCON,GIE
MOVLW04H;发送4个字节
MOVWFCUNT2
CALLSTA;启动I2C总线
MOVLWMD_ADDR_W;I2C地址
MOVWFWW
CALLWRBYT
CALLCACK
BTFSCBIT_SG,F0
GOTOI2C_START;非应答位则重发
MOVLWDATA1;所发4字节数据的首地址
MOVWFFSR
WRDA:MOVFINDF,W
MOVWFWW
CALLWRBYT
CALLCACK
BTFSCBIT_SG,F0
GOTOI2C_SEND;发送有误,重发
INCFFSR
DECFSZCUNT2,F
GOTOWRDA
CALLSTOP
BSFINTCON,GIE
RETURN
STA:BSFPORTA,SDA
BSFPORTA,SCL
NOP
NOP
NOP
NOP
BCFPORTA,SDA
NOP
NOP
NOP
NOP
BCFPORTA,SCL
RETURN
STOP:BCFPORTA,SDA
BSFPORTA,SCL
NOP
NOP
NOP
NOP
BSFPORTA,SDA
NOP
NOP
NOP
NOP
BCFPORTA,SDA
BCFPORTA,SCL
RETURN
CACK:BSFSTATUS,RP0
BSFTRISA,SDA
BCFSTATUS,RP0
BSFPORTA,SCL
NOP
NOP
NOP
NOP
BCFBIT_SG,F0
BTFSCPORTA,SDA
BSFBIT_SG,F0
CEND:BCFPORTA,SCL
BSFSTATUS,RP0
BCFTRISA,SDA
BCFSTATUS,RP0
RETURN
WRBYT:MOVLW08H
MOVWFCUNT1
WLP:RLFWW,F
BTFSSSTATUS,C;SKPC
GOTOWR0
GOTOWR1
WLP1:DECFSZCUNT1,F
GOTOWLP
RETURN
WR1:BSFPORTA,SDA
BSFPORTA,SCL
NOP
NOP
NOP
NOP
BCFPORTA,SCL
BCFPORTA,SDA
GOTOWLP1
WR0:BCFPORTA,SDA
BSFPORTA,SCL
NOP
NOP
NOP
NOP
BCFPORTA,SCL
GOTOWLP1
;//////////////////////////////////////////////////////////////////////////
;//////////////////////////////////////////////////////////////////////////
EEPROM_R:;EEPROM读子程序,把地址ADDR中内容读至DATA0
BCFSTATUS,RP1;BANK0
BCFSTATUS,RP0
MOVFADDR,W
BSFSTATUS,RP0;BANK1
MOVWFEEADR
BCFEECON1,WRERR
BSFEECON1,RD
MOVFEEDATA,W
BCFSTATUS,RP0;BANK0
MOVWFDATA0
RETURN;不带参数返回
;//////////////////////////////////////////////////////////////////////////
EEPROM_W:;EEPROM写子程序,把VALU中数值写入地址ADDR
CLRWDT
BCFSTATUS,RP1;BANK1
BSFSTATUS,RP0
BTFSCEECON1,WR;等待写允许
GOTO$-1
BCFSTATUS,RP0;BANK0
MOVFADDR,W
BSFSTATUS,RP0;BANK1
MOVWFEEADR
BCFSTATUS,RP0;BANK0
MOVFVALU,W
BSFSTATUS,RP0;BANK1
MOVWFEEDATA
BCFEECON1,WRERR
BSFEECON1,WREN
BCFINTCON,GIE
MOVLW55H
MOVWFEECON2
MOVLW0AAH
MOVWFEECON2
BSFEECON1,WR
BTFSCEECON1,WR
GOTO$-1
BSFINTCON,GIE;写结束
BCFEECON1,WREN
BCFSTATUS,RP0;BANK0
RETURN;不带参数返回
;////////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////
DELAY:MOVLW05H
MOVWFCUNT3
DELAY1:NOP;2ms
CLRWDT
MOVLW0FFH
MOVWFCUNT4
DELAY2:NOP
MOVFCUNT4,W
NOP
BTFSCSTATUS,Z
GOTODELAY3
NOP
DECFCUNT4,F
NOP
GOTODELAY2
DELAY3:NOP
MOVFCUNT3,W
BTFSCSTATUS,Z
GOTODELAY_RET
NOP
DECFCUNT3,F
NOP
GOTODELAY1
NOP
DELAY_RET:RETURN
;////////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////
FILL(GOTO$),NEXT_BLOCK-$
ORG03FFH
NEXT_BLOCK:
END