PIC16F877驅動KS0066U液晶程序
現(xiàn)在來總結總結以前學習單片機的經(jīng)驗和體會:
本文引用地址:http://cafeforensic.com/article/201611/317652.htm1、單片機其實并不難,無非就是那幾個模塊,而真正難的是:一個外圍芯片(比如下面將要驅動的液晶芯片)的工作時序以及準確的延時;然后利用單片機的資源去按照時序編程就得了,所以說了只要把一種單片機的常用模塊搞通了,其它也就一樣簡單,很容易就OK了!
2、單片機編程的框架:模塊的初始化,然后死循環(huán)和中斷,很簡單吧!
3、單片機編程應該注意的問題,一是要按照說明書給出的時序來編程,不要自己想當然了;二是要控制好延時,大部分單片機系統(tǒng)的不穩(wěn)定,有很多是因為延時不到位引起的;而對PIC等單片機來說,還得注意使用時一定得注意單片機的端口的方向(輸入還是輸出)!
本驅動采用4bit,2-line模式電路圖如下:
液晶驅動程序頭文件
#ifndef LCD_H
#define LCD_H
#include ”main.h“
#define uchar unsigned char
//define port function
#defineLCD_DB7 RB5 //;//占用的I/O口定義
#defineLCD_DB6 RB4 //;//該行硬件連接:LCD的DB6與RB4連接,其它類推
#defineLCD_DB5 RB3 //;
#defineLCD_DB4 RB2 //;
#defineLCD_E RA3 //;
#defineLCD_RS RB1 //;
#defineLCD_DB7_DIRTRISB5 //;//對應的方向寄存器定義
#defineLCD_DB6_DIRTRISB4 //;
#defineLCD_DB5_DIRTRISB3 //;
#defineLCD_DB4_DIRTRISB2 //;
#defineLCD_E_DIRTRISA3 //;
#defineLCD_RS_DIRTRISB1 //;
//define commad
#define LCD_FUNC_MODE 0x28 //4bit 2-line 5*8dots
#define LCD_CURSE_MODE0 0x0c //display :on ,curse :off,blink :offf
#define LCD_CURSE_MODE1 0x0e //lcd display curse display
#define LCD_CURSE_MODE2 0x0f //lcd display curse display curse blink
#define LCD_CLR_DISP 0x01 //clear display
#define LCD_BEGIN_ADD 0x80 //set begin address
#define LCD_SHIFT_RIGHT_ALL 0x05 //shift entire display in rightt direction
#define LCD_SHIFT_LEFT_ALL 0x07 //shirft left entire
#define LCD_CURSE_RIGHT 0x14//curse shift right
#define LCD_CURSE_LEFT 0x10 //curse shift left ;
#define LCD_DISP_LEFT 0x18//shift display in left direction
#define LCD_DISP_RIGHT 0x1C//shift display in right direction
#define LCD_SECOND_LINE 0xc0 //change line
void init_lcd() ;
void write_in() ;
void sendcmd(char cddata);
void putclcd(char data) ;
void printlcd(const char *data) ;
void write(char data) ;
void delay(unsigned int count) ;
void lcd_shift(uchar flag,uchar count) ;
void curse_shift(uchar flag,uchar count) ;
void delay_long() ;
#endif
液晶驅動程序
#include "lcd.h"
void init_lcd()
{
//設置端口輸出模式
LCD_DB7_DIR=0;
LCD_DB6_DIR=0;
LCD_DB5_DIR=0;
LCD_DB4_DIR=0;
LCD_E_DIR=0;
LCD_RS_DIR=0;
//清除數(shù)據(jù)線
LCD_DB7=0;
asm("nop");
LCD_DB6=0;
asm("nop");
LCD_DB5=0;
asm("nop");
LCD_DB4=0;
asm("nop");
LCD_RS=0;
asm("nop");
LCD_E=0;
asm("nop");
//將上述命令設置生效
write_in() ;
delay(0xffff) ;
delay(0xffff) ;
//設置功能模式,4bit,2-line.5*8dots
sendcmd(0x28) ;
sendcmd(0x0c) ;//啟動顯示,光標不顯示,光標不閃爍
sendcmd(0x80) ;//設置起始地址
sendcmd(0x01) ;//清屏
}
/*********************8
10us級延時
***********************/
void delay(unsigned int count)
{
while(count)
count-=1;
}
/*************************************
使寫入生效
****************************************/
void write_in()
{
asm("nop") ;
LCD_E=1 ;
asm("nop") ;
LCD_E=0 ;
asm("nop") ;
}
/***********************************
發(fā)送指令
*************************************/
void sendcmd(char cmdata)
{
LCD_RS=0; //設置為送命令模式,與PUTCLCD僅相差此行
write(cmdata); //寫入全字節(jié)
//delay(255);
}
/********************************************
顯示單個字符
********************************************/
void putclcd(char lcdbyte)
{
LCD_RS=1;//設置為發(fā)送數(shù)據(jù)模式
write(lcdbyte);
// delay(255);
}
/**************************************
*顯示字符串
*************************************/
void printlcd(const char *lcdata)
{
while((*lcdata)!=/0)
{
putclcd(*lcdata++);
}
}
/**********************************************
*寫入單個字節(jié)
**********************************************/
void write(char wdata)
{
char temp=wdata;
LCD_DB7=0;
LCD_DB6=0;
LCD_DB5=0;
LCD_DB4=0;
if(temp&0X80)
LCD_DB7=1;
if(temp&0X40)
LCD_DB6=1;
if(temp&0X20)
LCD_DB5=1;
if(temp&0X10)
LCD_DB4=1;
write_in() ;
temp=wdata<<4;
LCD_DB7=0;
LCD_DB6=0;
LCD_DB5=0;
LCD_DB4=0;
if(temp&0X80)
LCD_DB7=1;
if(temp&0X40)
LCD_DB6=1;
if(temp&0X20)
LCD_DB5=1;
if(temp&0X10)
LCD_DB4=1;
write_in() ;
delay(160);
}
/*************************************
*功能:移動顯示:如果把延時改動一下可以改變顯示移動的速凍
*輸入?yún)?shù):flag=0 shift left ;flag=1 shift right ;count :the bit og shift
******************************/
void lcd_shift(uchar flag,uchar count)
{
uchar i ;
if(flag==0)
{
for(i=0;i
//delay(0xfff) ;
delay_long() ;
sendcmd(LCD_DISP_LEFT) ;
}
}
else
{
for(i=0;i
delay_long() ;
sendcmd(LCD_DISP_RIGHT) ;
}
}
}
/*****************************
*功能:光標移動
*輸入?yún)?shù):flag=0 shift left ;flag=1 shift right ;count :the bit og shift
**************************/
void curse_shift(uchar flag,uchar count)
{
uchar i ;
if(flag==0)
{
for(i=0;i
//delay_long() ;
sendcmd(LCD_CURSE_LEFT) ;
}
}
else
{
for(i=0;i
//delay_long() ;
sendcmd(LCD_CURSE_RIGHT) ;
}
}
}
void delay_long()
{
unsigned char i ;
for(i=0;i<2;i++)
delay(0x4ff1) ;
}
評論