5257|5

1

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

51单片机串口通讯,在lcd上显示 [复制链接]

我用51单片机及433m模块做串口通讯,然后在lcd上显示,现在从电脑1发来的数据在lcd上不显示只闪烁,但是在单片机内直接写入的字符可以显示,求助为什么?程序如下:
#include
#define Lcd1602_DB P0
typedef unsigned char uchar;
typedef unsigned int uint;


unsigned char str[10];
unsigned char Temp;          //定义临时变量
unsigned char i = 0;

sbit Lcd1602_RS = P2^6;
sbit Lcd1602_RW = P2^5;
sbit Lcd1602_E = P2^7;

       
sbit MD0=P1^6;
sbit MD1=P1^7;
sbit TX=P3^1;
sbit RX=P3^0;



void Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}


void  uart ()                 //串口初始化
{
        //引脚配置
        MD0 = 0;
        MD1 = 0;
        TX = 0;                                        //TX配置为输出
        RX = 1;                                        //RX配置为输入
       
               
        //串口配置
        SCON = 0x50;                        //8位波特率可变
        TMOD = 0x20;                        //8位自动重装
        PCON = 0x00;                        //波特率不倍增
        TH1 = 0xF3;                                //波特率默认配置为2400
        TL1 = 0xF3;
        ES=1;
        TI = 1;                                        //清发送标志                                       
        TR1 = 1;                                //使能定时器

}


char * uart_rec_string(unsigned char *str)
{

    unsigned char i;

    for(i = 0; i < 4; i++)
    {
        str[i] = SBUF;
    }

    str[i] = '\0';

    return str;
}  

void LcdWaitReady()
{
        uchar sta;
        Lcd1602_DB = 0xff;
        Lcd1602_RS = 0;
        Lcd1602_RW = 1;
        do
                {
                Lcd1602_E = 1;
                sta = Lcd1602_DB;
                Lcd1602_E = 0;
        }
                while(sta & 0x80);
}
/*向Lcd602液晶写入一字节命令*/
void LcdWriteCmd(uchar cmd)
{
        LcdWaitReady();
        Lcd1602_RS = 0;
        Lcd1602_RW = 0;
        Lcd1602_DB = cmd;
        Lcd1602_E = 1;
        Lcd1602_E = 0;
}
/*向Lcd602液晶写入一字节数据*/
void LcdWriteDat(uchar dat)
{
        LcdWaitReady();
        Lcd1602_RS = 1;
        Lcd1602_RW = 0;
        Lcd1602_DB = dat;
        Lcd1602_E = 1;
        Lcd1602_E = 0;


}
/*设置显示RAM起始地址,亦即光标位置*/
void LcdSetCursor(uchar x,uchar y)
{
        uchar addr;
        if(y == 0)
                addr = 0x00 + x;
        else
                addr = 0x40 + x;
        LcdWriteCmd(addr | 0x80);
}
/*在液晶上显示字符串*/
void LcdShowStr(uchar x,uchar y,uchar *str)
{
        LcdSetCursor(x,y);//设置起始地址
        while(*str != '\0')
        {
                LcdWriteDat(*str++);
        }
}
/*初始化液晶*/
void InitLcd1602()
{
        LcdWriteCmd(0x38);
        LcdWriteCmd(0x0c);
        LcdWriteCmd(0x06);
        LcdWriteCmd(0x01);//清屏
               
}


void main()
{
        InitLcd1602();
        Delay1ms(100);
        LcdShowStr(0,0,"current distance");
        LcdShowStr(4,1,"mm");
                uart ();
while(1)
{}

}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
   if(RI)                        //判断是接收中断产生
     {
      RI=0;                      //标志位清零
      Temp=SBUF;                 //读入缓冲区的值
      P1=Temp;
      if(i < 10)
      {
        str[i] = Temp;
        i++;
      }
      if(i == 9)
      {
         str[i] = '\0';
                 LcdSetCursor(0,1);
         LcdWriteDat(str[i]);
                 Delay1ms(2000);
      }                  
     }

}


此帖出自51单片机论坛

最新回复

楼主应该是一个新手,这个程序应该是练习的程序。 简单说几点: 1、进入串口中断后,不用再判断是否有中断,这样有些多余,但是记得要清除中断标志。(对于不同单片机,中断标志是手动清除还是自动清除,有不同处理) 2、你中断里面,把接收到的数送到P1,这是什么目的,是P1口接的有LED还是什么? 3、中断里面的那个循环,目的何在,如果是希望每进一次中断i的值加1,那这个目的永远不会实现,如果是每收到一次数据,都要循环一次,那我没看明白目的是什么? 4、所有的中断函数里面,尽量不要出现延时,尤其是ms以上的延时。可以在终端里面做一标志,然后在主循环中判断标志,执行相应的操作。因为中断的目的就是为了能够快速响应,你加了长时间的延时,那第一次中断响应后,如果很快再来一个中断,由于你还在这个延时里面没出来,这个时候就会响应不了后面的延时  详情 回复 发表于 2018-12-9 15:06
点赞 关注(1)
 

回复
举报

3404

帖子

6

TA的资源

裸片初长成(初级)

沙发
 
中断函数里面不要延时。在主函数的while(1)里面循环加延时做显示,中断函数里只处理字符串就行了。
为了显示的及时性,可以在中断里做一个标志,在主函数的循环里面见到这个标志变化了就马上刷新LCD,不变化不刷新或者定时刷新都行。
此帖出自51单片机论坛

赞赏

1

查看全部赞赏

 
 
 

回复

4008

帖子

0

TA的资源

版主

板凳
 
Delay1ms(2000);这个太奇葩了
此帖出自51单片机论坛
 
 
 

回复

1368

帖子

6

TA的资源

版主

4
 
串口中断中搞延时就比较变态,搞这样的死循环的延时更是变态
此帖出自51单片机论坛
 
个人签名专注智能产品的研究与开发,专注于电子电路的生产与制造……QQ:2912615383,电子爱好者群: void
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

5
 
建议串口中断里只管接受数据,收到结束符后,回到主程序中再来调用显示。
你这段程序明显是中断接收数据出了问题,收数据时,应该有一个固定的数据头,收到这个字节,代表以下的数据是有效数据,还应有个结束字符,收到这个结束字符,代表这个数据串结束,这时可设置一个数据有效标志,主循环中看到这个标志,就可调用显示子程序。
此帖出自51单片机论坛

赞赏

1

查看全部赞赏

 
 
 

回复

6366

帖子

4914

TA的资源

版主

6
 
楼主应该是一个新手,这个程序应该是练习的程序。
简单说几点:
1、进入串口中断后,不用再判断是否有中断,这样有些多余,但是记得要清除中断标志。(对于不同单片机,中断标志是手动清除还是自动清除,有不同处理)
2、你中断里面,把接收到的数送到P1,这是什么目的,是P1口接的有LED还是什么?
3、中断里面的那个循环,目的何在,如果是希望每进一次中断i的值加1,那这个目的永远不会实现,如果是每收到一次数据,都要循环一次,那我没看明白目的是什么?
4、所有的中断函数里面,尽量不要出现延时,尤其是ms以上的延时。可以在终端里面做一标志,然后在主循环中判断标志,执行相应的操作。因为中断的目的就是为了能够快速响应,你加了长时间的延时,那第一次中断响应后,如果很快再来一个中断,由于你还在这个延时里面没出来,这个时候就会响应不了后面的延时
此帖出自51单片机论坛
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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