1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程
//********寫(xiě)指令函數(shù)************
void LCD_write_command(uchar dat)
{
LCD_DB=dat;
LCD_RS=0;//指令
LCD_RW=0;//寫(xiě)入
LCD_E=1;//允許
LCD_E=0;
delay_n40us(1);//實(shí)踐證明,我的LCD1602上,用for循環(huán)1次就能完成普通寫(xiě)指令。
}
//*******************************
//********寫(xiě)數(shù)據(jù)函數(shù)*************
void LCD_write_data(uchar dat)
{
LCD_DB=dat;
LCD_RS=1;//數(shù)據(jù)
LCD_RW=0;//寫(xiě)入
LCD_E=1;//允許
LCD_E=0;
delay_n40us(1);
}
//********************************
//*******顯示一個(gè)字符函數(shù)*********
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
//********************************
/*******檢查忙函數(shù)*************
void LCD_check_busy()? ? ? //實(shí)踐證明,在我的LCD1602上,檢查忙指令通過(guò)率極低,以
{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //至于不能正常使用LCD。因此我沒(méi)有再用檢查忙函數(shù)。而使
do? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//用了延時(shí)的方法,延時(shí)還是非常好用的。我試了一下,用
{ LCD_E=0;? ? ? ? ? ? ? ? ? ?//for循環(huán)作延時(shí),普通指令只要1次循就可完成。清屏指令
LCD_RS=0;? ? ? ? ? ? ? ? ?//要用200次循環(huán)便能完成。
LCD_RW=1;
LCD_DB=0xff;
LCD_E=1;
}while(LCD_DB^7==1);
}
******************************/
//********延時(shí)函數(shù)***************
void delay_n40us(uint n)
{ uint i;
uchar j;
for(i=n;i>0;i--)
for(j=0;j<2;j++);? ? ? ? ? //在這個(gè)延時(shí)循環(huán)函數(shù)中我只做了2次循環(huán),
}? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//實(shí)踐證明我的LCD1602上普通的指令只需1次循環(huán)就能可靠完成。
//*******************************
//*********主函數(shù)*****************
void main(void)
{
LCD_init();
LCD_disp_char(0,1,’A’);
while(1);
}
//*******************************
具體電路的制作是很簡(jiǎn)單的,就接了兩個(gè)電阻,一個(gè)是10歐姆的背光限流電阻,另一個(gè)是2K的LCD極板電壓調(diào)節(jié)電阻。這兩個(gè)電阻的阻值怎么定呢?背光比較簡(jiǎn)單,它就相當(dāng)于在后面接了幾個(gè)發(fā)光二極管,任何時(shí)候你只要在15、16腳串上個(gè)100歐的電位器接上電源,調(diào)節(jié)電位器,覺(jué)得亮度合適。此時(shí)的阻值便可。LCD液晶極板驅(qū)動(dòng)電壓調(diào)節(jié)電阻的確定就稍微麻煩一點(diǎn)。在各數(shù)據(jù)線,控制線接好關(guān)通上電源的前提下在第3腳(VEE)和地之間接一個(gè)10K的電位器。調(diào)節(jié)電位器。當(dāng)3腳電壓高時(shí)為全亮,電壓為0時(shí)為全暗(液晶全顯示為黑塊)。你用電位器把屏幕從全暗剛好調(diào)到變亮。這時(shí)便可調(diào)試程序。待屏幕能正確顯示后再細(xì)調(diào)電位器,使對(duì)比度合適。這時(shí)的阻值便可確定,然后換成等值的固定電阻焊上便可。
組裝后:
具體電路圖:
接口說(shuō)明:
我們從CGROM表上可以看到,在表的最左邊是一列可以允許用戶自定義的CGRAM,從上往下看著是16個(gè),實(shí)際只有8個(gè)字節(jié)可用。它的字符碼是00000000-00000111這8個(gè)地址,表的下面還有8個(gè)字節(jié),但因?yàn)檫@個(gè)CGRAM的字符碼規(guī)定0-2位為地址,3位無(wú)效,4-7全為零。因此CGRAM的字符碼只有最后三位能用也就是8個(gè)字節(jié)了。等效為0000X111,X為無(wú)效位,最后三位為000-111共8個(gè)。
如果我們要想顯示這8個(gè)用戶自定義的字符,操作方法和顯示CGROM的一樣,先設(shè)置DDRAM位置,再向DDRAM寫(xiě)入字符碼,例如“A”就是41H。現(xiàn)在我們要顯示CGRAM的第一個(gè)自定義字符,就向DDRAM寫(xiě)入00000000B(00H),如果要顯示第8個(gè)就寫(xiě)入00000111(08H),簡(jiǎn)單吧!
現(xiàn)在我們來(lái)看怎么向這八個(gè)自定義字符寫(xiě)入字模。有個(gè)設(shè)置CGRAM地址的指令大家還記得嗎?趕快再找出來(lái)看看。
從這個(gè)指令可以看出指令數(shù)據(jù)的高2位已固定是01,只有后面的6位是地址數(shù)據(jù),而這6位中的高3位就表示這八個(gè)自定義字符,最后的3位就是字模數(shù)據(jù)的八個(gè)地址了。例如第一個(gè)自定義字符的字模地址為01000000-01000111八個(gè)地址。我們向這8個(gè)字節(jié)寫(xiě)入字模數(shù)據(jù),讓它能顯示出“℃”
地址:01000000 數(shù)據(jù):00010000? ?? ? 圖示:○○○■○○○○
01000001 00000110? ?? ?? ?? ?? ?○○○○○■■○
01000010 00001001? ?? ?? ?? ?? ?○○○○■○○■
01000011 00001000? ?? ?? ?? ?? ?○○○○■○○○
01000100 00001000? ?? ?? ?? ?? ?○○○○■○○○
01000101 00001001? ?? ?? ?? ?? ?○○○○■○○■
01000110 00000110? ?? ?? ?? ?? ?○○○○○■■○
01000111 00000000? ?? ?? ?? ?? ?○○○○○○○○
可以通過(guò)手動(dòng)提取的方法。如下圖所示,對(duì)應(yīng)一個(gè)字符顯示區(qū)域。每8個(gè)字節(jié),組成一個(gè)點(diǎn)陣數(shù)組。
“日”的點(diǎn)陣數(shù)組即為 {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}
“車”字取模數(shù)組為:{0x00,0x0f,0x02,0x04,0x07,0x00,0x0f,0x00,
0x10,0x1e,0x00,0x10,0x1c,0x10,0x1e,0x10}
將生成的點(diǎn)陣數(shù)組保存到CGRAM存儲(chǔ)器中,生成自定義字符。1602內(nèi)部CGRAM用于自定義的字符點(diǎn)陣的存儲(chǔ),總共64字節(jié)。由上一步點(diǎn)陣提取可知,每一個(gè)字符由8個(gè)字節(jié)數(shù)據(jù)組成。所以64字節(jié)CGRAM存儲(chǔ)器,能夠存儲(chǔ)8組自定義字符的點(diǎn)陣數(shù)組。按照CGRAM地址劃分為0-7為第一組,8-15為第二組,依次類推56-63為第8組數(shù)據(jù)。把自定義字符的數(shù)組按8個(gè)字節(jié)一組存儲(chǔ)到CGRAM中,程序代碼參考如下。
//功能:將自定義字符的編碼數(shù)組 寫(xiě)入到CGRAM中.
//輸入:自定義字符的編碼數(shù)組
void Write_CGRAM(unsigned char *p)
{
unsigned char i,j,kk;
unsigned char tmp=0x40;??//操作CGRAM的命令碼
kk=0;
for(j=0;j<8;j++)? ?? ???//64 字節(jié)存儲(chǔ)空間,可以生成 8 個(gè)自定義字符點(diǎn)陣
{
for(i=0;i<8;i++)? ? // 8 個(gè)字節(jié)生成 1 個(gè)字符點(diǎn)陣
{
Write_com(tmp+i);? ? //操作CGRAM的命令碼+寫(xiě)入CGRAM地址.
Write_dat(p[kk]);? ? //寫(xiě)入數(shù)據(jù)
kk++;
}
tmp += 8;
}
}
上一步中,自定義字符存儲(chǔ)到CGRAM的任意一組以后,每一個(gè)組(8個(gè)字節(jié))也有一個(gè)顯示編碼。按順序依次為00H-07H 。顯示時(shí),只要調(diào)用每一組的編碼,即可以顯示相應(yīng)的字符。
注:內(nèi)部常用字符顯示時(shí),顯示編碼是從0x20開(kāi)始的。0x00-0x0f是專門(mén)留給自定義字符顯示的。0x00-0x07和0x08-0x0f內(nèi)容是一樣的。例如:調(diào)用0x01 位置和0x09位置,顯示的內(nèi)容是一樣的。
直接按照單個(gè)字符的顯示方式調(diào)用顯示函數(shù),就可以顯示自定義字符了。代碼參考如下:
//在第1行,第7個(gè)位置顯示自定義漢字 “年”
DisplayOneChar(6,0,0);? ? //顯示 "年"??//CGRAM 碼 00
說(shuō)明:此時(shí)“年”的8個(gè)字節(jié)點(diǎn)陣數(shù)組 ,存儲(chǔ)空間為CGRAM的 00-07地址
也就是CGRAM的第1組數(shù)據(jù)存儲(chǔ)區(qū)域,編碼為0。 如果存儲(chǔ)在CGRAM的08-15地址,那么編碼就應(yīng)該是 1了。
很多資料中,都沒(méi)有詳細(xì)介紹過(guò)CGRAM和CGROM的區(qū)別和用法,在1602調(diào)試過(guò)程中經(jīng)常會(huì)被搞混。這里總結(jié)一點(diǎn)小技巧,希望能給需要的人一點(diǎn)幫助。
以下是顯示效果:
單個(gè)和兩個(gè)點(diǎn)陣的漢字顯示:
圖形顯示效果:
下面一段程序讓這8個(gè)自定義字符顯示出一個(gè)心的圖案:
#include unsigned char table1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00};//心圖案
unsigned char table[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃
#define? ? ?CLEARSCREEN? ? ?LCD_write_command(0x01)
/**************定義接口************************/
#define? ? ?LCDIO? ? ? P2
sbit LCD1602_RS=P3^0;
sbit LCD1602_RW=P3^1;
sbit LCD1602_EN=P3^2;
/**************定義函數(shù)************************/
void LCD_write_command(unsigned char command);//寫(xiě)入指令函數(shù)
void LCD_write_dat(unsigned char dat);//寫(xiě)入數(shù)據(jù)函數(shù)
void LCD_set_xy( unsigned char x, unsigned char y );//設(shè)置顯示位置函數(shù)
void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat);//顯示一個(gè)字符函數(shù)
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s);//顯示字符串函數(shù)
void LCD_init(void);//初始化函數(shù)
void delay_nms(unsigned int n);//延時(shí)函數(shù)
/********************************************/
/************初始化函數(shù)****************/
void LCD_init(void)
{
CLEARSCREEN;//clear screen
LCD_write_command(0x38);//set 8 bit data transmission mode
LCD_write_command(0x0c);//open display (enable lcd display)
LCD_write_command(0x80);//set lcd first display address
CLEARSCREEN;//clear screen
}
/****************************************************/
/**************寫(xiě)指令函數(shù)********************************/
void LCD_write_command(unsigned char command)
{
LCDIO=command;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_EN=0;
LCD1602_EN=1;
delay_nms(10);
}
/***************************************************/
/****************寫(xiě)數(shù)據(jù)函數(shù)************************/
void LCD_write_dat(unsigned char dat)
{
LCDIO=dat;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=0;
delay_nms(1);
LCD1602_EN=1;
}
/****************************************************/
/***************設(shè)置顯示位置**************************/
void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 1)
address = 0x80 + x;
else
address =0xc0+ x;
LCD_write_command(address);
}
/***************************************************/
/****************顯示一個(gè)字符**********************/
void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat)
{
LCD_set_xy( x, y );
LCD_write_dat(dat);
}
/**********************************************/
/***************顯示字符串函數(shù)***************/
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s)
{
LCD_set_xy( X, Y );
while (*s)
{
LCD_write_dat(*s);
s ++;
}
}
/***********************************************/
/********** 延時(shí)**********************/
void delay_nms(unsigned int n)
{
unsigned int i=0,j=0;
for (i=n;i>0;i--)
for (j=0;j<10;j++);
}
/**************************************/
/***********主函數(shù)**************/
void main(void)
{
unsigned char i,j,k,tmp;
LCD_init();
delay_nms(100);
tmp=0x40;//設(shè)置CGRAM地址的格式字
k=0;
[1] [2] [3]
總結(jié)
以上是生活随笔為你收集整理的1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 维纳滤波
 - 下一篇: 在matlab中,简单地利用RS485协