我们都知道如何使用系统配置的串口初始化函数去使用我们的串口,就是只能使用固定的引脚去进行串行通信,就是下面这种方法,
如果想要使用其他的引脚来进行串行通信,就不可以了。下面教大学如何使用模拟串行通信,即可以使用任意引脚进行数据的收发。
1.计算传输一位数据所需要的时间,这与通信的波特率有关,在这里以波特率为1200bps为例。
波特率为1200,意思就是每秒传输的位数是1200位,那么每一位传输的时间就是1/1200*10的6次方=833us
这就表示传输每一位的时间是833us。
2.了解串行数据收发的过程,它的一帧数据一般包括1个起始位 + 8位有效数据(即一个字节)+ 1位停止位,还有校验位,在这里可要可不要,为了初学者学起来比较简单,在这里就不要校验位了,那么它发送一个字节数据共需要发送10位。还需要注意的是,有效数据是从最低位开始发送,也是从最低位开始接收的。
3.知道了它发送数据,接收数据的原理和顺序,计算出它发送一位的时间,我们就可以开始写它的发送函数和接收函数了。
4.还有一个难点是如何处理号数据接收和数据发送的关系,让他们之间互不影响。接收一个字节时,需要等待起始位的到来,假设接收数据的引脚是RX,那么就需要一直等待RX为0后才可以接收数据,但是在程序里一直等待RX为0,会影响程序其他功能的使用。解决方法有两个,一是采用中断的方法,二是采用查询的方法,在这里我使用了查询的方法,如果不明白的话可以看下面的代码。
代码实现的功能是按下KEY1键,单片机发送0x01,按下KEY2键,单片机发送0x02;也可以通过串口助手向单片机发送数据,单片机接收到数据后,就再把接收到的数据发送给串口助手。这样的话,即可以实现基本的收发数据的功能。因为单片机的不同,有的地方可能有细微的区别,烧录后看不出效果的可以在下方留言,相互交流一下。
代码如下:
#include"STC15Fxxxx.h"
sbit TX =P3^1;
sbit RX =P3^0;
unsigned flag = 0;
sbit KEY1 = P0^0;
sbit KEY2 = P0^1;
void Delay833us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 12;
j = 244;
do
{
while (--j);
} while (--i);
}
void Delay416us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 6;
j = 247;
do
{
while (--j);
} while (--i);
}
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 144;
j = 157;
do
{
while (--j);
} while (--i);
}
//发送一个字节
void sendbyte(unsigned char num)
{
int i;
TX=1;
TX=0; //START
Delay833us();
for(i=0;i<8;i++)
{
if(num&0x01) TX=1;
else TX=0;
num=num>>1;
Delay833us();
}
TX=1; //STOP
Delay833us();
}
//接收一个字节
unsigned char receive()
{
int i = 0;
unsigned char temp,dat;
// TX=1;
// while(RX==1); //等待起始位 可以等待到起始位
Delay833us();
Delay416us();
for(i = 0;i < 8;i ++) //开始接收数据
{
dat >>= 1;
temp = RX;
if(temp)
dat |= 0x80;
else
dat &= 0x7f;
Delay833us();
}
P64 = ~P64;
flag = 3;
return dat;
}
void keyscan()
{
if(KEY1 == 0)
{
Delay10ms();
if(KEY1 == 0)
{
flag = 1;
while(KEY1 == 0);
}
}
if(KEY2 == 0)
{
Delay10ms();
if(KEY2 == 0)
{
flag = 2;
while(KEY2 == 0);
}
}
}
////////////////////
void main(void)
{
unsigned char value;
P07 = 0;
while(1)
{
if(RX == 0) //有数据需要接收
{
value = receive(); //接收数据
}
else
{
//按键1被按下,flag = 1;按键2被按下,flag = 2
keyscan();
if(flag == 1)
{
flag = 0;
sendbyte(0x01);
}
else if(flag == 2)
{
flag = 0;
sendbyte(0x02);
}
if(flag == 3) //接收到数据,并把它再次发送 出来
{
flag = 0;
Delay10ms();
Delay10ms();
Delay10ms();
Delay10ms();
Delay10ms();
Delay10ms();
sendbyte(value);
}
}
}
}