【51单片机零基础-chapter6:LCD1602调试工具】
实验0-用显示屏LCD验证自己的猜想
如同c++的cout,前端的console.log()
#include <REGX52.H>
#include <INTRINS.H>
#include "LCD1602.h"
int var=0;
void main()
{
LCD_Init();
LCD_ShowNum(1,1,var+211,5);
while(1){;}
}
实验1-编写LCD1602液晶显示屏驱动函数
LCD1602.c
#include <REGX52.H>
#include <INTRINS.H>
#include "LCD1602.h"
sbit LCD_RS=P2^6; //LCD1602 RS 数据/指令选择
sbit LCD_RW=P2^5; //LCD1602 RW 读/写选择
sbit LCD_EN=P2^7; //LCD1602 EN 使能
#define LCD_DataPort P0 //LCD1602 D0~D7 数据端口
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay() //@11.0592MHz 1ms
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned Command)
{
LCD_RS = 0; //LCD1602指令
LCD_RW = 0; //LCD1602写
LCD_DataPort = Command; //写指令
LCD_EN = 1; //LCD1602 EN使能为高
LCD_Delay(); //delay 1ms,防止时序太快LCD1602来不及执行
LCD_EN = 0; //LCD1602 EN使能为低
LCD_Delay(); //delay 1ms
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned Data)
{
LCD_RS = 1; //LCD1602数据
LCD_RW = 0; //LCD1602写
LCD_DataPort = Data; //写数据
LCD_EN = 1; //LCD1602 EN使能为高
LCD_Delay(); //delay 1ms,防止时序太快LCD1602来不及执行
LCD_EN = 0; //LCD1602 EN使能为低
LCD_Delay(); //delay 1ms
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init(void)
{
LCD_WriteCommand(0x38); //8位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c); //显示开,光标关,闪烁关
LCD_WriteCommand(0x06); //数据读写操作后,光标自动加1,画面不动
LCD_WriteCommand(0x01); //清屏
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line, unsigned char Column)
{
unsigned char AC_DDRAM = 0;
/* 计算写入到DDRAM(显示区)的光标AC的位置 */
if(Line == 1)
{
AC_DDRAM = 0x00 + (Column - 1);
AC_DDRAM |= 0x80;
}
else if(Line == 2)
{
AC_DDRAM = 0x40 + (Column - 1);
AC_DDRAM |= 0x80;
}
LCD_WriteCommand(AC_DDRAM); //设置光标地址
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line, unsigned char Column, char Char)
{
LCD_SetCursor(Line, Column); //设置光标位置
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowString(unsigned char Line, unsigned char Column, char *String)
{
unsigned char i = 0;
LCD_SetCursor(Line, Column); //设置光标位置
/* 打印字符串 */
i = 0;
while(String[i] != '\0'){
LCD_WriteData(String[i]); //光标AC每次自动加1
i++;
}
}
/**
* @brief 返回值=X的Y次方
*/
signed int LCD_Power(int x, int y)
{
int result = 1;
while(y > 0)
{
result *= x;
y--;
}
return result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length)
{
unsigned char i = 0;
unsigned char Chr;
LCD_SetCursor(Line, Column); //设置光标位置
for(i=Length; i>0; i--)
{
Chr = Num/LCD_Power(10,i-1)%10;
if(Chr >=0 && Chr <= 9){
Chr += 0x30;
}
LCD_WriteData(Chr);
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line, unsigned char Column, int Num, unsigned char Length)
{
unsigned char i = 0;
unsigned char SingleNum;
unsigned char Number1;
LCD_SetCursor(Line, Column); //设置光标位置
if(Num>=0)
{
LCD_WriteData('+');
Number1 = Num;
}
else{
LCD_WriteData('-');
Number1 = -Num; //-32768 转为32768之后可能会溢出
}
for(i=Length; i>0; i--)
{
SingleNum = Number1/LCD_Power(10,i-1)%10;
if(SingleNum >=0 && SingleNum <= 9){
SingleNum += 0x30;
}
LCD_WriteData(SingleNum);
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length)
{
unsigned char i = 0;
unsigned char SingleNum;
LCD_SetCursor(Line, Column); //设置光标位置
for(i=Length; i>0; i--)
{
SingleNum = Num/LCD_Power(16,i-1)%16;
if(SingleNum >=0 && SingleNum <= 9){
SingleNum += 0x30;
}
else if(SingleNum >=10 && SingleNum <= 15)
{
SingleNum = SingleNum - 10 + 'A'; //16进制A,B,C,D,E,F
}
LCD_WriteData(SingleNum);
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinaryNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length)
{
unsigned char i = 0;
unsigned char SingleNum;
LCD_SetCursor(Line, Column); //设置光标位置
for(i=Length; i>0; i--)
{
SingleNum = Num/LCD_Power(2,i-1)%2;
SingleNum += 0x30;
LCD_WriteData(SingleNum);
}
}
LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__
void LCD_Init(void);
void LCD_WriteCommand(unsigned Command)
void LCD_ShowChar(unsigned char Line, unsigned char Column, char Char);
void LCD_ShowString(unsigned char Line, unsigned char Column, char *String);
void LCD_ShowNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line, unsigned char Column, int Num, unsigned char Length);
void LCD_ShowHexNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length);
void LCD_ShowBinaryNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length);
#endif
main.c
#include <REGX52.H>
#include <INTRINS.H>
#include "LCD1602.h"
void main()
{
LCD_Init();
LCD_ShowChar(1, 1, 'Y');//显示一个字符:1行1列
LCD_ShowString(1, 3, "POSTGRADUATE");//显示一个字符串:1行3列开始
LCD_ShowNum(2, 1, 985, 3);//2行1列显示数字985,如果指定两位则不显示高位,为85,如果是四位则高位补零显示,为0985
//LCD_ShowSignedNum(2, 5, -5, 1);//显示有符号数(符号不计入位数)
//LCD_ShowHexNum(2, 8, 0xA8, 2); //显示十六进制
LCD_ShowBinaryNum(2, 5, 0xAA, 8);//显示二进制
while(1){;}
}
比较核心的
实验2-动态显示
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
int var=0;
void main()
{
LCD_Init();
while(1){
var++;
Delay(1000);
LCD_ShowNum(1,1,var,3);
Delay(1000);
}
}
实验3-滚动显示
在Main.c中增加LCD1602移屏指令
#include <REGX52.H>
#include <INTRINS.H>
#include "LCD1602.h"
#include "Delay.h"
void main(){
LCD_Init();
while(1)
{
LCD_ShowString(1, 16, "CONGRATULATIONS!");
LCD_ShowString(2, 16, "WELCOME TO UESTC , WANG XIAO !");
Delay(500);
LCD_WriteCommand(0x18);//调用一次左移一次
//LCD_WriteCommand(0x1c);//调用一次右移一次
Delay(500);
}
}
参考1:LCD显示时期
参考2:笔记
参考3:笔记
参考4:lcd位移
参考5:lcd驱动程序