由于工作需要需要通过一根IO线往外发送8位的命令,以下程序是老板定的一个雏形,不大明白:
流程大概是:定义两个缓存来存放要发送的数据,通过RRC指令从低位开始每1MS往外发一位。
当两个缓存里的值都是0FFH时认为没有数据要发送。发送从低电平开始,高电平结束,中间是数据位共10位。
程序代码:
HBQ_DAB BIT P2.1 ;发送端口
T_NN DATA 33H
HBQ_DA DATA 34H ;要发送的数据缓存
HBQ_DB DATA 35H ;要发送的数据缓存
HBQ_DAA DATA 36H ;缓存发送数据
HBQ_DA_OK BIT 20H ;是否需要发送标志
;=====主程序===============
ORG 00H
LJMP START
ORG 0BH
LJMP TM0
此处仍需ORG 0A0H?为什么?
;=======
START: MOV SP,#0C0H
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH ;IO口初始化
BG_T4: MOV R0,#0C0H ;开机清00-C0H
BGG: MOV A,#00H
MOV @R0,A
DJNZ R0,BGG
MOV TMOD,#01H ;选择定时器T0
MOV TCON,#00 ;关闭定时器T0,关闭EA总中断,清除定时T0溢出标志位
MOV TH0,#0B8H
MOV TL0,#00H ;T0定时10MS初值
SETB TR0 ;启动T0
SETB ET0 ;允许T0中断
SETB EA ;开放总中断EA
MOV HBQ_DA,#01100111B
JMP $
TM0: PUSH ACC
PUSH PSW
;延时10MS进入中断后,关闭T0,重新分配T0初值,再启动T0,实现T0十分频
CLR TCON.4
MOV TH0,#0F8H
MOV TL0,#0CDH ;定时1ms初值
SETB TCON.4
;------------------
;1/10ms波特率
;如果有数据,就会发送 一个起始位+8个数据位+1个结束位 共10bit
;------------------
INC T_NN ;中断1MS计数
MOV A,T_NN
CLR C
SUBB A,#10
JNC TM_001 ;如果CY=0则跳转,当T_NN小于10时,CY=1,往下执行;当T_NN大于等于10时,CY=0,跳转重新给T_NN清零
;------------------
JNB HBQ_DA_OK,TM_002 ;HBQ_DA_OK:判断是否在发送状态,为1时是正在发送,为0时没有发送任务
TM_003: MOV A,HBQ_DAA ;HBQ_DAA:发送时的移位寄存器,发送顺序:从低位输出 ->C ->HBQ_DAB 高位补1,发送完后HBQ_DAA会变成0FFH,如果HBQ_DAA中为0FFH,则认为无发送任务
SETB C ;假设发送3CH,0011 1100
RRC A ;从低位开始发送,发送第一位0后变成1001 1110,CY变成了0
MOV HBQ_DAB,C ;HBQ_DAB:DA引脚P2.1,把CY的值给到发送管脚
MOV HBQ_DAA,A ;发送了一位之后把没发送的位保留在 HBQ_DAA,同时退出T0中断,等待进入下一个中断继续发送
TM_002: POP PSW
POP ACC
RETI ;退出中断
TM_005: MOV HBQ_DAA,HBQ_DA ;把要发送的数据放在HBQ_DAA缓存
MOV HBQ_DA,#0FFH ;然后HBQ_DA的内存单元赋值为0FFH
TM_008: CLR HBQ_DAB ;把DA数据接口置0
SETB HBQ_DA_OK ;设置为1,需要发送
SJMP TM_006 ;跳转并退出中断
TM_007: MOV HBQ_DAA,HBQ_DB ;
MOV HBQ_DB,#0FFH
SJMP TM_008
TM_001: MOV T_NN,#00 ;发送一个数据开始的准备
SETB HBQ_DAB ;把DA数据接口置1
CLR HBQ_DA_OK ;清除需要发送标志位
MOV A,HBQ_DA ;待发送的值存放在HBQ_DA
CJNE A,#0FFH,TM_005 ;判断是否为0FFH,如果不是,说明有值要发送,跳转
MOV A,HBQ_DB ;如果为0FFH,存到HBQ_DB里去
CJNE A,#0FFH,TM_007;判断是否为0FFH,如果不是跳转发送,是则退出
TM_006: POP PSW ;退出中断前出栈
POP ACC
RETI
END
;==========================================================
其中,主程序给T0定时10MS赋了值,然后进入中断后重新赋值,不过赋值的是1MS的定时。
那么从第二次进入中断开始,每次进入中断的间隔是10MS还是1MS?KEIL仿真结果是第一次进入中断10MS,之后每次都是1MS进入。既然这样,为什么不直接定时1MS就完了? |