• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

STM32 LCD1602忙信号检测的问题

石头雷 2014-12-29 浏览量:3909

检测LCD1602忙信号程序如下,实现不了,有没有好的改进方案,或其他好的建议,(我已经用延时替代忙信号检测实现了字符显示)

uint8_t ReadDataPort(void)
{
 uint32_t temp;
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|
                             GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 temp=GPIOA->IDR;
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|
                             GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
 return (uint8_t)temp;
 }
void WaitForEnable(void)
{
 uint8_t val;
 WriteDataPort(0xff);
 LCM_RS_0;LCM_RW_1;delay_us(1);
 LCM_EN_1;delay_us(1);
 val=ReadDataPort();
 while(val&0x80) val=ReadDataPort();
 LCM_EN_0;
 }

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 以前也用MCU写过lcd1602的时序,不过都没有深究,也就是照着1602的时序写下去,没有用到忙信号检测,也不知道怎么用, 1602貌似也能正常工作o(_)o…哈哈(无语)……

    最近温习了一下,居然让我看出点套路来了,呵呵 ……首先让我们看一下busy check的程序

    void busy_check()//忙信号检测

    {

          lcdrs=0;

          lcdrw=1;

          lcden=1;

          _nop_();

          while(P0&0x80)//忙信号检测关键

          {

               lcden=0;

               _nop_();

               lcden=1;

               _nop_();

          }

    现在让我们来分析一下这个忙信号的检测过程:

    1、读状态 RS = L   RW = H  EN = H 然后就可以读它的状态了,我看到很多人写这个读状态的时候都是这样的:

    void busy_check()//忙信号检测

    {

          lcdrs=0;

          lcdrw=1;

          lcden=1;

          _nop_();

          while(P0&0x80);

    }

    2、这样写其实是不对的,为什么呢,现在我们来看一下1602的时序:

    从时序当中可以看出,如果1602为忙状态的话,那么DB71,当E也一直高电平的时候,DB0-DB7的数据就会维持不变,所以读到的DB7都是高电平(忙状态)。现在假设当DB7H是,我们让E再来一个脉冲,这个时候DB0-DB7的数据就有机会发生改变,那么它才有可能发生变化,DB7才有可能变为0,这样检测才是正确的。

    • 发布于 2014-12-29
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:12
  • 额,我用的好像从来不检测忙的。。直接拿来显示
    • 发布于2014-12-29
    • 举报
    • 评论 0
    • 0
    • 0

  • 要用忙显示的,我不知道你用用中断调试了么?是否可以执行,是否是延时影响的。

    时序很重要哦

    建议首先看看LCD是否可以显示,然后再调节其他。

    • 发布于2014-12-29
    • 举报
    • 评论 0
    • 0
    • 0

  • 支持一下,学习
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • #include "lcd16032.h" #include "delay.h" const uint8_t LCD_DAT0[]="白日依山尽黄河入海流"; const uint8_t LCD_DAT1[]="欲穷千里目更上一层楼"; const uint8_t LCD_DAT3[]="好雨知时节当春乃发生"; const uint8_t LCD_DAT4[]="随风潜入夜润物细无声"; //////////1602写指令函数//////// void LCD16032_writeCom(uint8_t com) { // busy(); LCD_RS_LOW; LCD_RW_LOW; LCD_EN_LOW; Delay(1000); LCD_EN_HIGH; Delay(1000); LCD_DATA=0XFF00&(com<<8); Delay(1000); LCD_EN_LOW; } //////////1602写数据函数//////// void LCD16032_writeData(uint8_t wdata) { LCD_RS_HIGH; LCD_RW_LOW; LCD_EN_LOW; Delay(1000); LCD_EN_HIGH; Delay(1000); LCD_DATA=0XFF00&(wdata<<8); Delay(1000); LCD_EN_LOW; } //////////初始化1602写指令函数//////// void LCD16032_init(void) { LCD16032_writeCom(0x30); //0011 1000 Delay(2000); LCD16032_writeCom(0x30); Delay(2000); LCD16032_writeCom(0x0F); Delay(2000); LCD16032_writeCom(0x06); Delay(2000); LCD16032_writeCom(0x01); Delay(2000); } //////////初始化1602写数据函数//////// void LCD16032_initWriteData(void) { uint8_t i; LCD16032_writeCom(0x80); for(i=0;i<20;i++) { LCD16032_writeData(LCD_DAT3[i]); } LCD16032_writeCom(0x90); for(i=0;i<20;i++) { LCD16032_writeData(LCD_DAT4[i]); } } void LCD16032_WriteData(uint8_t xpos,uint8_t ypos,uint8_t Data) { uint8_t address; if(ypos==0) {address = 0x80 + xpos;} else if(ypos==1) {address = 0x90 + xpos;} LCD16032_writeCom(address); LCD16032_writeData(Data); } void LCD16032_WriteString(uint8_t xpos,uint8_t ypos,uint8_t *DisplayString) { uint8_t address; if(ypos==0) {address = 0x80 + xpos;} else if(ypos==1) {address = 0x90 + xpos;} LCD16032_writeCom(address); while(*DisplayString) { LCD16032_writeData(*DisplayString); DisplayString++; } } void LCD16032_WriteString_shift(uint8_t xpos,uint8_t ypos,uint8_t *buf) { uint8_t m1; for(m1=0;m1<10;m1++) { LCD16032_WriteString(m1+xpos,ypos,buf); Delay(0xffffff); LCD16032_writeCom(0x01); Delay(0xffff); } } void LCD_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //PIN8~15 = DB0~7 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOE, &GPIO_InitStructure); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); }
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • #include "lcd16032.h"
    #include "delay.h"

    const uint8_t LCD_DAT0[]="白日依山尽黄河入海流";
    const uint8_t LCD_DAT1[]="欲穷千里目更上一层楼";
    const uint8_t LCD_DAT3[]="好雨知时节当春乃发生";
    const uint8_t LCD_DAT4[]="随风潜入夜润物细无声";




    //////////1602写指令函数////////
    void LCD16032_writeCom(uint8_t com)
    {
    //       busy();
          LCD_RS_LOW;
          LCD_RW_LOW;
       LCD_EN_LOW;
       Delay(1000);
       LCD_EN_HIGH;
       Delay(1000);

          LCD_DATA=0XFF00&(com<<8);

       Delay(1000);

          LCD_EN_LOW;

    }

    //////////1602写数据函数////////

    void LCD16032_writeData(uint8_t wdata)
    {

          LCD_RS_HIGH;
          LCD_RW_LOW;
       LCD_EN_LOW;
       Delay(1000);
       LCD_EN_HIGH;
       Delay(1000);
       LCD_DATA=0XFF00&(wdata<<8);
       Delay(1000);

          LCD_EN_LOW;

    }

    //////////初始化1602写指令函数////////

    void LCD16032_init(void)
    {
          LCD16032_writeCom(0x30);  //0011 1000
          Delay(2000);
          LCD16032_writeCom(0x30);
       Delay(2000);
          LCD16032_writeCom(0x0F);
       Delay(2000);
          LCD16032_writeCom(0x06);
       Delay(2000);
          LCD16032_writeCom(0x01);
       Delay(2000);
    }

    //////////初始化1602写数据函数////////

    void LCD16032_initWriteData(void)
    {
          uint8_t i;
          LCD16032_writeCom(0x80);
          for(i=0;i<20;i++)
          {
              LCD16032_writeData(LCD_DAT3[i]);
          }
    LCD16032_writeCom(0x90);
    for(i=0;i<20;i++)
          {
              LCD16032_writeData(LCD_DAT4[i]);
          }
    }
    void LCD16032_WriteData(uint8_t xpos,uint8_t ypos,uint8_t Data)
    {
          uint8_t address;
       
       if(ypos==0)
    {address = 0x80 + xpos;}
       else if(ypos==1)
    {address = 0x90 + xpos;}

          LCD16032_writeCom(address);
          LCD16032_writeData(Data);

    }
    void LCD16032_WriteString(uint8_t xpos,uint8_t ypos,uint8_t *DisplayString)
    {
          uint8_t address;
       
       if(ypos==0)
    {address = 0x80 + xpos;}
       else if(ypos==1)
    {address = 0x90 + xpos;}

          LCD16032_writeCom(address);
          while(*DisplayString)
          {
                 LCD16032_writeData(*DisplayString);
        DisplayString++;
          }
    }


    void LCD16032_WriteString_shift(uint8_t xpos,uint8_t ypos,uint8_t *buf)
    {
       uint8_t m1;
    for(m1=0;m1<10;m1++)
    {
    LCD16032_WriteString(m1+xpos,ypos,buf);
    Delay(0xffffff);
    LCD16032_writeCom(0x01);
    Delay(0xffff);
     }
    }

    void LCD_GPIO_Config(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);    
    //PIN8~15 = DB0~7
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);


      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);  
    }

    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 上面是我做过的可用的16032的程序 希望能有帮助
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 没有用中断调试过,我用延时替代忙检测,LCD可以显示的;现在我的疑问是在配置GPIO引脚时是输出模式,但是忙检测是要用输入模式的吧,怎么切换这两种模式呢?还是不用切换就能读引脚的电平呢
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 这个程序也没有用忙检测的吧
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 我看到的很少用忙检测的
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 实在不行 参考一下上面的
    • 发布于2014-12-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 查了很多资料,就发现一个是用忙检测的,我就试了试不行。

    看来还是不用忙检测了的好

    • 发布于2014-12-31
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

STM32 LCD1602忙信号检测的问题