//串口
#define TXD P54D //端口
volatile unsigned char tx;//数据
volatile unsigned char txb;//数据位数
volatile unsigned char txsend;//要求发送,遇到1 进行发送一次 发送结束 0
//p54端口发送
/*
波特率4800 =》 4800bit(位)每秒 =>480字符每秒
1起始位 8数据位 1停止位 共10bit
1000 000 /4800 =208.333us 则1bit的电平持续时间是208us 一个字符则需要2.08ms
起始位是低电平,停止位是高电平 则待机状态高电平 低位先发
*/
//串口发送数据
void usart_sent(void)//每次中断进入该函数是208us
{
if(!star)//未发送起始位
{
star=1;
TXD=0;
}
else//已发送起始位
{
if(!stop)//未发送停止位 处于发送数据位期间
{
if(tx&(0x01<<txb))//发送数据
{
TXD=1;//高电平
}
else
{
TXD=0;//低电平
}
txb++;//前面位数是txb 0-7
if(txb>=8)//发送完数据完成 完成 txb是7 +1后是8 结束数据位的发送
{
txb=0;
stop=1;//进行发送停止位
}
}
else
{
stop=0;
star=0;
TXD=1;//停止位是高电平
txsend=0;//发送结束后才能 不再进入txsend==5中,在进行txsend++计时
}
}
}
void main(void)
{
TXD=1;
txb=0;
stop=0;
star=0;
txsend=1;
//只需要修改发送的数据就可以了
tx=0x91;
}
void int_isr(void) __interrupt
{
__asm
push
__endasm;
//************需要放在208us中断中使用 对应设置波特率是4800
//我现在使用是104us 所以在计时上需要104*2
//当T0CNT递减到0时,此时产生T0溢出中断请求标志T0IF/T1IF置1
if(T0IF) //104us触发一次
{
T0IF=0;
T0CNT=0x9A;
timer0us_4++;
if(timer0us_4>=2)//104us*2
{
timer0us_4=0;
if(txsend==5)//设置间隔发送时间
{
usart_sent();
}
else
{
txsend++;
}
}
}
if(T1IF) //32uS
{
T1IF=0;
timer1us=1;
timer1ms_1++;
}
__asm
pop
__endasm;
}
使用定时器设置模拟串口发送功能,波特率是4800 ,需要配合208us定时器中断使用
#define RXD P15D //接受端口
volatile unsigned char rx;//数据位
volatile unsigned char rxbtime;//位数计时
volatile unsigned char rxb;//数据位数
volatile unsigned char stop;//空闲状态
volatile unsigned char key_val;//数据位主程序进行判断
//52us触发一次
//串口数据接收
void usart_accept(void)
{
//空闲状态。端口持续高电平
if(stop==1)
{
if(RXD==0)//一直等待发送端的起始信号,低电平
{
rxbtime=2;//在低电平的208us中需要在104us中再检测一次
rxb=0;//数据位0,发送端是低位先传
stop=0;//传输状态
}
}
else
{
if(rxbtime<=1)//延时计算时间
{
switch(rxb)
{
case 0://起始电平经过2*52=104us
if(RXD)//检测起始位是否真启动,
{
//起始位错误
stop=1;
rxb=0;
}
else
{
//延时208us进行检测 由于第一次起始位是在104us后续的208us都是
//在波形的中间检测,避免了临界有误差
rxbtime=4;
rxb++;
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
//先接收低位 右移7次 最后一次不需要右移 触发8次
rx=rx>>1;//当第一次rx=0是是无效的,下面才给0位赋值,
if(RXD)
{
rx=rx|0x80;
}
rxb++;
rxbtime=4;//延时208us进行检测
break;
case 9:
if(RXD)//等待停止位
{
stop=1;
rxb=0;
key_val=rx;
}
break;
}
}
else
{
rxbtime--;
}
}
}
void main (void)
{
stop=1;
while(1)
{
switch(key_val)
{
case 0xF0://按照发送端对应的码接受就可以了
.....//需要执行的命令
break;
case 0xF1:
....
break;
case 0xF2:
...
break;
case 0xF3:
.....
break;
case 0xF4:
.....
break;
case 0xF5:
.....
break;
}
key_val=0;
}
}
void int_isr(void)__interrupt
{
if((T0IF)&&(T0IE))//52us
{
T0CNT=151;
T0IF=0;
F_52us=1;
//每次进入52us定时器
usart_accept();
}
if((T1IF)&&(T1IE))//32us
{
T1CNT=255;
T1IF=0;
}
}
使用定时器设置模拟串口接受功能,波特率是4800 ,需要配合52us定时器中断使用
上方发送端使用芯片是晟矽微7041, 接收端使用芯片是晟矽微6060,可以成功实现,