矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 1639|回复: 1

请教:串口接收的问题

[复制链接]
     
发表于 2021-7-4 14:09:42 | 显示全部楼层 |阅读模式
/*************************************************************************
程序功能:超时判断接收一串无固定数量的字符
制 订 人:
修订日期:
*************************************************************************/
#include<reg52.h>  //
#include"delay.h"  //  包含延时头文件
#include"Uart.h"
#include<intrins.h>

void timer0_Init();
void main()            //  进入主程序
{


         timer0_Init();
      UartInit();    //  串口初始化调用
         EA=1;
         P0=0x01;
         printf("Please waiting....\r\n");        // 开机画面
         sendString(".....\r\n");            //  开机画面
        while(1)            //
                            
        {
                  if(rec_flag==1)        //传送标志位置1,说明字符串传送完成,进入下面执行
                    {                         
                   sendString(rec_Buf);           //数据包发送给上位机
                        switch(rec_Buf[rec_cnt])//数据解析执行函数
                                 {
                                   case 0x01: P0=_crol_(P0,1);break;
                                   case 0x02: P0=_cror_(P0,1);break;
                                   case 0x03: P0=_crol_(P0,2);break;
                                   case 0x04: P0=_cror_(P0,2);break;

                                   default:break;
                                 }
                        rec_flag=0;        // 标志位变量清零
                        rec_cnt=0;//串口中断中接收字符数量清零
                        clean_rec_buf();//缓冲区数据清
                          
                        }  
               
        }
}
/*************************************************************************
原理:每个字符之间的时间间隔是1/9600(波特率)秒,超过此时间三到五倍,则认为
该数据包传输完毕。

*************************************************************************/
void timer0_Init() // 定时器0初始化
{
   TMOD=0x01&0x20;        // TMOD定时器设置两个都打开,一定要与一下双方开启条件
   TH0=(65536-1000)/256;         // 装初值为1Ms定时,波特率9600,字符之间间隔1.04毫秒
   TL0=(65536-1000)%256;         // 装初值为1Ms定时
   TF0=0;                                 //标志位清零,也可以不写
   ET0=1;                                 // 定时器0中断打开,由于2个中断都开,总中断在main()里打开
   TR0=1;                                 // 定时器0打开

}
void timer0_ISR() interrupt 1//定时器0中断服务函数
{
  TR0=0;                                   // 关闭 定时器0
          if(start_timer==1)//软件开关变量打开
          {
            rec_timer_cnt++;//字符间隔1毫秒次数定时累加
                    if(rec_timer_cnt>Max_TIMER_CNT) //当累加时间超时,数据包送完
                    {
                         rec_timer_cnt=0;        //字符间隔1毫秒次数清零
                             rec_flag=1;                //数据包送完标志变量置1,供主函数使用
                         start_timer=0;        //软件定时开关关闭
                //         rec_cnt=0;//串口中断中接收字符数量清零.(不要在主函数中清零。)
                     }
          }

  TH0=(65536-1000)/256;        // 重赋初值
  TL0=(65536-1000)%256;        // 重赋初值
  TR0=1;                                //打开定时器0
}




                rec_cnt=0;//串口中断中接收字符数量清零这一句放在主函数中就不执行switch语句内的程序
按道理来说,数据包解析后,对数据字符数量清零也可以。但仿真和开发板都不行。只有放在定时器0中断函数中清零才正常。
实在不明白怎么回事,还请大神解惑。
下面附件有程序和仿真。谢谢。














超时接收字符.zip

138.35 KB, 下载次数: 22

     
 楼主| 发表于 2021-7-4 21:10:46 | 显示全部楼层
唉,大神都在忙
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 02:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表