51单片机串口通讯,在lcd上显示

2019-03-24 16:56发布

我用51单片机及433m模块做串口通讯,然后在lcd上显示,现在从电脑1发来的数据在lcd上不显示只闪烁,但是在单片机内直接写入的字符可以显示,求助为什么?程序如下:
#include <reg52.h>
#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] = '';

    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 != '')
        {
                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] = '';
                 LcdSetCursor(0,1);
         LcdWriteDat(str[i]);
                 Delay1ms(2000);
      }                  
     }

}


此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
tiankai001
2019-03-25 12:29
楼主应该是一个新手,这个程序应该是练习的程序。
简单说几点:
1、进入串口中断后,不用再判断是否有中断,这样有些多余,但是记得要清除中断标志。(对于不同单片机,中断标志是手动清除还是自动清除,有不同处理)
2、你中断里面,把接收到的数送到P1,这是什么目的,是P1口接的有LED还是什么?
3、中断里面的那个循环,目的何在,如果是希望每进一次中断i的值加1,那这个目的永远不会实现,如果是每收到一次数据,都要循环一次,那我没看明白目的是什么?
4、所有的中断函数里面,尽量不要出现延时,尤其是ms以上的延时。可以在终端里面做一标志,然后在主循环中判断标志,执行相应的操作。因为中断的目的就是为了能够快速响应,你加了长时间的延时,那第一次中断响应后,如果很快再来一个中断,由于你还在这个延时里面没出来,这个时候就会响应不了后面的延时

一周热门 更多>