打印

为何此程序在1602上显示不正常

[复制链接]
3041|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
544852010|  楼主 | 2012-4-25 15:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 544852010 于 2012-4-25 15:40 编辑

显示很暗很暗--全是大黑快--此程序只需改一点点配置(ADCON1和ANSEL处),却可以在877A上面显示正常。

#include <htc.h>
#define uchar unsigned char
#define uint  unsigned int
#define TESTBIT(a,b) ((a)&(1<<(b)))
__CONFIG(WDTDIS & HS & PWRTDIS & BORDIS);//设置配置位

#define  LCD_RS  RA0
#define  LCD_RW  RA1
#define  LCD_EN      RA2

/************************定义显示字符*****************************************/
uchar Wel[]  = {"Welcome To BeiJin"};
uchar tab[]  = {"0123456789"};
/************************声明函数*********************************************/
void Delay_US(uint delay);
void Delay_Ms(uint delay);
void Delay_Sec(uint delay);
uchar Chk_1602_busy(void);
void Write_1602_command(uchar gcmd,uchar gvalue);
void Write_1602_data(uchar gdata);
void INIT_1602(void);
void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata);
void Display_1602(uchar x,uchar y,uchar gdata);
void Clear_Display(void);
void Open_Disp(void);
void Close_Disp(void);
/*******************************************************************************
* 函 数 名: Delay_US(uint8 delay)
* 函数功能: 微秒延时--12us
* 入口参数: delay
* 返    回: 无
*******************************************************************************/
void Delay_US(uint delay)   
{
   for(;delay;)
   {
      delay--;
   }
}
/*******************************************************************************
* 函 数 名: Delay_MS(uint16 delay)
* 函数功能: 毫秒延时--1ms
* 入口参数: delay
* 返    回: 无
*******************************************************************************/
void Delay_Ms(uint delay)  
{
   uint i;
   for(i=0;i<delay;i++)
       Delay_US(83);
}
/*******************************************************************************
* 函 数 名: Delay_Sec(uint16 delay)
* 函数功能: 毫秒延时--1ms
* 入口参数: delay
* 返    回: 无
*******************************************************************************/
void Delay_Sec(uint delay)
{
   uint i,j;
   for(i=0;i<20*delay;i++)
   {
       for(j=0;j<4536;j++);
   }   
}
/*******************************************************************************
* 函 数 名: Read_LCD_Busy(void)
* 函数功能: 读液晶忙通道数据
* 入口参数: 无
* 返    回: 无
*******************************************************************************/
uchar Chk_1602_busy(void)
{
   uint gR_data;
   uint gwait_time=0xff;   //设置忙超时数
   LCD_RS=0;         //表示状态
   LCD_RW=1;         //选择读
   LCD_EN=1;
   TRISC = 0xFF;     //接收口设为输入口
   Delay_US(30);
   gR_data=PORTC;
   while(TESTBIT(gR_data,7))  //表示busy
   {
      --gwait_time;
      if(!gwait_time)
      { LCD_EN=0;TRISC = 0x00; return 0; }
   }
    LCD_EN=0;
    TRISC = 0x0;   //恢复为输出口
    return 1;
}
/******************************************************************************
* 函 数 名: Write_LCD_Comd(uint8 commond)
* 函数功能: 写指令
* 入口参数: commond指令
* 返    回: 无
*******************************************************************************/
void Write_1602_command(uchar gcmd,uchar gvalue)
{
   if(gvalue)             //写命令时大部分情况下是在LCD空闲模式下写
   {
      if(Chk_1602_busy())
      {
         LCD_RS=0;         //选择指令
         LCD_RW=0;         //选择写
         PORTC=gcmd;       //赋指令
         LCD_EN=1;         //使能
         Delay_US(30);
         LCD_EN=0;
      }
   }
   else
   {
      LCD_RS=0;         //选择指令
      LCD_RW=0;         //选择写
      PORTC=gcmd;       //赋指令
      LCD_EN=1;         //使能
      Delay_US(30);
      LCD_EN=0;
   }
}
/******************************************************************************
* 函 数 名: Write_LCD_Data(uint8 Data)
* 函数功能: 写数据
* 入口参数: Data数据
* 返    回: 无
*******************************************************************************/
/*----------- 写数据 -------------*/
void Write_1602_data(uchar gdata)
{
   if(Chk_1602_busy())     //写数据必须是在LCD空闲模式下才能写
   {
      LCD_RS=1;             //选择数据
      LCD_RW=0;             //选择写
      PORTC=gdata;
      LCD_EN=1;             //使能
      Delay_US(30);
      LCD_EN=0;
      Delay_US(10);
   }
}
/******************************************************************************
* 函 数 名: LCD1602_Init(void)
* 函数功能: 初始化1602LCD
* 入口参数: 无
* 返    回: 无
*******************************************************************************/
/*-----------1602初始化函数-------------*/
void INIT_1602(void)
{
   Delay_Ms(15);
   Write_1602_command(0x38,0);  //设置16X2显示,5X7点阵,8位数据传送,不检测忙信号
   Delay_Ms(5);
   Write_1602_command(0x38,0);
   Delay_Ms(5);
   Write_1602_command(0x38,0);  //设置16X2显示,5X7点阵,8位数据传送,不检测忙信号
   Write_1602_command(0x38,1);  //设置16X2显示,5X7点阵,8位数据传送,检测忙信号
   Write_1602_command(0x08,1);  //关闭显示、无光标、检测忙信号
   Write_1602_command(0x01,1);  //清屏、光标归位、AC=0、检测忙信号
   Write_1602_command(0x06,1);  //显示光标右移位置、检测忙信号
   Write_1602_command(0x0c,1);  //显示功能开、无光标
}
/******************************************************************************
* 函 数 名: void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata)
* 函数功能: 显示字符串
* 入口参数: gadd_start-列号,uchar gline-行号,glength-数据长度,pdata-数组元素
* 返    回: 无
*******************************************************************************/
/*-----------显示字符串-------------*/
//                                列号           行号       数据长度     数组元素
void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata)
{
   uchar gaddress;
   uchar *pdat;
   uchar gcount=0;
   if(!gline)                          //第0行
   { gaddress=0x80+gadd_start; }      //地址对应
   else
   { gaddress=0xc0+gadd_start; }      //第一行
   for(;gcount<glength;gcount++)
   {
      Write_1602_command(gaddress,1);        //设定数据地址
      Write_1602_data(*pdata);  //取设定地址里的数据
      gaddress++;
      pdata++;
   }
}
/*-----------指定位置显示字符-------------*/
void Display_1602(uchar x,uchar y,uchar gdata)
{
   uchar gaddress;
   if(y)
   { gaddress=0x80+x; }
   else
   { gaddress=0xc0+x; }
   Write_1602_command(gaddress,1);   //设定数据地址
   Write_1602_data(gdata);
}
/*-----------清屏-------------*/
void Clear_Display(void)
{
  Write_1602_command(0x01,1);
  Delay_Ms(5);
}
void Open_Disp(void)
{
Write_1602_command(0x0c,1);
}
void Close_Disp(void)
{
Write_1602_command(0x08,1);
}

