×
单片机 > 单片机程序设计 > 详情

51单片机驱动1602程序

发布时间:2020-06-08 发布时间:
|
sbit LCD_RS=P3^4;         // 定义IO口,具体1602的读控制线
sbit LCD_RW=P3^3;         // 定义IO口,具体1602的写控制线
sbit LCD_EN=P2^0;         // 定义IO口,具体1602的使能控制线
sbit Light=P3^7;             // 定义IO口,具体1602的背光控制线(0:开通,1关闭)
sbit D0 = P1^0;           // 定义IO口,P1.0数据口1602LCD的D0口
sbit D1 = P1^1;           // 定义IO口,P1.1数据口1602LCD的D1口
sbit D2 = P1^2;           // 定义IO口,P1.2数据口1602LCD的D2口
sbit D3 = P1^3;           // 定义IO口,P1.3数据口1602LCD的D3口
sbit D4 = P1^4;           // 定义IO口,P1.4数据口1602LCD的D4口
sbit D5 = P1^5;           // 定义IO口,P1.5数据口1602LCD的D5口
sbit D6 = P1^6;           // 定义IO口,P1.6数据口1602LCD的D6口
sbit D7 = P2^1;           // 定义IO口,P2.1数据口1602LCD的D7口    

sbit B_0=B^0;             // 定义变量B的位,方便位操作
sbit B_1=B^1;
sbit B_2=B^2;
sbit B_3=B^3;
sbit B_4=B^4;
sbit B_5=B^5;
sbit B_6=B^6;
sbit B_7=B^7;
 void main(void)
{    
    P1M0 = 0x00;
    P1M1 = 0x00;        // 配置P1口为准双向口
    P2M0 = 0x00;
    P2M1 = 0x00;        // 配置P2口为准双向口      
    P3M0 = 0x00;
    P3M1 = 0x80;        // 配置P3.7口为强推挽输出(控制背光),其它IO口默认为准双向口(详细配置见STC12C56XXAD数据手册)      
    Light = 0;             // 开1602LCD的背光

    lcd_init();            // LCD 初始化
    lcd_write_char(0,0,'A');       //在坐标(0,0)处写入A
       lcd_write_char(1,0,'B');       //在坐标(1,0)处写入B
       lcd_write_char(2,0,'C');       //在坐标(2,0)处写入C
       lcd_write_char(3,0,'D');       //在坐标(3,0)处写入D
       lcd_write_char(4,0,'E');       //在坐标(4,0)处写入E
      lcd_write_char(5,0,'F');       //在坐标(5,0)处写入F
       lcd_write_char(6,0,'G');       //在坐标(6,0)处写入G
       lcd_write_char(7,0,'H');       //在坐标(7,0)处写入H
       lcd_write_char(8,0,'I');       //在坐标(8,0)处写入I
       lcd_write_char(9,0,'J');       //在坐标(9,0)处写入J
       lcd_write_char(10,0,'K');   //在坐标(10,0)处写入K
       lcd_write_char(11,0,'L');   //在坐标(11,0)处写入L
       lcd_write_char(12,0,'M');   //在坐标(12,0)处写入M
       lcd_write_char(13,0,'N');   //在坐标(13,0)处写入N
       lcd_write_char(14,0,'O');   //在坐标(14,0)处写入O
       lcd_write_char(15,0,'P');   //在坐标(15,0)处写入P
    lcd_write_char(0,1,'Q');       //在坐标(0,1)处写入Q
    lcd_write_char(1,1,'R');       //在坐标(1,1)处写入R
    lcd_write_char(2,1,'S');       //在坐标(2,1)处写入S
    lcd_write_char(3,1,'T');       //在坐标(3,1)处写入T
    lcd_write_char(4,1,'U');       //在坐标(4,1)处写入U
    lcd_write_char(5,1,'V');       //在坐标(5,1)处写入V
    lcd_write_char(6,1,'W');       //在坐标(6,1)处写入W
    lcd_write_char(7,1,'X');       //在坐标(7,1)处写入X
    lcd_write_char(8,1,'Y');       //在坐标(8,1)处写入Y
    lcd_write_char(9,1,'Z');       //在坐标(9,1)处写入Z   
    while(1)            // 进入程序主循环
    {            
        
    }         
}
void delay1(int ms)      // 延时子函数,用于模拟时序中高低电平的保持时间,非精确的定时
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<100; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}
//================================*/   
//               1602检测判忙函数                        */
//================================*/
bit lcd_busy()            // 读写判断数据的D7读写位,用于判断1602是否忙
 {                          
    bit result;
    D7 = 1;          // 数据口D7置1,为读状态做准备
    LCD_RS = 0;      // 选择指令寄存
    LCD_RW = 1;      // 选择读控制线
    LCD_EN = 1;      // 开使能控制线
    delayNOP();      // 时序延时
    result = D7;  // 读D7的电平
    LCD_EN = 0;      // 关使能
    return(result); // 返回值1:忙,0可以执行操作
 }
