外部中断模拟串口,波特率不能超过65536
实验测试:发送57600可以正常,但接收只能 <= 38400
#include "Uart_EXT0.h"
#include "MAIN.h"
#define FOCS 22114800ul
bit Over;
bit bRxflag;
unsigned char IEN0_NOW,IEN1_NOW; //中断临时变量
unsigned char idata bRxstate=0; //接收状态
unsigned char idata tmp_Len=0; //缓存数组下标
unsigned char idata bRxlen; //接收字节数
unsigned char xdata EX_buf[64]; //接收存放区
/***************************************************
baud = 56000 接收一字节 =178.6us ,接收会出现错误
baud = 38400 接收一字节 =260.4us //快速接收都容易出现错误
baud = 19200 接收一字节 =520us |
baud = 14400 接收一字节 =694.5us |
baud = 9600 接收一字节 =1041.6us |
baud = 4800 接收一字节 =2.083ms 接收过长,定时器MODE2无法满足
//主机发送的数据最好加上校验字
发送:最大57600,发送还能正常。
****************************************************/
void Time0_Uart(unsigned int baud)
{
TMOD &= 0XF0;
TMOD |= 0X02; //使用定时器0方式2,使用方式1则2400波特也能有
TH0 = 256-(FOCS/12)/baud;
TL0 = TH0;
IP0 |= 0x02; //设置为最高优先级
IP1 |= 0x02;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Time0_isr() interrupt 1
{
//方式1则重装值
Over = 1;
}
/* 发送数据,1起始位,8数据,1停止位
发送波特率实验57600都不会错误,大量发送数据待测试
*/
void Uart_set(unsigned char dat)
{ unsigned char i;
Over = 0;
TL0 = TH0; //防止发送数据开始时不知道TL0是多少
T_uart = 0; //起始位
while(Over==0);
Over = 0;
for(i=0;i<8;i++) //8数据位
{// Over = 0; //起始位时清零了
if(dat&0x01) //先发最低位
{
T_uart = 1;
}
else
{
T_uart = 0;
}
while(Over==0);
Over = 0;
dat >>= 1;
}
// Over = 0; //数据位清零了
T_uart = 1; //停止位,此后如果没有数据则一直为高
while(Over==0);
}
unsigned char get_Uart()
{
unsigned char I=0,get_dat=0;
Over = 0;
TL0 = TH0; //重新赋值,防止出错
while(Over==0);
Over = 0;
for(I=0;I<8;I++)
{
get_dat >>= 1;
if(Get_ex == 1)
get_dat |= 0x80;
else
get_dat &= 0x7f;
while(Over==0);
Over = 0;
}
if(Get_ex == 1)
{
Over = 0;
}
return get_dat;
}
void EXuart_isr() interrupt 0
{ unsigned char _chr;
IEN0_NOW = IEN0; //进入接收1字节,关闭中断
IEN1_NOW = IEN1;
IEN0 = 0X82;
IEN1 = 0;
_chr=get_Uart();
switch(bRxstate)
{
case 0:
if(_chr==0x55)
{
bRxstate=1;
}
else
bRxstate=0;
break;
case 1:
if(_chr==0xaa)
{
bRxstate=2;
}
else
bRxstate=0;
break;
case 2:
//取得数据长度
bRxlen=_chr;
bRxstate=3;
break;
case 3:
EX_buf[tmp_Len]=_chr;
tmp_Len++;
if(tmp_Len==bRxlen)
{
bRxstate=0;
tmp_Len=0;
bRxflag=1; //一帧数据接收完毕,置位完成标志位
}
break;
default:
break;
}
IE0 = 0; //清外部0中断标志,防止下次接收不到
IEN0 = IEN0_NOW;
IEN1 = IEN1_NOW;
}
void main()
{
Time0_Uart(9600);
EX_uart();
if(bRxflag==1)
{
bRxflag = 0;
for(i=0;i<10;i++)
RevBuffer[i] = EX_buf[i];
T0Uart_TX(10,RevBuffer);
}
}
2022-06-21 15:14:28
61KB
模拟串口
51
1