完整的LCD1602驱动,可直接使用

2020-02-05 09:09发布

这是本人开发板的光盘附带代码,觉得写得不错,大家品评一下。

点击此处下载 ourdev_716736QW5XQD.rar(文件大小:31K) (原文件名:LCD1602.rar)
点击此处下载 ourdev_716554ZB6HAD.pdf(文件大小:793K) (原文件名:Spark51原理图.pdf)
点击此处下载 ourdev_716560C3448M.pdf(文件大小:324K) (原文件名:LCD1602液晶.pdf)
点击此处下载 ourdev_716561D39WEO.pdf(文件大小:759K) (原文件名:LCD1602接口封装.pdf)


以下是代码,只粘贴出来液晶驱动的C文件,大家喜欢的话,下载附件。
觉得作者考虑的挺严谨,比如检测忙状态,使用了次数统计,不会因为电路出现故障而死循环。

/*********************************************************************
文件名称:lcd1602.c
文件功能:lcd1602液晶驱动
创建时间:
作    者:Spark嵌入式工作室
*********************************************************************/
#include "lcd1602.h"

/*********************************************************************
功能:读取LCD状态
参数:无
返回:0 -- 空闲,可以进行读写操作
      1 -- 忙
*********************************************************************/
u8 lcd1602_read_state(void)
{
    u8 temp = 0;
   
    LCD1602_EN   = 0;
    LCD1602_RS   = 0;
    LCD1602_RW   = 1;
    LCD1602_EN   = 1;
    _nop_();
    _nop_();
   
    //读取状态
    LCD1602_DATA = 0xFF;
    temp = LCD1602_DATA;
   
    //只有最高位表示状态
    if(temp & 0x80)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/*********************************************************************
功能:向lcd写入指令
参数:command -- 指令
返回:无
*********************************************************************/
void lcd1602_write_command(u8 command)
{
    u8 i = 0;
   
    while(1)
    {
        //统计检测次数
        i++;
        
        //空闲退出循环
        if(lcd1602_read_state() == 0)
        {
            break;
        }
        //多次检测仍忙,放弃此次操作
        else if(i > 50)
        {
            return;
        }
    }
   
    //输出指令
    LCD1602_EN   = 0;
    LCD1602_RS   = 0;
    LCD1602_RW   = 0;
    LCD1602_DATA = command;
    _nop_();
    _nop_();
   
    //EN端产生上升沿,再恢复到低
    LCD1602_EN   = 1;
    _nop_();
    _nop_();
    LCD1602_EN   = 0;
}

/*********************************************************************
功能:向lcd写入数据
参数:dat -- 数据
返回:无
*********************************************************************/
void lcd1602_write_data(u8 dat)
{
    u8 i = 0;
   
    while(1)
    {
        //统计检测次数
        i++;
        
        //空闲退出循环
        if(lcd1602_read_state() == 0)
        {
            break;
        }
        //多次检测仍忙,放弃此次操作
        else if(i > 50)
        {
            return;
        }
    }
   
    //输出数据
    LCD1602_EN   = 0;
    LCD1602_RS   = 1;
    LCD1602_RW   = 0;
    LCD1602_DATA = dat;
    _nop_();
    _nop_();
   
    //EN端产生上升沿,再恢复到低
    LCD1602_EN   = 1;
    _nop_();
    _nop_();
    LCD1602_EN   = 0;
}

/*********************************************************************
功能:lcd初始化
参数:无
返回:无
*********************************************************************/
void lcd1602_init(void)
{
    lcd1602_write_command(0x38);   //设置16*2显示,5*7点阵,8位数据接口
    lcd1602_write_command(0x0C);   //开显示,没有光标
    lcd1602_write_command(0x06);   //写入数据,地址和光标增加,不移动
    lcd1602_write_command(0x01);   //显示清屏
}

/*********************************************************************
功能:设定lcd显示位置,即地址
参数:row -- 行坐标 1~2
      col -- 列坐标 1~16
返回:0  --  修改失败
      1  --  修改成功
*********************************************************************/
u8 lcd1602_set_cursor(u8 row, u8 col)
{
    u8 addr = 0;
   
    //判断参数合法性
    if((row < 1) || (row > 2) || (col < 1) || (col > 16))
    {
        //参数有误,直接返回
        return 0;
    }
   
    //把坐标转换成地址
    if(row == 1)
    {
        addr = col - 1;
    }
    else if(row == 2)
    {
        addr = 0x40 + (col - 1);
    }
   
    //写入地址
    lcd1602_write_command(0x80 | addr);
   
    return 1;
}

/*********************************************************************
功能:在特定的坐标写入字符
参数:row -- 行坐标 1~2, 如果是0则不进行坐标改动
      col -- 列坐标 1~16,如果是0则不进行坐标改动
      chr -- 字符ASCII码
返回:无
*********************************************************************/
void lcd1602_write_char(u8 row, u8 col, u8 chr)
{   
    //改动光标位置
    if((row != 0) && (col != 0))
    {
        if(!lcd1602_set_cursor(row, col))
        {
            //光标修改失败,直接返回
            return;
        }
    }
   
    //写入字符
    lcd1602_write_data(chr);

}

/*********************************************************************
功能:在特定的坐标写入字符串,没有换行功能
参数:row -- 行坐标 1~2, 如果是0则不进行坐标改动
      col -- 列坐标 1~16,如果是0则不进行坐标改动
      str -- 字符串地址
返回:无
*********************************************************************/
void lcd1602_write_str(u8 row, u8 col, u8 *str)
{
    u8 count = 0;
   
    //改动光标位置
    if((row != 0) && (col != 0))
    {
        if(!lcd1602_set_cursor(row, col))
        {
            //光标修改失败,直接返回
            return;
        }
    }
   
    //写入字符串
    while(*str != '')
    {
        lcd1602_write_data(*str);
        str++;
        
        //这里用count计数,防止死循环
        count++;
        if(count > 16)
        {
            break;
        }
    }
}

/*********************************************************************
功能:在特定的坐标写入数字,没有换行功能
参数:row  -- 行坐标 1~2, 如果是0则不进行坐标改动
      col  -- 列坐标 1~16,如果是0则不进行坐标改动
      num  -- 要显示的数字,范围0~9999
返回:无
*********************************************************************/
void lcd1602_write_num(u8 row, u8 col, u16 num)
{
    u8 str[5];        //保存num转换成的字符串
    u8 temp = 0, i = 0, count = 0;
    u8 *p;
   
   
    //取得千位,转换成ASCII码存入str
    temp   = num / 1000;
    str[0] = temp + '0';
   
    //取得百位
    num    = num - 1000 * temp;
    temp   = num / 100;
    str[1] = temp + '0';
   
    //取得十位
    num    = num - 100 * temp;
    temp   = num / 10;
    str[2] = temp + '0';
   
    //取得个位
    temp   = num % 10;
    str[3] = temp + '0';
   
    //添加字符串结束标志
    str[4] = '';
   
    //统计高位0的位数
    p = str;
    while(*p != '')
    {
        if(*p++ == '0')
        {
            count++;
        }
        else
        {
            break;
        }
    }
   
    if(count == 0)
    {
        //最高位不为0,不用处理
    }
    else if((count > 0) && (count < 4))
    {
        //根据0的个数,将字符串左移count个
        for(i = 0; i < (4 - count); i++)
        {
            str = str[i + count];
        }
        str = '';
    }
    else if(count == 4)
    {
        //num的值为0
        str[0] = '0';
        str[1] = '';
    }
   
    lcd1602_write_str(row, col, str);
}

/*********************************************************************
                         End  Of  File
*********************************************************************/
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。