proteus论坛|仿真论坛
直播中

9年用户 124经验值
擅长:测量仪表 EMC/EMI设计 控制/MCU EDA/IC设计 MEMS/传感技术 MEMS/传感技术 测量仪表
私信 关注
[问答]

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

各位大神,我编了一个C代码,计数外来脉冲的数量,然后把计数值通过串口传送给pc机实时显示,用计数器2来用作波特率发生器,但编写的程序有问题,串口调试助手显示乱码,请教大神指导,谢谢!
/*-----------------------------------------------
  名称:串口通信
  
  内容:连接好串口或者u***转串口至电脑,下载该程序,打开电源
        打开串口调试程序,将波特率设置为9600,无奇偶校验
        晶振11.0592MHz,发送和接收使用的格式相同,如都使用
        字符型格式,设置正确后接受框可以看到实时传送的计数值
------------------------------------------------*/
#include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义                        
#define DataPort P0 //定义数据端口 程序中遇到
//DataPort 则用P0 替换
***it LATCH1=P2^2;//定义锁存使能端口 段锁存
***it 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     {
    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)

武力戡乱

2015-6-17 19:36:15
引用: handsomezb 发表于 2015-6-18 15:44
ok!谢谢了,已解决

亲,既然问题解决了,就应该把我设置为最佳答案!嗯这样我就有积分奖励!
举报

武力戡乱

2015-6-18 09:31:57
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC
这个波特率算的有点问题
举报

2015-6-18 15:44:21
引用: 武力戡乱 发表于 2015-6-18 09:31
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC
这个波特率算的有点问题

ok!谢谢了,已解决
举报

武力戡乱

2015-6-18 19:11:14
引用: handsomezb 发表于 2015-6-18 15:44
ok!谢谢了,已解决

举报

wangchaojie1993

2016-4-18 15:23:42
引用: handsomezb 发表于 2015-6-18 15:44
ok!谢谢了,已解决

求指导,后来初值换了多少就可以了?
举报

wangchaojie1993

2016-4-18 15:23:56
引用: 武力戡乱 发表于 2015-6-18 09:31
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC
这个波特率算的有点问题

那应该换多少呢?
举报

武力戡乱

2016-4-18 21:18:51
引用: wangchaojie1993 发表于 2016-4-18 15:23
那应该换多少呢?

我也不老计算,一般哈,用11.0592Mhz的,自动从装载0xFD
举报

唐哲

2016-7-31 19:47:51
我也不老计算,一般哈,用11.0592Mhz的,自动从装载0xFD
举报

唐哲

2016-7-31 19:50:18
谢谢分享!谢谢分享!
举报

linsquirrel

2017-2-23 23:46:36
引用: 武力戡乱 发表于 2015-6-18 09:31
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
  TL2 = 0xDC
这个波特率算的有点问题

为什么我按这个设置可以正常通讯,求指导
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
TL2 = 0xDC
举报

武力戡乱

2017-3-2 10:10:23
引用: linsquirrel 发表于 2017-2-23 23:46
为什么我按这个设置可以正常通讯,求指导
TH2 = 0xFF;  //9600波特率,11.0592Mhz晶振
TL2 = 0xDC

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

tranhunga

2017-5-7 21:16:00
亲,既然问题解决了,就应该把我设置为最佳答案!嗯这样我就有积分奖励
举报

真的拉闸了哦

2018-1-4 23:43:39
举报

更多回帖

发帖
×
20
完善资料,
赚取积分