GPIO模拟串口

文章目录[隐藏]

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

生成海报
点赞 0

是葉先生了

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

华大MCU的IAP升级

折腾了些时间,总算解决了 芯片型号是HC32F460,用串口实现IAP升级,从21IC论坛中找到了同样的IAP升级源码,下载后,在自己的开发板上测试也没问题,阅读源码发现,作者的源码中串口通信部分没有用中断。 不过像这样的IAP程序也没有