//===============================*/                                                         
//               1602写命令函数                         */
//===============================*/
void lcd_wcmd(uchar cmd)
{                          
    while(lcd_busy());    // 判断等待
    LCD_RS = 0;        // 选择指令寄存
    LCD_RW = 0;        //选择写
    LCD_EN = 0;        // 开使能控制线
    _nop_();        // 时序延时
    _nop_();         // 时序延时
    B = cmd;        // 把命令字送入B 
    D0 = B_0;        // 把cmd的0位写入D0
    D1 = B_1;        // 把cmd的1位写入D1
    D2 = B_2;        // 把cmd的2位写入D2
    D3 = B_3;        // 把cmd的3位写入D3
    D4 = B_4;        // 把cmd的4位写入D4
    D5 = B_5;        // 把cmd的5位写入D5
    D6 = B_6;        // 把cmd的6位写入D6
    D7 = B_7;        // 把cmd的7位写入D7
    delayNOP();        // 时序延时
    LCD_EN = 1;        // 使能控制线
    delayNOP();        // 时序延时
    LCD_EN = 0;      // 关闭使能控制线
}
//===========================*/   
//          1602写数据函数                     */
//===========================*/
void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());      // 判断等待
    LCD_RS = 1;        // 选择数据寄存器
    LCD_RW = 0;        // 选择写
    LCD_EN = 0;        // 使能控制线
    B = dat;        // 把databuf送入B 
    D0 = B_0;        // 把dat的0位写入D0
    D1 = B_1;        // 把dat的1位写入D1
    D2 = B_2;        // 把dat的2位写入D2
    D3 = B_3;        // 把dat的3位写入D3
    D4 = B_4;        // 把dat的4位写入D4
    D5 = B_5;        // 把dat的5位写入D5
    D6 = B_6;        // 把dat的6位写入D6
    D7 = B_7;        // 把dat的7位写入D7
    delayNOP();        // 时序延时
    LCD_EN = 1;        // 开使能控制线
    delayNOP();        // 时序延时
    LCD_EN = 0;     // 关使能控制线
}
//=========================*/   
//          1602 LCD初始化               */
//=========================*/
void lcd_init()
{ 
    delay1(15);          // 时序延时        
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay1(5);             // 时序延时
    lcd_wcmd(0x38);         
    delay1(5);             // 时序延时
    lcd_wcmd(0x38);         
    delay1(5);             // 时序延时

    lcd_wcmd(0x0c);      //显示开,关光标
    delay1(5);
    lcd_wcmd(0x06);      //移动光标
    delay1(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay1(5);
}
//====================*/   
//    设置显示地址     */
//===================*/
void lcd_write_address(unsigned char x,unsigned char y)
{  
    x&=0x0f;                                //列地址限制在0-15
       y&=0x01;                                //行地址限制在0-1
       if(y==0x00)
        lcd_wcmd(x| 0x80);
       else                                    //需要自行查看1602写地址的指令格式
        lcd_wcmd((x +0x40) | 0x80);            //第二行的列地址写入
}
//========================*/   
//   指定地址写入函数     */
//=====================*/
void lcd_write_char(unsigned char x,unsigned char y,unsigned char buf)
{          
    lcd_write_address(x,y); //写入地址            
    lcd_wdat(buf);        //写入显示数据    
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式