微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 正学串口,这个程序不难,但是不知道错哪了,请帮着看一下,谢谢

正学串口,这个程序不难,但是不知道错哪了,请帮着看一下,谢谢

时间:10-02 整理:3721RD 点击:
要求:实现用串口调试助手向串口发送一个字符X,串口将发回“I get X”
我用keil的串口助手发送X ,单片机只发回 I get ,不发回X,是哪里错了呢?
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
//全局变量
uchar flag,a,i;
//定义数组
uchar code table[]="I get";
//函数原型
void init(void);//串口设定初始化函数
void ser();
/*串口中断函数*/
void ser()interrupt 4
{
        RI=0;   //现在单片机是由读数据进入中断(RI=1),要将RI清零,才能在下一次进入中断。
        a=SBUF;   //将外界(电脑)给单片机的数据赋值给a
        flag=1;   //这是方便查询是否已经收到数据的变量          flag=1说明已经收到数据
}
/*串口设置(初始化)函数*/
void init(void)
{
        TMOD=0x20;//16进制一位对应2进制 4位:0010 0000 方式2:设定时器1为8位初值自动重装的 8位 定时器
        TH1=0xfd; //设定波特率  1111 1101   
        TL1=0xfd; //设定波特率
        SCON=0x50;//0101 0000 没有定义的则设为0即可。
        EA=1;//开总中断
        ES=1;//开串口中断               
        TR1=1;//启动定时器1
}
/*接受字符并反馈函数*/
void f(void)
{
        if(flag==1)          //  若已经收到数据
        {
                ES=0;  //关闭串口中断。使单片机在进行对这次电脑发来的数据的处理的过程中,SBUF等的值不改变。
                for(i=0;i<6;i++)        //"I get "   :4个字母 加2个空格 一共6个字符 ,所以要循环6次。
                {
                        SBUF=table[i]; // 把table[]中的字符发回电脑
                        while(!TI);//没发送完时TI=0
                        TI=0;                        //发送完时TI被硬件置为1,必须用软件清零,才能进行下一次发送(SBUF=XXX)
                }
                SBUF=a;
                while(!TI);          
                TI=0;
                ES=1;      
                flag=0;          
        }                  
}
/*主函数*/
void main(void)
{
        init();//对串口进行初始化
        while(1)
        {
                f();
        }
}

i get的定义里最后是不是少了个空格,看程序应该没什么问题,看你的情况象是发送完第一个i get 之后程序跑飞了,这应该是逻辑错误或是C语言隐藏规则的问题

单片机接收到的数据不要放在a里,定义一个变量放接收的数据,发送的时候再从这个变量里取数据

我是定义变量a来接收、发送的,跟你的意思不一样吗?  你的意思是?

刚没看到a的定义,你试试在单片机接收到数据存入a后,马上再把a发给计算机,然后再发完i get 后面,发完a后,再随便发一个数据,看看接收到什么

在发i get之前发  SBUF=a;的话a 和 i get都能发回电脑。但是在发完第一个 i get之后,再在它后面不管是发SBUF=a,还是发i get 都没用了。这是为什么呢?怎么改呢

把ES=0去掉试试,另外把整个操作重复操作2、3次,对比看看结果

额,还是没好。

不知道怎么回事,都是我改成一个字符一个字符地发,发回的就对了。

关于郭天祥版的串口通讯第一个例子
上位机通过串口助手发送一个字符“X”,单片机收到后返回给上位机“I get X ”;程序代码如下:
#include<reg52.h>  
#define uint  unsigned int  
#define uchar unsigned char  
uchar code table[]="I get ";
uchar flag=0,a;  
void init_ser()  
{   
    TMOD=0X20;//定时器1工作在方式2   
    TH1=0XFD;  
    TL1=0XFD;  //波特率9600,51单片机大多用这个  
TR1=1;  //定时器/计数器1启动  
REN=1;//允许串口接收  
SM0=0;  
    SM1=1;   //串行口方式1  
REN=1;//允许串口接收  
EA=1;    //开放总中断  
    ES=1;//开串口 中断  
}  
   
void main()  
{  
    init_ser();
   
    while(1)  
    {  
        if(flag==1)  
        {  
   
             ES=0;  //关闭中断  
          //  flag=0;   //重置  
            for(i=0;i<6;i++)
{
            SBUF=table[i];
                    while(!TI);
                TI=0;
}           
                SBUF=a;
                    while(!TI);
              
              TI=0;       //为下次发送做准备  
                           
            ES=1;
            flag=0;
        }  
    }     
void ser_int() interrupt 4     //中断函数不用声明   
{  
    if(RI==1)  
    {  
        RI=0;  
        a=SBUF;
        flag=1;  
  
  
     }            
   
   }   
上述程序进行实例验证后单片机不能发送字符给上位机!重点在于 串口初始程序现将修改,更改了串口允许接受的位置,如下所示
void init_ser()  
{   
    TMOD=0X20;//定时器1工作在方式2   
    TH1=0XFD;  
    TL1=0XFD;  //波特率9600,51单片机大多用这个  
    TR1=1;  //定时器/计数器1启动  
    EA=1;    //开放总中断  
    SM0=0;  
    SM1=1;   //串行口方式1  
    REN=1;//允许串口接收  
    ES=1;//开串口 中断  
}  

谢谢哈,但是这两个的区别不就是把初始化函数里面几条语句的顺序换了一下吗?为什么执行效果不一样?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top