1、并口通信与串口通信
对于8位单片机并口通信一般是使用8条数据线将字节的数据分为8位从8条数据线同时发送出去或接收进来,当然所需要的线并不止8条,一般还需要一些控制线,控制线的功能可以自己定义控制协议;而串口通信一般需要两条数据线(发送和接收数据线),发送和接收字节时,将数据从高位到低位或者从低位到高位一次发送一个位,将数据连续发送出去,对于同步串口通信一般还需要一个同步时钟线,异步串口通信不需要同步时钟线,但需要设置上位机和下位机为相同的波特率,波特率和同步时钟的功能是一样,就是确定数据发送和接收的抽样频率,如果抽样的频率不同,那么提取出来的数据肯定是不同的。
2、51单片机串口结构
第一步先了解51单片机的配置寄存器,主要涉及串口控制寄存器SCON(serial control)、工作方式控制寄存器TMOD(timer mode)、定时器控制寄存器TCON和特殊功能寄存器PCON。SCON主要是控制串口的工作方式以及保存串口状态;TMOD和TCON主要是用来设置波特率,我们一般是利用定时器T1来产生波特率,在一些增强51单片机上有独立的波特率发生器;PCON中的SMOD是控制串口的波特率选择,SMOD=1波特率加倍。
SCON | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
可位寻址
(1)
SM0 | SM1 | 功能 |
---|---|---|
0 | 0 | 同步移位寄存器方式(拓展IO口) |
0 | 1 | 8位异步收发,波特率可变 |
1 | 0 | 9位异步收发,波特率不可变 |
1 | 1 | 9位异步收发,波特率可变 |
(2)SM2一般不进行设置,默认值位0
(3)REN串口接收允许位
1:允许串口接收数据
0:禁止串口接收数据
(4)TB8发送的第9位数据,一般用来校验
(5) RB8接收的第9位数据,一般用来校验
(6)TI发送中断标志位,但一帧数据发送完毕,TI由硬件置一,并申请中断,但不一定需要响应中断,可以通过软件查询方式来读取数据,如果通过软件查询,需要在发送数据前将串口中断关闭,另外需要软件清零
(7)RI接收中断标志位,但一帧数据接收完毕,RI由硬件置一,并申请中断,虽然也可以软件查询,但是不推荐,实时太差,很容易丢失数据,另外需要软件清零。
具体实现代码如下
主要实现功能是复位先发送一串字符(偶校验),在主函数中,将接收到的数据进行偶校验,校验成功发送回PC,同时在没有接收到数据时进入空闲模式。
;时钟频率:11.0592MHz
;串口波特率:9600
;运行芯片:stc12c5a60s2(兼容stc89c52)
BUSY BIT 20H.0
FLAG BIT 20H.1
EVENFLAG BIT 20H.2
TXDATA EQU 21H
RXDATA EQU 22H
ORG 0000H
LJMP START
ORG 0003H
; 外部中断0
ORG 000BH
; T0中断
ORG 0013H
; 外部中断1
ORG 001BH
; T1中断
ORG 0023H
; 串口中断
LJMP SERIAL
START:
CLR FLAG
CLR BUSY
MOV SP,#60H
MOV SCON,#0D0H;9位异步发送,波特率可变,允许串口接收数据
MOV TMOD,#20H;定时器T1,方式1
MOV TH1,#0FDH;波特率9600
MOV TL1,#0FDH
SETB TR1;启动定时器T1
SETB ES;允许串口中断
SETB EA;允许总中断
SETB P2^4
MOV DPTR,#STR
SENDSTR:
CLR A
MOVC A,@A+DPTR
JZ SENDEND
MOV TXDATA,A
LCALL SEND_DATA
INC DPTR
SJMP SENDSTR
SENDEND:
MainLoop:
JNB FLAG,LOOP1;判断是否接收到数据
MOV TXDATA,RXDATA
LCALL EVENPARITY;调用偶检验子程序
JNB EVENFLAG,LOOP1;判断偶检验是否成功
CLR FLAG;清除标志
CLR EVENFLAG
LCALL SEND_DATA;发送R3的数据
LOOP1:
MOV PCON,#01H;进入空闲模式
LCALL DELAY;调用延时子程序
CPL P2^4
SJMP MainLoop
EVENPARITY:
MOV A,TXDATA
MOV C,P
;偶校验
;C=0则运行JNB RB8,L2
;RB8=0校验正确则跳转到L2发送数据
;RB8=1顺序运行JNC LOOP1
;C=0校验出错跳转到LOOP1不发送数据
;C=1跳转到L1
;c=1不跳转
;RB=1跳转到L2
;RB=0顺序运行
;RB=0跳转到LOOP1不发送数据
JC L1;C为1跳转
JNB RB8,L2;RB8为0跳转
L1:
JNC L3;C为零跳出
JB RB8,L2
JNB RB8,L3
L2:
SETB EVENFLAG
RET
L3:
CLR EVENFLAG
RET
DELAY:;@11.0592MHz
PUSH 30H
PUSH 31H
PUSH 32H
MOV 30H,#17
MOV 31H,#28
MOV 32H,#23
NEXT:
DJNZ 32H,NEXT
DJNZ 31H,NEXT
DJNZ 30H,NEXT
;延时时间(32H)*(31H)*(30H)+(31H)*(30H)+(30H)次
POP 32H
POP 31H
POP 30H
RET
SEND_DATA:
PUSH ACC
PUSH PSW
JB BUSY,$
SETB BUSY
MOV A,TXDATA
MOV C,P
MOV TB8,C
MOV SBUF,TXDATA
POP ACC
POP PSW
RET
SERIAL:
PUSH ACC
PUSH PSW
JNB RI,NRX
CLR RI
SETB FLAG
MOV RXDATA,SBUF
CLR P2^7
NRX:
JNB TI,NTX
CLR TI
CLR BUSY
SETB P2^7
NTX:
POP PSW
POP ACC
RETI
STR:DB "HELLO WORD",0DH,0AH,0
END
波特率计算
9600=(1/32) * (11.0592M/ (12* (0xff-0xfd) ) )