51驅動1602液晶顯示器的程序


//1602.h
#include <reg52.h>

//數據類型定義
typedef unsigned char uchar;
typedef unsigned int uint;

//1602指令定義
//屏幕初始化
#define SCREEN_INIT 0x38 //屏幕設置:16*2行,5*7點陣,8位數據接口
//光標及屏幕顯示設置
#define SHOW_SCREEN 0x0C //屏幕顯示
#define HIDE_SCREEN 0x08 //屏幕不顯示
#define SHOW_CURSOR 0x02 //顯示光標
#define FLASH_CURSOR    0x01 //光標閃爍
//地址指針及滾動設置
#define DPTR_INC    0x06 //讀/寫一個字節地址指針+1,光標+1
#define DPTR_DEC    0x04 //讀/寫一個字節地址指針-1,光標-1
#define SCREEN_SCR  0x01 //寫一個字符,整屏左移/右移
//ADDR設置
#define ADDR_LINE1  0x80 //第一行
#define ADDR_LINE2  0xC0 //第二行
#define LINE1_END   0x10
#define LINE2_END   0x50
//忙碌狀態
#define BUSY        0x80
//清屏
#define CLR_SCR     0x01 //清屏
//DPTR清零
#define CLR_DPTR    0x02 //數據指針清零
//1602.c
#include <reg52.h>
#include <intrins.h>

#include "1602.h"

//女孩不哭
//2012-10-25
//ts=sts=sw=4

//以下是端口定義,自行修改
sbit RS = P0^0; //數據/指令選擇
sbit RW = P0^1; //讀/寫控制
sbit E = P0^2;  //使能
#define DATA P2 //數據端口 P[0~7] -> DATA[0~7] 

/*
    函數:微秒延時
    參數:
        us[uchar]:微秒
    返回:(無)
*/
void delay_us(uchar us)
{
    for(; us>0; us--)
        _nop_();
}

/*
    函數:10毫秒延時
    參數:
        ms10[uint]:10毫秒
    返回:(無)
*/
void delay_10ms(uint ms10)
{
    uchar x,y,z;
    while(ms10--){
        for(x=5; x>0; x--);
        for(y=4; y>0; y--);
        for(z=248; z>0; z--);
    }
}
/*
    函數:讀取1602狀態
    參數:(無)
    返回:(無)
    說明:最高位為忙碌狀態位,1代表忙碌
*/
uchar read_state(void)
{
    DATA = 0xff;
    RW = 1;
    RS = 0;
    E = 1;
    return DATA;
}

/*
    函數:執行一條命令
    參數:
        cmd[uchar]:命令
    返回:(無)
*/
void do_cmd(uchar cmd)
{
    while(read_state()&BUSY)
        _nop_();
    RS = 0;
    RW = 0;
    DATA = cmd;    
    E = 1;
    delay_us(50);
    E = 0;
    delay_us(50);
}

/*
    函數:1602初始化
    參數:(無)
    返回:(無)
*/
void init_lcd(void)
{
    do_cmd(CLR_SCR);//清屏
    do_cmd(SCREEN_INIT);//顯示模式設置
    do_cmd(SHOW_SCREEN|SHOW_CURSOR/*|FLASH_CURSOR*/);
    do_cmd(DPTR_INC);
}

/*
    函數:寫一個字節到顯存
    參數:
        ch[uchar]:顯示字符ASCII碼
    返回:(無)
*/
void write(uchar ch)
{
    uchar addr;
    while(read_state()&BUSY)
        ;
    //換行處理
    addr = read_state()&~BUSY;
    if(addr == LINE1_END)
        do_cmd(ADDR_LINE2);
    else if(addr == LINE2_END)
        do_cmd(ADDR_LINE1);
    RW = 0;
    RS = 1;
    DATA = ch;
    E = 1;
    delay_us(50);
    E = 0;
    delay_us(50);
}

void write_str(uchar line, uchar pos, uchar* str)
{
    uchar addr;
    uchar* ptr;
    if(line!=1 && line!=2)
        return;//只能是第1,2行
    if(pos>16)
        return;//只能是第 1~16 個字符
    //pos=0表示從當前位置開始寫,忽略行
    if(pos){
        addr = (line==1?ADDR_LINE1:ADDR_LINE2)+pos-1;
        do_cmd(addr);
    }
    for(ptr=str; *ptr; ptr++){
        write(*ptr);
        delay_10ms(80);
    }
}

#if 0
void main(void)
{   
    uchar str[16] = {0};
    uchar x;
    delay_10ms(10);
    init_lcd();
    write_str(1,1,"012345671");
    delay_10ms(200);
    write_str(2,1,"AbCdEfGhIjK");
    delay_10ms(200);
    write_str(1,1,"Nv Hai Bu Ku!");
    delay_10ms(200);
    do_cmd(CLR_SCR);
    do_cmd(SHOW_SCREEN|FLASH_CURSOR);
    write_str(1,1,"this is a very very very long string!");
    for(x=0; x<4; x++){
        do_cmd(HIDE_SCREEN);
        delay_10ms(300);
        do_cmd(SHOW_SCREEN);
        delay_10ms(300);
    }
    do_cmd(SHOW_SCREEN);
    delay_10ms(200);
    do_cmd(CLR_SCR);
    write_str(1,1,"Screen will now Scroll....");
    delay_10ms(300);
    do_cmd(DPTR_INC|SCREEN_SCR);
    write_str(1,0,"Screen Scrolling");
    do_cmd(DPTR_DEC|SCREEN_SCR);
    write_str(1,0,"Screen Scrolling");
    do_cmd(DPTR_INC);
    delay_10ms(200);
    do_cmd(CLR_SCR);
    for(x=0x20; x<0xdf; x++){
        write(x);
        delay_10ms(80);
    }
    delay_10ms(200);
    do_cmd(CLR_SCR);
    write_str(2,1," ... what??");
    for(;;){
    }
}
#endif

女孩不哭(QQ:191035066) @ 2012-11-09 20:02:49 @ http://www.cnblogs.com/nbsofer


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM