實驗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每次自動加1i++;}
}/*** @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驅動程序