zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    115. 不同的子序列
    114. 二叉树展开为链表
    基于Docker结合Canal实现MySQL实时增量数据传输
    Docker-Compose
    Docker容器的创建、启动、和停止
    ES集群
    ES
    Docker配置JDK1.8镜像
    Docker及Docker-Compose的使用
    docker安装jdk
  • 原文地址:https://www.cnblogs.com/memset/p/2763201.html
Copyright © 2011-2022 走看看