单片机C语言拉高1位,第二讲 单片机C语言之12864液晶显示
前面一講我們焊接了C51的最小系統。這講里我們將繼續焊接上液晶顯示相關電路,并分別實現用12864顯示一個漢字,字符串,數字,浮點數以及可調節的電子時鐘。
概念
點陣式液晶顯示模塊(LCD)廣泛應用于單片機控制系統,比數碼管、段式液晶能模塊顯示更多、更直觀的信息,如漢字、曲線、圖片等。點陣液晶顯示模塊集成度很高,一般都內置控制芯片、行驅動芯片和列驅動芯片,點陣數量較大的LCD還配置RAM芯片,帶漢字庫的LCD還內嵌漢字庫芯片,有負壓輸出的LCD還設有負壓驅動電路等。單片機讀寫LCD實際上就是對LCD的控制芯片進行讀寫命令和數據。編程驅動LCD時,不需要對LCD的結構和點陣行列驅動原理深入了解,只要理解LCD接口的定義和LCD的控制芯片的讀寫時序和命令就可以了。
12864LCD屬于點陣圖形液晶顯示模塊,不但能顯示字符,還能顯示漢字和圖形,分帶漢字庫和不帶那字庫兩種,價格也有差別。帶漢字庫的12864LCD使用起來非常方便,不需要編寫復雜的漢字顯示程序,只要按時序寫入兩個字節的漢字機內碼,漢字就能顯示出來了,驅動程序簡單許多。本文例程就是基于帶漢字庫的12864液晶顯示模塊。DM12864M 漢字圖形點陣液晶顯示模塊,可顯示漢字及圖形,內置 8192 個中文漢字(16X16 點陣)、128
個字符(8X16 點陣)及 64X256 點陣顯示 RAM(GDRAM)。
12864有如下特點:
1. 128點X 64行=8192點。
2. 12864有兩種工作模式。
(1)文本工作模式
整屏平均分成32個顯示區(每個顯示區是16X16點陣),每個顯示區可顯示一個中文,每個顯示區可顯示兩個英文ASCII字符。下圖為漢字顯示坐標即地址。
(2)繪圖工作模式 ???????? 整屏按水平方向每16個點分為一組,所以整屏共有8192/16=512組,每次可控制任意一組的16個點。圖形顯示坐標:水平方向 X—以字節單位,垂直方向 Y—以位為單位。
3. 12864的硬件接口
總共20個引腳。其中引腳4-14是連接到MCU的。4.5.6引腳有兩種功能,分別對應不同串并驅動模式。當為串行驅動時,4.5.6分別為CS,SID,CLK,且此時8位數據并行線無效;當為并行驅動時,4.5.6分別為RS,RW,E,且此時8位并行數據線有效。而15腳則是用于選擇串并模式的。
漢字顯示實驗
好了現在我們來顯示一個漢字。首先明確思路,初始化液晶屏,切換到文本模式,設置要顯示漢字的地址,寫入顯示漢字。新建工程,分別建立三個文件main.c, 12864.c, 12864.h。
main.c
#include "12864.h"
void main()
{
LCD_Init();
LCD_SetAddText(0x93);
LCD_WriteDat(0XC4);
LCD_WriteDat(0Xe3);
LCD_SetAddText(0x94);
LCD_WriteDat(0XBa);
LCD_WriteDat(0XC3);
while(1)
{
}
}12864.c
#include "12864.h"
sbit LCDRS_CS=P3^5;
sbit LCDWR_SID=P3^6;
sbit LCDE_CLK=P3^7;
/*
數據 0xFA
命令-地址0xF8
*/
void delay(u16 x)
{
while(x--);
}
void LCD_Send8bit(u8 dat) //向LCD發送一個字節
{
u8 i;
for(i=0;i<8;i++)
{
LCDE_CLK=0;
//LCDWR_SID=dat>>7;
LCDWR_SID=dat&(1<<7);
LCDE_CLK=1;
dat<<=1;
}
}
void LCD_EntryText() //LCD進入文本模式
{
LCD_WriteCmd(0x30);
}
void LCD_EntryDraw() //LCD進入繪圖模式
{
}
voidLCD_SetAddText(u8 add)//設置LCD文本模式顯示地址
{
LCDE_CLK=0;
LCDRS_CS=1;
LCD_Send8bit(0Xf8);
LCD_Send8bit(add&0xf0);
LCD_Send8bit(add<<4);
LCDE_CLK=0;
LCDRS_CS=0;
}
void LCD_SetAddDraw(u8 x, u8 y)//設置LCD繪圖模式顯示地址
{
x=y;
}
void LCD_WriteDat(u8 dat)//向LCD寫入顯示數據
{
LCDE_CLK=0;
LCDRS_CS=1;
LCD_Send8bit(0Xfa);
LCD_Send8bit(dat&0xf0);
LCD_Send8bit(dat<<4);
LCDE_CLK=0;
LCDRS_CS=0;
}
void LCD_WriteCmd(u8 cmd) //向LCD發送一條命令
{
LCDE_CLK=0;
LCDRS_CS=1;
LCD_Send8bit(0Xf8);
LCD_Send8bit(cmd&0xf0);
LCD_Send8bit(cmd<<4);
LCDE_CLK=0;
LCDRS_CS=0;
}
void LCD_Init()
{
LCD_EntryText();
delay(50);
LCD_WriteCmd(0x01);//清屏
delay(5000);
LCD_WriteCmd(0x0c); //開顯示
delay(50);
}12864.h
#ifndef _12864_
#define _12864_
#include "reg51.h"
#define u8 unsigned char
#define u16 unsigned int
void delay(u16 x);
void LCD_EntryText();
void LCD_EntryDraw();
void LCD_SetAddText(u8 add);
void LCD_SetAddDraw(u8 x, u8 y);
void LCD_WriteDat(u8 dat);
void LCD_WriteCmd(u8 cmd);
void LCD_Send8bit(u8 dat);
void LCD_Init();
#endif這個程序顯示了兩個漢字,在地址0x93和0x94處裝入了“你好”兩個漢字。我們一步一步來分析整個程序,所有的驅動都放在了12864.c里面。首先程序剛開始定義了三個IO口分別對應4.5.6腳,因為我們這里要采用串行模式。接下來液晶屏是要工作在文本模式還是繪圖模式呢,所以我們又新建了兩個函數LCD_EntryText()和LCD_EntryDraw(),暫時不管繪圖模式,然后查看數據手冊,得知進入繪圖模式需要發送指令0x30給液晶,因此我們需要新建一個發送命令的函數。這樣的話這個函數可以在這里被調用,也可以在其他地方被調用。這個函數為LCD_WriteCmd(u8 cmd),然而命令是怎么被發送的呢?這就得回到串行連接時序圖了。
如圖SID總共發送了三個字節,其中第一個字節的RW位用來表明數據傳送方向,1則為數據從LCD到MCU,0相反。顯然我們這里是寫數據到LCD所以這位為0。RS位則表明數據的類型,1表示數據是顯示數據,0表示數據是控制指令。顯然我們是發送指令因此這位為0。因此第一個字節就是0Xf8。第二個字節發送的是目標數據的高4位,如果發送的命令為cmd,那么取cmd的高4位構成這第二個字節,即為cmd&0xf0。同理第三個字節發的是目標數據低4位,cmd<<4。CS和SCLK的時序就不具體講了。但是LCD_WriteCmd(u8 cmd)函數要完成,前面說的三個字節具體又是怎么發送的呢?因此我們還需要內嵌一個函數來發送一個字節。這樣我們就又新建一個函數LCD_Send8bit(u8 dat)。根據前面的時序圖,要發送一個位,首先當SCLK為低時,拉高CS并保持,準備好要發送的位(這里取要發送的字節dat的最高位,即右移7位),在SCLK由低跳變到高時,發送這位。然后再拉低SCLK,以此循環直到8個位都發完。
切換到文本模式后,我們就要選擇顯示的地址了。怎么選擇地址呢,MCU就需要把一個地址數據發送給LCD,然后LCD就知道接下來要在這個地址上放MCU發來的顯示數據。因此又新建一個函數LCD_SetAddText(u8 add)。前面我們講了怎么發送命令,實際上發送地址也是使用相同的程序(液晶能識別命令和地址),這里就不再贅述了。
再接下來就是發送顯示數據了。因此又新建一個函數?LCD_WriteDat(u8 dat)。顯然還是跟發送命令和地址一個模式,唯一的區別就是第一個字節這時候變成了0xfa。好了講解完畢。
引申:
如果是要發送數字和浮點數,我們可以在12864.c中引入如下函數,然后載主函數作相應調用即可。
void Show_String(u8 add, u8 *str)//lcd顯示字符串
{
LCD_EntryText(); //lcd進入文本模式
LCD_SetAddText(add);
while(*str)
{
LCD_WriteDat(*str++);
}
}
void Show_Number(u8 add, u16 n) //lcd顯示一個數字
{
char s[6];
sprintf(s,"%05d",n);
Show_String(add, s);
}
void Show_Float(u8 add, float n) //lcd顯示一個浮點數
{
char s[6];
sprintf(s,"%03.2f",n);
Show_String(add, s);
}
電子時鐘實驗
相關代碼可查看我的代碼片。
總結
以上是生活随笔為你收集整理的单片机C语言拉高1位,第二讲 单片机C语言之12864液晶显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2011年c语言二级计算机考试,2011
- 下一篇: c语言 线程a每隔10秒执行一次,线程b