/******************************************************************************
* 函 数 名: main()
* 函数功能: LCD显示字符
* 入口参数: 无
* 返    回: 无
*******************************************************************************/
void main()
{
    ANSEL = 0x00;
    //ADCON1 = 0x87;        //设置PORTA为普通IO口
TRISA0 = 0;
TRISA1 = 0;
TRISA2 = 0;
    TRISA3 = 0;
TRISC = 0x00;   //设置PORTC为输出
Delay_Ms(10);
INIT_1602();
Delay_Ms(100);
while(1)
{
      RA3 = 1;Delay_Ms(1000);RA3 = 0;
      
      Display_1602_string(0,0,16,tab);
      
      RA3 = 0;Delay_Ms(1000);RA3 = 1;
}
}

lcd1602.pdf

255.88 KB

PIC16F91X 数据手册.pdf

3.04 MB

沙发
fffofo| | 2012-4-26 14:01 | 只看该作者
LCD1602有对比度调节,你调调试试

使用特权

评论回复
板凳
544852010|  楼主 | 2012-4-27 14:27 | 只看该作者
回复fff0f0:对比度我反复调试过,也多次怀疑是对比度的问题,但是,经过多次验证,显示不正常的原因不是对比度造成的。
这个程序,可以在877A上面正常显示,你也可以试试,如果你有914,麻烦帮忙实验下看否能显示,谢谢!

使用特权

评论回复
地板
544852010|  楼主 | 2012-4-27 14:40 | 只看该作者
显示很暗很暗--全是大黑快--此程序只需改一点点配置(ADCON1和ANSEL处),却可以在877A上面显示正常。开始我怀疑是开发板问题或者线路焊接问题,但是,经过多次自己在面包板上焊接对应电路,烧写程序均正常,显示依然老问题...也就是说,很有可能还是程序的问题,或者是单片机不支持这样做(驱动1602液晶屏),1602液晶屏完好无任何质量问题,同一液晶屏在其它单片机,如877系列,均显示正常。

使用特权

评论回复
5
兰天白云| | 2012-4-27 16:47 | 只看该作者
可能是IO口配置和电压问题

使用特权

评论回复
6
544852010|  楼主 | 2012-4-28 09:16 | 只看该作者
:lol:lol嘿嘿,搞定了,原来IO口需要这样配置(原先我咨询了Microchip上海技术支持,一女的说不用段式LCD功能,就不用管COMCON0和LCDCON,搞的我.......看来,还是要自己细心才行啊),同志们,不要犯我这样的错误哦,嘿嘿,谢谢各位的指导啊。
/*-----------1602端口初始化-------------*/
void Port_1602_Init(void)
{
    PORTA=0x00;
        CMCON0=0xff;
    ANSEL = 0x00;
    TRISA=0X00;
   
    PORTC=0x00;
    TRISC=0x00;
    LCDCON=0x00;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:LED行业应用技术支持工程师,欢迎多多交流!QQ-544852

35

主题

68

帖子

1

粉丝