文章目录[隐藏]
GPIO模拟串口发送接收数据
简介:波特率9600bit/s,表示1s发送9600bit数据,也就是发送1bit数据间隔需要104us。本文是在11.0592M晶振下实现。
发送程序
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit GPIO_Send = P1^0;
u8 temp,cnt = 0;
u8 flag = 0;
u8 send_buf = 0xaa;
void Delay50ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Init()
{
TMOD |= 0x02;
TH0 = 256 - 96; //???
TL0 = TH0;
ET0 = 1;
EA = 1;
TR0 = 0;
GPIO_Send = 1;
}
void main()
{
Init();
GPIO_Send = 0; //t0
TR0 = 1;
while (1)
{;}
}
void time0() interrupt 1 //t1
{
if(cnt < 8)
{
cnt++;
temp = send_buf & 0x01;
send_buf >>= 1;
if(temp == 0)
GPIO_Send = 0;
else
GPIO_Send = 1;
}
else if(cnt == 8)
{
GPIO_Send = 1;
cnt = 0;
TR0 = 0;
}
if(cnt == 0)
{
Delay50ms();
GPIO_Send = 0;
send_buf = 0xaa;
TR0 = 1;
}
}
接收程序
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit GPIO_Read = P3^2;
sbit led1 = P2^0;
sbit led2 = P0^0;
u8 cnt1,cnt2;
u8 read_buf;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void init()
{
TMOD |= 0x02;
TH0 = 0;
TL0 = 0;
ET0 = 1;
TR0 = 0;
IT0 = 1;
EX0 = 1;
EA = 1;
}
void main()
{
init();
P3M1 = 0xff;
P3M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
while(1)
{
}
}
void int0() interrupt 0
{
EX0 = 0;
cnt2++;
if(cnt2 == 1)
{
TR0 = 0;
TH0 = 256 - 144; //??156us
TL0 = TH0;
TR0 = 1;
}
else if(cnt2 == 2)
{
cnt2 = 0;
}
}
void time0() interrupt 1
{
TR0 = 0;
TH0 = 256 - 96; //??104us //96-10 16
TL0 = TH0;
TR0 = 1;
if(cnt1 < 0x08)
{
read_buf >>= 1;
if(GPIO_Read)
read_buf |= 0x80;
cnt1++;
}
else if(cnt1 == 0x08 && GPIO_Read)
{
if(read_buf == 0xaa)
{
led2 = ~led2;
}
cnt1 = 0;
TR0 = 0;
EX0 = 1;
}
}
二合一
实现效果:发送01,led1亮,发送02,led2亮。
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit led1 = P0^0;
sbit led2 = P0^4;
sbit GPIO_Send = P1^1;
sbit GPIO_Read = P3^2;
u8 temp,t1;
u8 cnt1,cnt2,cnt3; //计数变量
u8 flag1 = 0; //发送还是接收
u8 flag2 = 0;
u8 send_buf = 0xaa;
u8 read_buf,temp_buf;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
void Init()
{
TMOD |= 0x02;
TH0 = 256 - 96;
TL0 = TH0;
ET0 = 1;
EX0 = 1;
IT0 = 1;
EA = 1;
GPIO_Send = 1;
}
void main()
{
Init();
P3M1 = 0xff;
P3M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
GPIO_Send = 0;
TR0 = 1;
while (1)
{
}
}
void time0() interrupt 1
{
if(flag1) //接收数据 PC-->MCU
{
TR0 = 0;
TH0 = 256 - 96; //重新修改定时初值
TL0 = TH0;
TR0 = 1;
if(cnt1 < 8)
{
cnt1++;
read_buf >>= 1;
if(GPIO_Read)
read_buf |= 0x80;
}
else if (cnt1 == 8 && GPIO_Read)
{
temp_buf = read_buf;
if(read_buf == 0x01)
{
led1 = ~led1;
flag2 = 1;
}
else if(read_buf == 0x02)
{
led2 = ~led2;
flag2 = 1;
}
cnt1 = 0;
flag1 = 0;
TR0 = 0;
GPIO_Send = 0;
t1 = GPIO_Read;
TR0 = 1;
}
}
else //发送数据 MCU-->PC
{
if(flag2 == 1)
{
send_buf = temp_buf;
flag2 = 0;
}
if(cnt2 < 8)
{
cnt2++;
temp = send_buf & 0x01;
send_buf >>= 1;
if(temp == 0)
GPIO_Send = 0;
else
GPIO_Send = 1;
}
else if(cnt2 == 8) //结束位拉高,计数标志位清零,关闭定时器0
{
GPIO_Send = 1;
cnt2 = 0;
TR0 = 0;
EX0 = 1;
}
}
}
void int0() interrupt 0
{
EX0 = 0;
cnt3++;
if(cnt3 == 1)
{
flag1 = 1;
TR0 = 0;
TH0 = 256 - 144; //延时104 + 52 进入第一个数据位的中间时刻
TL0 = TH0;
TR0 = 1;
}
else if(cnt3 == 2)
{
EX0 = 1;
cnt3 = 0;
}
}
版权声明:本文为CSDN博主「是葉先生了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ymqcd/article/details/122334203
GPIO模拟串口发送接收数据
简介:波特率9600bit/s,表示1s发送9600bit数据,也就是发送1bit数据间隔需要104us。本文是在11.0592M晶振下实现。
发送程序
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit GPIO_Send = P1^0;
u8 temp,cnt = 0;
u8 flag = 0;
u8 send_buf = 0xaa;
void Delay50ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Init()
{
TMOD |= 0x02;
TH0 = 256 - 96; //???
TL0 = TH0;
ET0 = 1;
EA = 1;
TR0 = 0;
GPIO_Send = 1;
}
void main()
{
Init();
GPIO_Send = 0; //t0
TR0 = 1;
while (1)
{;}
}
void time0() interrupt 1 //t1
{
if(cnt < 8)
{
cnt++;
temp = send_buf & 0x01;
send_buf >>= 1;
if(temp == 0)
GPIO_Send = 0;
else
GPIO_Send = 1;
}
else if(cnt == 8)
{
GPIO_Send = 1;
cnt = 0;
TR0 = 0;
}
if(cnt == 0)
{
Delay50ms();
GPIO_Send = 0;
send_buf = 0xaa;
TR0 = 1;
}
}
接收程序
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit GPIO_Read = P3^2;
sbit led1 = P2^0;
sbit led2 = P0^0;
u8 cnt1,cnt2;
u8 read_buf;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void init()
{
TMOD |= 0x02;
TH0 = 0;
TL0 = 0;
ET0 = 1;
TR0 = 0;
IT0 = 1;
EX0 = 1;
EA = 1;
}
void main()
{
init();
P3M1 = 0xff;
P3M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
while(1)
{
}
}
void int0() interrupt 0
{
EX0 = 0;
cnt2++;
if(cnt2 == 1)
{
TR0 = 0;
TH0 = 256 - 144; //??156us
TL0 = TH0;
TR0 = 1;
}
else if(cnt2 == 2)
{
cnt2 = 0;
}
}
void time0() interrupt 1
{
TR0 = 0;
TH0 = 256 - 96; //??104us //96-10 16
TL0 = TH0;
TR0 = 1;
if(cnt1 < 0x08)
{
read_buf >>= 1;
if(GPIO_Read)
read_buf |= 0x80;
cnt1++;
}
else if(cnt1 == 0x08 && GPIO_Read)
{
if(read_buf == 0xaa)
{
led2 = ~led2;
}
cnt1 = 0;
TR0 = 0;
EX0 = 1;
}
}
二合一
实现效果:发送01,led1亮,发送02,led2亮。
#include <reg52.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit led1 = P0^0;
sbit led2 = P0^4;
sbit GPIO_Send = P1^1;
sbit GPIO_Read = P3^2;
u8 temp,t1;
u8 cnt1,cnt2,cnt3; //计数变量
u8 flag1 = 0; //发送还是接收
u8 flag2 = 0;
u8 send_buf = 0xaa;
u8 read_buf,temp_buf;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
void Init()
{
TMOD |= 0x02;
TH0 = 256 - 96;
TL0 = TH0;
ET0 = 1;
EX0 = 1;
IT0 = 1;
EA = 1;
GPIO_Send = 1;
}
void main()
{
Init();
P3M1 = 0xff;
P3M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
GPIO_Send = 0;
TR0 = 1;
while (1)
{
}
}
void time0() interrupt 1
{
if(flag1) //接收数据 PC-->MCU
{
TR0 = 0;
TH0 = 256 - 96; //重新修改定时初值
TL0 = TH0;
TR0 = 1;
if(cnt1 < 8)
{
cnt1++;
read_buf >>= 1;
if(GPIO_Read)
read_buf |= 0x80;
}
else if (cnt1 == 8 && GPIO_Read)
{
temp_buf = read_buf;
if(read_buf == 0x01)
{
led1 = ~led1;
flag2 = 1;
}
else if(read_buf == 0x02)
{
led2 = ~led2;
flag2 = 1;
}
cnt1 = 0;
flag1 = 0;
TR0 = 0;
GPIO_Send = 0;
t1 = GPIO_Read;
TR0 = 1;
}
}
else //发送数据 MCU-->PC
{
if(flag2 == 1)
{
send_buf = temp_buf;
flag2 = 0;
}
if(cnt2 < 8)
{
cnt2++;
temp = send_buf & 0x01;
send_buf >>= 1;
if(temp == 0)
GPIO_Send = 0;
else
GPIO_Send = 1;
}
else if(cnt2 == 8) //结束位拉高,计数标志位清零,关闭定时器0
{
GPIO_Send = 1;
cnt2 = 0;
TR0 = 0;
EX0 = 1;
}
}
}
void int0() interrupt 0
{
EX0 = 0;
cnt3++;
if(cnt3 == 1)
{
flag1 = 1;
TR0 = 0;
TH0 = 256 - 144; //延时104 + 52 进入第一个数据位的中间时刻
TL0 = TH0;
TR0 = 1;
}
else if(cnt3 == 2)
{
EX0 = 1;
cnt3 = 0;
}
}
版权声明:本文为CSDN博主「是葉先生了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ymqcd/article/details/122334203
暂无评论