求教89C52单片机计数器2用作波特率发生器的串口通信的问题

2019-07-18 09:03发布

各位大神,我编了一个C代码,计数外来脉冲的数量,然后把计数值通过串口传送给pc机实时显示,用计数器2来用作波特率发生器,但编写的程序有问题,串口调试助手显示乱码,请教大神指导,谢谢!
/*-----------------------------------------------
  名称:串口通信
  
  内容:连接好串口或者usb转串口至电脑,下载该程序,打开电源
        打开串口调试程序,将波特率设置为9600,无奇偶校验
        晶振11.0592MHz,发送和接收使用的格式相同,如都使用
        字符型格式,设置正确后接受框可以看到实时传送的计数值
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义                        
#define DataPort P0 //定义数据端口 程序中遇到
//DataPort 则用P0 替换
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;//                 位锁存
unsigned char code dofly_DuanMa[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};// 显示段码值0~9
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]; //存储显示值的全局变量
void Delay(unsigned int t); //函数声明
void Display(unsigned char FirstBit,unsigned char Num);
long int Count=0;
unsigned long int Count1=0;
unsigned long int Count2=0;
int i=0;
/*------------------------------------------------
                    计数器初始化子程序
------------------------------------------------*/
void Init_timer0(void)
{
  TMOD=0x55;  //计数器0,方式1,16位计数器
  TH0=TL0=256-1;
  ET0=1;   
  EA=1;
  IP=0x02; //计数器0位最高优先级
  IT0=1;
  TR0=1;
}
void Init_Timer1(void)
{
  TMOD=0x55;  //计数器1,方式1,16位计数器
  TH1=TL1=256-1;
  ET1=1;   
  EA=1;
  IT1=1;
  TR1=1;
}
void Init_Timer2(void)
{
  T2CON = 0x30; //计数器2,T2用做发送接收时钟,作为串口波特率发生器
  TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC;
  RCAP2H = 0xFF;
  RCAP2L = 0xDC;
  SCON = 0x50; //串口方式1,1个起始位,1个停止位,8位数据
  TR2 = 1;  //启动T2
}
/*------------------------------------------------
                    主函数
------------------------------------------------*/
main()
{
     
     Init_Timer0();
     Init_Timer1();
     Init_Timer2();
  while(1)
      {
       Count=(Count1-Count2);
       if(Count<0)
    {
           Count=~Count;
      Count=Count+1;
          TempData[0]=0x40;
     TempData[1]=dofly_DuanMa[Count/10000];
        TempData[2]=dofly_DuanMa[(Count%10000)/1000];
        TempData[3]=dofly_DuanMa[(Count%10000%1000)/100];
        TempData[4]=dofly_DuanMa[(Count%10000%1000%100)/10];
        TempData[5]=dofly_DuanMa[(Count%10000%1000%100)%10];
     Display(0,6);
    }
        else
   {
        TempData[0]=dofly_DuanMa[Count/100000];//分解显示信息,如要显示68,则68/10=6  68%10=8  
        TempData[1]=dofly_DuanMa[(Count%100000)/10000];
        TempData[2]=dofly_DuanMa[(Count%100000%10000)/1000];
        TempData[3]=dofly_DuanMa[(Count%100000%10000%1000)/100];
        TempData[4]=dofly_DuanMa[(Count%100000%10000%1000%100)/10];
        TempData[5]=dofly_DuanMa[(Count%100000%10000%1000%100)%10];
     Display(0,6);
   }
       ES=1;   //打开串口中断
     TF2=1;
   }
}
/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
/*-------------------------------------------------------------------
   显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
      unsigned char i;
   
   for(i=0;i<Num;i++)
    {
    DataPort=0;   //清空数据,防止有交替重影
       LATCH1=1;     //段锁存
       LATCH1=0;
       DataPort=dofly_WeiMa[i+FirstBit]; //取位码
       LATCH2=1;     //位锁存
       LATCH2=0;
       DataPort=TempData[i]; //取显示数据,段码
       LATCH1=1;     //段锁存
       LATCH1=0;
       Delay(100); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
       }
}
/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
TH0=TL0=256-1;
Count1=(Count1+1);   //计数器T0口每遇到一个脉冲中断一次,Count1计数值加1
}
void Timer1_isr(void) interrupt 3 using 1
{
TH1=TL1=256-1;  
Count2=(Count2+1);   //计数器T1口每遇到一个脉冲中断一次,Count2计数值加1
}
/*------------------------------------------------
                     串口中断程序
------------------------------------------------*/
void receive() interrupt 5 //串口中断
{
   TF2=0;
   ES=0;
   SBUF=TempData[i];   //发送到pc机
   while(!TI) ;
   TI=0;
   i++;
   if(i>5)
    {
    i=0;
    }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
武力戡乱
1楼-- · 2019-07-19 03:07
wangchaojie1993 发表于 2016-4-18 15:23
那应该换多少呢?

我也不老计算,一般哈,用11.0592Mhz的,自动从装载0xFD
tangsic
2楼-- · 2019-07-19 06:52
我也不老计算,一般哈,用11.0592Mhz的,自动从装载0xFD
tangsic
3楼-- · 2019-07-19 09:06
 精彩回答 2  元偷偷看……
linsquirrel
4楼-- · 2019-07-19 11:43
武力戡乱 发表于 2015-6-18 09:31
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC
这个波特率算的有点问题

为什么我按这个设置可以正常通讯,求指导
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
TL2 = 0xDC
武力戡乱
5楼-- · 2019-07-19 13:32
linsquirrel 发表于 2017-2-23 23:46
为什么我按这个设置可以正常通讯,求指导
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
TL2 = 0xDC

有计算公式,我建议你查表或者记住

51-单片机波特率计算.doc 下载积分: 积分 -1 分

78 KB, 下载次数: 22, 下载积分: 积分 -1 分

tranhunga
6楼-- · 2019-07-19 17:54
亲,既然问题解决了,就应该把我设置为最佳答案!嗯这样我就有积分奖励

一周热门 更多>