传统的8051系列单片机一般都装备一个串口,而STC 89C52RC增强型单片机也不破例,只要一个串口可供运用,这样就出问题了,假定当时单片机体系要求二个串口或多个串口进行一起通讯,8051系列单片机只要一个串口可供通讯就显得非常为难,可是在实践的运用中,有两种办法能够挑选。
办法2:在IO资源比较足够的情况下,能够经过IO来模仿串口的通讯,尽管这样会添加编程的难度,模仿串口的波特率会比真实的串口通讯低一个层次,可是仅有长处便是本钱上得到操控,并且经过不同的IO组合能够完结愈加之多的模仿串口,在实践运用中往往会选用模仿串口的办法来完结多串口通讯。
遍及运用串口通讯的数据流都是1位开始位、8位数据位、1位中止位的格局的,如表1。
表1
开始位 | 8位数据位 | 中止位 | |||||||
0 | Bit0 | Bit1 | Bit2 | Bit3 | Bit4 | Bit5 | Bit6 | Bit7 | 1 |
要注意的是,开始位作为辨认是否有数据到来,中止位标志数据现已发送完毕。开始位固定值为0,中止位固定值为1,那么为什么开始位要是0,中止位要是1呢?这个很好了解,假定中止位固定值为1,为了愈加易辨认数据的到来,电平的跳变最为简略也最简单辨认,那么当有数据来的时分,只要在规则的时刻内检测到发送过来的第一位的电平是否0值,就能够确认是否有数据到来;别的中止位为1的效果便是当没有收发数据之后引脚置为高电平起到抗干扰的效果。
在平常运用红外无线收发数据时,一般都选用模仿串口来完结的,可是有个问题要注意,波特率越高,传输间隔越近;波特率越低,传输间隔越远。关于这些经过模仿串口进行数据传输,波特率适合为1200b/s来进行数据传输。
模仿串口试验代码:
2
3
4
5
6
7
8
9
10
11
12unsignedcharfTimeouts=0;//T/C超时溢出标志位
13
14
15
16
17
23
24{
25unsignedchari=8;
26
27TXD=0;
28
29TIMER_ENABLE();
30TIMER_WAIT();
31
32
33while(i–)
34{
35if(b&1)TXD=1;
36elseTXD=0;
37
38TIMER_WAIT();
39
40b>>=1;
41
42}
43
44
45TXD=1;
46
47TIMER_WAIT();
48TIMER_DISABLE();
49}
50
56unsignedcharRecvByte(void)
57{
58unsignedchari;
59unsignedcharb=0;
60
61TIMER_ENABLE();
62TIMER_WAIT();
63
64for(i=0;i<8;i++)
65{
66if(RXD)b|=(1<67
68TIMER_WAIT();
69}
70
71TIMER_WAIT();//等候完毕位
72
73
74returnb;
75
76}
77
83
84{
85while(pstr&&*pstr)
86{
87SendByte(*pstr++);
88}
89}
90
96
97{
98TMOD=0x02;
99TR0=0;
100TF0=0;
101TH0=(256-99);
102TL0=TH0;
103ET0=1;
104EA=1;
105}
106
112unsignedcharStartBitCome(void)
113{
114return(RXD==0);
115}
116
122
123{
124unsignedchari;
125
126TimerInit();
127
128PrintfStr(“Hello 8051rn”);
129
130while(1)
131{
132if(StartBitCome())
133{
134RecvBuf[RecvCount++]=RecvByte();
135
136if(RecvCount>=RECEIVE_MAX_BYTES)
137{
138RecvCount=0;
139
140for(i=0;i
142SendByte(RecvBuf[i]);
143}
144}
145}
146
147}
148}
149
155
156{
157fTimeouts=1;
158}
159
在模仿串口试验代码中,宏的运用占用了适当的一部分。
#define RXD P3_0
#define TXD P3_1
#define TIMER_ENABLE()
#define TIMER_DISABLE() {TR0=0;fTimeouts=0;}//制止T/C
#define TIMER_WAIT()
模仿串口接纳引脚为P3.0,发送引脚为P3.1。为了到达准确的守时,削减模仿串口时收发数据的累积差错,有必要经过对T/C进行频频的使能和制止等操作。例如宏TIMER_ENABLE为使能T/C,宏TIMER_DISABLE制止T/C,宏TIMER_WAIT等候T/C超时。
模仿串口的作业波特率为9600b/s,在串口收发的数据流傍边,每一位的时刻为1/9600≈104us,
若单片机作业在12MHz频率下,运用T/C0作业在方法2,那么为了到达104us的守时时刻,TH0、TL0的初值为256-104=152,在实践的模仿串口中,往往呈现收发数据不正确的现象。原因就在于TH0、TL0的初值,或许很多人会疑问,按道理来说,核算T/C0的初值是没有错的。对,是没有错,可是在SendByte和Recv的函数傍边,履行每一行代码都要耗费必定的时刻,这便是所谓的“累积差错”导致收发数据呈现问题,因而咱们有必要经过实践测验得到TH0、TL0的初值,最佳值256-99=157。那么在T/C初始化TimerInit函数中,TH0、TL0的初值不能够依照惯例来核算得到,实践初值在正常初值邻近,能够经过实践测验得到。
模仿串口首要杂乱在模仿串口发送与接纳,详细完结函数在SendByte和RecvByte函数,这两个函数有必要要遵从“1位开始位、8位数据位、1位中止位”的数据流。
SendByte函数用于模仿串口发送数据,以开始位“0”作为移位传输的开始标志,然后即将发送的自己从低字节到高字节移位传输,最终以中止位“1”作为移位传输的完毕标志。
RecvByte函数用于模仿串口接纳数据,一旦检测到开始位“0”,就马上将接纳到的每一位移位存储,最终以判别中止位“1”完毕当时数据的接纳。
main函数完结T/C的初始化,在while(1)死循环以检测开始位“0”为意图,当接纳到的数据到达宏RECEIVE_MAX_BYTES的个数时,将接纳到的数据返发到外设。
波特率的研讨
8051系列单片机外接能够被除尽的晶振即12MHz、24MHz、48MHz这些晶振时,波特率的准确性就得不到确保。
波特率 (11.0592MHz) |
初值 | 波特率 (12MHz) |
初值 | ||
TH1、TL1 (SMOD=0) |
TH1、TL1 (SMOD=1) |
TH1、TL1 (SMOD=0) |
TH1、TL1 (SMOD=1) |
||
1200 | 0xE7 | 0xD0 | 1200 | 0xE5 | 0xCB |
2400 | 0xF3 | 0xE7 | 2400 | 0xF2 | 0xE5 |
4800 | 0xF9 | 0xF3 | 4800 | 0xF9 | 0xF2 |
9600 | 0xFC | 0xF9 | 9600 | 0xFC | 0xF9 |
14400 | 0xFD | 0xFB | 14400 | 0xFD | 0xFB |
19200 | 0xFE | 0xFC | 19200 | 0xFE | 0xFC |
波特率 (11.0592MHz) |
初值 | 波特率 (12MHz) |
初值 | ||
RCAL2H | RCAL2L | RCAL2H | RCAL2L | ||
1200 | 0xFE | 0xE0 | 1200 | 0xFE | 0xC8 |
2400 | 0xFF | 0x70 | 2400 | 0xFF | 0x64 |
4800 | 0xFF | 0xD8 | 4800 | 0xFF | 0xB2 |
9600 | 0xFF | 0xDC | 9600 | 0xFF | 0xD9 |
14400 | 0xFF | 0xE8 | 14400 | 0xFF | 0xE6 |
19200 | 0xFF | 0xEE | 19200 | 0xFF | 0xED |
假如我们想经过设置不同的晶振获取愈加多的波特率的值,能够下载以下东西进行核算:
软件下载地址:http://files.cnblogs.com/wenziqi/单片机多功能帮手.rar