3778|13

9

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

51单片机串口通信问题 [复制链接]

大家好,最近我学51串口通信 PC给单片机发一串数据 长度不定 单片机收到后,将原数据再发给PC,但是一直接收不到数据,请大家帮我看看是什么原因,新手求指导。我用定时器1做波特率发生器,定时器0用作超时法判断数据接收完毕,串口中断接收数据,查询法发送数据。下面附程序:
#include
#include
unsigned char idata tab[];
unsigned char j,cnt=0,flag=0;
unsigned char i=0;
void UART_INIT()
{
  SCON=0X50;            //工作方式1,发送使能
  TMOD|=0X21;           //定时器1,工作方式2,定时器0,工作方式1
  AUXR&=0x3F;                    //定时器0,1时钟为Fosc/12,即12T
  AUXR&=0xFE;                    //串口1选择定时器1为波特率发生器
  PCON&=0x7F;                    //波特率不加倍
  TH1=0XFC;             //波特率9600,时钟频率14.7456MHz
  TL1=0XFC;
  TH0=0XFB;             //定时长度1ms
  TL0=0X33;
  TR0=0;                //定时器0不使能
  TR1=1;                //定时器1使能
  PS=1;                 //串口中断设为高优先级
  ES=1;                 //开串口中断
  ET1=0;                        //禁止定时器1中断
  ET0=1;                //开定时器0中断
  EA=1;                 //开总中断
}

