注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

始めの一歩

不是世界变得无聊了,而是你变成了无聊的人……

 
 
 

日志

 
 

【C51】源码 5 -- LCD 1602 显示字符  

2012-04-21 20:20:39|  分类: Fateの51单片机の |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

LCD 1602,正式说法叫 LCM 1602(包括了一些外围电路),一般用来显示简单的字符,也可以通过自定义的方式“造字”。

刚学会基本的字符显示,仅仅是字符显示就大量应用了各种指令格式,姑且在这个阶段写个程序,总结一下:

程序功能:在 LCD 正中央显示字符:“Hello World”、“By Fate”

注:LCD 1602 的使用:http://gaebolg.blog.163.com/blog/static/198269068201231665524137/

 

附上源码:(初出茅庐,难免有写的不好的地方,仅作备份之用,欢迎指点,喷子退散……)

/*------------------------------------------------------------------------------------
LCD 1602 显示字符,在正中央显示“Hello World”、“By Fate”
-------------------------------------------------------------------------------------*/

#include <reg52.h>
#include <intrins.h>        // 各种函数,这里使用了 空函数 _nop_()

sbit RS = P2^4;
sbit RW = P2^5;
sbit EN = P2^6;

#define DataPort P0

void Init_LCD(void);         // 初始化 LCD 显示

void LCD_Write_Com(unsigned char c);        // 向 LCD 写指令
void LCD_Write_Data(unsigned char d);        // 向 LCD 写数据

bit LCD_Busy(void);         // LCD 忙检测函数,忙 返回 1,闲 返回 0
void LCD_Clear(void);     // 清屏

/*-------------------------------------------------------------------------------------
LCD 参数设定:DL    0 = 数据总线为 4 位     1 = 数据总线为 8 位
                   N      0 = 显示 1 行                1 = 显示 2 行
                   F      0 = 5x7 点阵/每字符     1 = 5x10 点阵/每字符
--------------------------------------------------------------------------------------*/
void LCD_Set_Argument(unsigned char DL, unsigned char N, unsigned char F);

/*-----------------------------------------------------------------------------------------------------------------------------------
LCD 输入模式设定:ID     0 = 写入新数据后光标左移           1 = 写入新数据后光标右移
                          S      0 = 写入新数据后显示屏不移动    1 = 写入新数据后显示屏整体右移 1 个字
------------------------------------------------------------------------------------------------------------------------------------*/
void LCD_Set_InputMode(unsigned char ID, unsigned char S);

/*-----------------------------------------------------------------------
LCD 显示设定:D     0 = 显示功能关     1 = 显示功能开
                   C     0 = 无光标            1 = 有光标
                   B     0 = 光标不闪烁     1 = 光标闪烁
------------------------------------------------------------------------*/
void LCD_Set_DisplayMode(unsigned char D, unsigned char C, unsigned char B);

/*-----------------------------------------------------------
在第 row 行,第 col 列的位置,显示字符 c
------------------------------------------------------------*/
void LCD_Write_Char(unsigned char row, unsigned char col, unsigned char c);

/*-----------------------------------------------------------
从第 row 行,第 col 列开始,显示字符串 s
------------------------------------------------------------*/
void LCD_Write_String(unsigned char row, unsigned char col, unsigned char *s);

void Delay(unsigned int t);
void Delay_ms(unsigned int t);       // 延迟 t ms

void main (void)
{
    Init_LCD();
    LCD_Write_Char(1, 3, 'H');
    LCD_Write_Char(1, 4, 'e');
    LCD_Write_Char(1, 5, 'l');
    LCD_Write_Char(1, 6, 'l');
    LCD_Write_Char(1, 7, 'o');
    LCD_Write_String(1, 9, "World!");
    LCD_Write_String(2, 5, "By Fate!");
    while (1);
}

void Init_LCD(void)
{
    LCD_Set_Argument(1, 1, 0);             // 设定基础参数:数据总线 8 位、显示 2 行、5x7 点阵/字符
    LCD_Set_DisplayMode(0, 0, 0);       // 设定显示模式:关显示、关光标显示、关光标闪烁
    LCD_Set_InputMode(1, 0);               // 设定输入模式:每输入一个字符,光标右移、屏幕不动
    LCD_Clear();                                      // 清屏
    LCD_Set_DisplayMode(1, 0, 0);       // 开显示
}

void LCD_Write_Com(unsigned char c)
{
    while (LCD_Busy());
    RS = 0;
    RW = 0;
    EN = 1;
    DataPort = c;
    _nop_();           // 小延时,比 Delay() 小得多,目的:使总线上数据变稳定
    EN = 0;             // 写操作是 EN 下降沿驱动
}

void LCD_Write_Data(unsigned char d)
{
    while (LCD_Busy());
    RS = 1;
    RW = 0;
    EN = 1;
    DataPort = d;
    _nop_();
    EN = 0;
}

bit LCD_Busy(void)
{
    DataPort = 0xFF;
    RS = 0;
    RW = 1;
    EN = 0;
    _nop_();
    EN = 1;         // 读操作是 EN = 1 驱动
    return (bit)(DataPort & 0x80);        // 强制转换到 bit 时,除非原数据等于 0,bit = 0,否则 bit = 1
}

void LCD_Clear(void)
{
    LCD_Write_Com(0x01);
    Delay_ms(5);
}

void LCD_Set_Argument(unsigned char DL, unsigned char N, unsigned char F)
{
    DL <<= 4;         // 指令格式决定了要移位,具体看指令格式要求
    N  <<= 3;
    F  <<= 2;
    LCD_Write_Com(0x20 | DL | N | F);
    Delay_ms(5);
}

void LCD_Set_InputMode(unsigned char ID, unsigned char S)
{
    ID <<= 1;
    LCD_Write_Com(0x04 | ID | S);
    Delay_ms(5);
}

void LCD_Set_DisplayMode(unsigned char D, unsigned char C, unsigned char B)
{
    D <<= 2;
    C <<= 1;
    LCD_Write_Com(0x08 | D | C | B);
    Delay_ms(5);
}

void LCD_Write_Char(unsigned char row, unsigned char col, unsigned char c)
{
    if (row == 1) LCD_Write_Com(0x80 + col - 0x01);          // 由指令格式可知,DB7 = 1,因此要加上 80H
    else if (row == 2) LCD_Write_Com(0xC0 + col - 0x01);
    LCD_Write_Data(c);
}

void LCD_Write_String(unsigned char row, unsigned char col, unsigned char *s)
{
    if (row == 1) LCD_Write_Com(0x80 + col - 0x01);
    else if (row == 2) LCD_Write_Com(0xC0 + col - 0x01);
    while (*s) {
        LCD_Write_Data(*s);
        s++;
    }
}

void Delay(unsigned int t)
{
    while (t--);
}

void Delay_ms(unsigned int t)       // 根据测试,可以相当近似的表示 t ms
{
    while (t--) {
        Delay(245);
        Delay(245);
    }
}

  评论这张
 
阅读(193)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018