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条回答
jjzyf
2019-03-25 06:30
建议串口中断里只管接受数据,收到结束符后,回到主程序中再来调用显示。
你这段程序明显是中断接收数据出了问题,收数据时,应该有一个固定的数据头,收到这个字节,代表以下的数据是有效数据,还应有个结束字符,收到这个结束字符,代表这个数据串结束,这时可设置一个数据有效标志,主循环中看到这个标志,就可调用显示子程序。

一周热门 更多>