void delay_1ms(unsigned int t)
{
  unsigned int a,b;
  for(a=0;a   for(b=0;b<1167;b++);
}

void mian(void)
{
  delay_1ms(100);
  UART_INIT();
  while(1)
    {
          if(flag==1)
            {
          flag=0;
                  ES=0;
                  for(j=0;j                         {
                      SBUF=tab[j];
                      while(!TI);
                      TI=0;
                        }
                  ES=1;
            }
    }
}

void UART_Rountine() interrupt 4
{
  if(RI)
    {
          TR0=0;
          i=0;
          RI=0;
          tab[cnt++]=SBUF;
        }
  TR0=1;
}


void Timer0_Rountine() interrupt 1
{
  TH0=0XFB;             //定时长度1ms
  TL0=0X33;
  TF0=0;
  i++;
  if(i==50)
    {
      i=0;
          TR0=0;
      flag=1;
    }
}

此帖出自51单片机论坛

最新回复

ZNF
看你芯片手册uart部分,然后如果你是买的板子的话,应该有自带的范例程序  详情 回复 发表于 2015-4-23 13:39
点赞 关注
 

回复
举报

2856

帖子

260

TA的资源

五彩晶圆(高级)

沙发
 
印象中51定时器方式2(自动重载8位定时器/计数器)才能用于波特率。你查查书
此帖出自51单片机论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
ltbytyn 发表于 2015-4-21 16:59
印象中51定时器方式2(自动重载8位定时器/计数器)才能用于波特率。你查查书

我是用的定时器1 方式2做波特率发生器
此帖出自51单片机论坛
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

4
 
把ES=0;去掉
此帖出自51单片机论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

5
 

试过了 不行 串口还是接收不到数据,我把程序写了具体点:

#include

#include

unsigned char idata tab[];  //定义数组用于存放数据

unsigned char j,cnt=0,flag=0;

unsigned char i=0;

void UART_INIT()

{

  SCON=0X50;            //工作方式1,发送使能

  TMOD|=0X21;           //定时器1,工作方式2

  AUXR&=0x3F;                    //定时器0,1时钟为Fosc/12,即12T

  AUXR&=0xFE;                    //串口1选择定时器1为波特率发生器

  PCON&=0x7F;                    //波特率不加倍

  TH1=0XFC;             //波特率9600,时钟频率14.7456MHz

  TL1=0XFC;

  TH0=0XFB;             //定时长度1ms

  TL0=0X33;

  TR0=1;                //定时器0不使能,接收到数据在开始计时

  TR1=1;                //定时器1使能

  PS=1;                 //串口中断设为高优先级

  ES=1;                 //开串口中断

  ET1=0;                        //禁止定时器1中断

  ET0=1;                //开定时器0中断

  EA=1;                 //开总中断

}



void delay_1ms(unsigned int t)          //软件延时1ms

{

  unsigned int a,b;

  for(a=0;a
  for(b=0;b<1167;b++);

}



void mian(void)

{

  delay_1ms(100);                  //单片机上电延时

  UART_INIT();                     //初始化

  while(1)

    {

          if(flag==1)                  //检测到接收成功标志

            {

          flag=0;

                  ES=0;                    //关串口中断,查询法置TI也会产生中断,防止干扰

                  for(j=0;j
                        {

                      SBUF=tab[j];

                      while(!TI);

                      TI=0;

                        }

                  ES=1;                    //发送完毕打开串口中断,等待下一帧数据接收

            }

    }

}



void UART_Rountine() interrupt 4

{

  if(RI)

    {

          TR0=0;                      //接收数据过程中定时器不工作

          i=0;                        //计数清0

          RI=0;

          tab[cnt++]=SBUF;            //接收数据

        }

  TR0=1;                          //接收完一个字节数据打开定时器,等待下一字节数据



}





void Timer0_Rountine() interrupt 1

{

  TH0=0XFB;             //定时长度1ms

  TL0=0X33;

  TF0=0;                //清除溢出标志

  i++;                  //没产生一次溢出中断,递增一次

  if(i==50)             //发送一个字节数据大概1ms,等待50ms还没有数据判断接收完毕

    {

      i=0;              //计数清零

          TR0=0;            //关定时器

      flag=1;           //接收成功标志

    }

}

此帖出自51单片机论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

6
 
圣灵枫 发表于 2015-4-22 08:41
试过了 不行 串口还是接收不到数据,我把程序写了具体点:

#include

#include

unsigned char idata tab[];  //定义数组用于存放数据

unsigned char j,cnt=0,flag=0;

unsigned char i=0;

void UART_INIT()

{

  SCON=0X50;            //工作方式1,发送使能

  TMOD|=0X21;           //定时器1,工作方式2

  AUXR&=0x3F;                    //定时器0,1时钟为Fosc/12,即12T

  AUXR&=0xFE;                    //串口1选择定时器1为波特率发生器

  PCON&=0x7F;                    //波特率不加倍

  TH1=0XFC;             //波特率9600,时钟频率14.7456MHz

  TL1=0XFC;

  TH0=0XFB;             //定时长度1ms

  TL0=0X33;

  TR0=1;                //定时器0不使能,接收到数据在开始计时

  TR1=1;                //定时器1使能

  PS=1;                 //串口中断设为高优先级

  ES=1;                 //开串口中断

  ET1=0;                        //禁止定时器1中断

  ET0=1;                //开定时器0中断

  EA=1;                 //开总中断

}



void delay_1ms(unsigned int t)          //软件延时1ms

{

  unsigned int a,b;

  for(a=0;a

请大家帮帮忙 谢谢了
此帖出自51单片机论坛
 
 
 

回复

117

帖子

1

TA的资源

一粒金砂(中级)

7
 
程序里面,数据从单片机发向PC,发送完了,记得把cnt清0了,为下次接收数据做准备。你可以先试试你的串口可不可以工作先,就单单接收一个数据;看看串口可不可以正常的工作,波特率对了没有,一个数据工作正常了,在来看多数据的
此帖出自51单片机论坛
 
个人签名图腾实验室------总有你想要的东西
https://shop112199014.taobao.com/?spm=a1z10.1-c.0.0.ie7t4K
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

8
 
xmb6954757 发表于 2015-4-22 10:54
程序里面,数据从单片机发向PC,发送完了,记得把cnt清0了,为下次接收数据做准备。你可以先试试你的串口可不可以工作先,就单单接收一个数据;看看串口可不可以正常的工作,波特率对了没有,一个数据工作正常了,在来看多数据的

cnt清零也不行 我之前没用中断,接收也用的查询法 在主函数里面死等 调试时发送跟接收都是正常的 多个字节数据也正常 但这样写实际中是不能用的 才换的中断 所以串口应该是正常的 波特率也没问题 换了中断之后就完全没反应 我在数据接收后面加了一个led显示 发现不亮 说明没接收到数据 中断函数不对 但我中断初始化跟调用都是参考的手册 没看出有什么问题啊
此帖出自51单片机论坛
 
 
 

回复

117

帖子

1

TA的资源

一粒金砂(中级)

9
 
那你先去掉超时检测试试看,怎么样
此帖出自51单片机论坛

点评

没用 问题还是中断接收根本接收不到数据  详情 回复 发表于 2015-4-22 14:19
 
个人签名图腾实验室------总有你想要的东西
https://shop112199014.taobao.com/?spm=a1z10.1-c.0.0.ie7t4K
 
 

回复

900

帖子

0

TA的资源

五彩晶圆(初级)

10
 
老弟,你把终端函数放在主函数后边是不是要预先做个声明额??
你定义flag这个变量好像得用“汪愣忒奥”额,英文忘了怎么写了,你去查查吧。
此帖出自51单片机论坛
 
个人签名别打我! 我说。
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

11
 
yangxf1217 发表于 2015-4-22 11:42
老弟,你把终端函数放在主函数后边是不是要预先做个声明额??
你定义flag这个变量好像得用“汪愣忒奥”额,英文忘了怎么写了,你去查查吧。

我记得中断函数是不需要声明的,跟主函数是并行执行的,不过我还是听你的加了声明,然后flag确实定义错了,得用bit定义,但是现在调试程序还是没反应
此帖出自51单片机论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

12
 
xmb6954757 发表于 2015-4-22 11:32
那你先去掉超时检测试试看,怎么样

没用 问题还是中断接收根本接收不到数据
此帖出自51单片机论坛
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(中级)

13
 
大家帮帮忙 不能沉啊
此帖出自51单片机论坛
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

14
 
看你芯片手册uart部分,然后如果你是买的板子的话,应该有自带的范例程序
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表