51单片机1602怎么显示一行字符,c语言的

Python012

51单片机1602怎么显示一行字符,c语言的,第1张

#define LCD1602_FLAG

#define LCD1602_PORT P0

#include<reg51.h>

#include<stddef.h>

#define uchar unsigned char

sbit lcd1602_rs=P2^0

sbit lcd1602_e=P2^2

sbit lcd1602_rw=P2^1

sbit lcd1602_busy=P0^7

uchar str[]="This is Key Test"

uchar keyval,keystr[16]

void delay(uchar a)

{

uchar i

while(a--)for(i=0i<120i++)

}

/*

************************************

 * 函数名称:lcd1602_CheckBusy()

 * 函数功能:状态查询

************************************

*/

void lcd1602_CheckBusy()

{

    do

    {

    lcd1602_busy=1

    lcd1602_rs=0

    lcd1602_rw=1

    lcd1602_e=0

    lcd1602_e=1

    }

while(lcd1602_busy)

}

/*

***************************************

 * 函数名称: lcd1602_WriteCmd()

 * 函数功能:写命令

 * 入口参数:命令字

 * 出口参数:无

***************************************

*/

void lcd1602_WriteCmd(const uchar cmd)

{

    lcd1602_CheckBusy()

lcd1602_rs=0

lcd1602_rw=0

lcd1602_e=1

LCD1602_PORT=cmd

lcd1602_e=0

}

/*

*******************************************

 * 函数名称:lcd1602_WriteData()

 * 函数功能:写数据

 * 入口参数:c--待写数据

 * 出口参数:无

*********************************************

*/

void lcd1602_WriteData(const uchar c)

{

    lcd1602_CheckBusy()

lcd1602_rs=1

lcd1602_rw=0

lcd1602_e=1

LCD1602_PORT=c

lcd1602_e=0

}

/*

***********************************************

 * 函数名称:lcd1602_Init()

 * 函数功能:初始化LCD

 * 入口参数:无

 * 出口参数:无

***********************************************

*/

void lcd1602_Init()

{

    lcd1602_WriteCmd(0x38) //显示模式为8位2行5*7点阵

    lcd1602_WriteCmd(0x0c) //display enable,flag enable,flash enable,

    lcd1602_WriteCmd(0x06) //flag move to right,screen don't move

    lcd1602_WriteCmd(0x01) //clear screen

}

/*

************************************************

 * 函数名称:lcd1602_Display()

 * 函数功能: 字符显示

 * 入口参数:ptr--字符或字符串指针

 * 出口参数:无

 * 说    明:用户可通过以下方式来调用:

 *           1)lcd1602_Display("Hello,world!")

 *           2) INT8U 存储类型 txt[]="要显示的字符串"

 *              或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'}

 *              INT8U *ptr

 *              ptr=&txt

 *              lcd1602_Display(ptr)

 *              或 lcd1602_Display(txt)

 *              或 lcd1602_Display(&txt)

************************************************

*/

void lcd1602_Display(const uchar *ptr,uchar line)

{

    uchar data i=0

uchar *data q

q=ptr

switch(line)

{

case 0:

lcd1602_WriteCmd(0x80)

while(q!=NULL && (*q!='\0') && i<16)

     {

lcd1602_WriteData(*q)

q++

i++

     }

break

case 1:

lcd1602_WriteCmd(0xc0)

while(q!=NULL && (*q!='\0') && i<16)

     {

lcd1602_WriteData(*q)

q++

i++

}

break

}

}

uchar kbscan(void)

{

unsigned char sccode,recode

P3=0x0f  //发0扫描,列线输入

if ((P3 & 0x0f) != 0x0f)  //有键按下

{

delay(20)   //延时去抖动

if ((P3&0x0f)!= 0x0f)

{

sccode = 0xef    //逐行扫描初值

while((sccode&0x01)!=0)

{

    P3=sccode

if((P3&0x0f)!=0x0f)

{

    recode=(P3&0x0f)|0xf0

while((P3&0x0f)!=0x0f)//等待键抬起

return((~sccode)+(~recode))

 }

        else

sccode=(sccode<<1)|0x01

}

}

}

return 0  //无键按下,返回0

}

uchar getkey(void)

{

uchar key

key=kbscan()

if(key==0){keyval=0xffreturn(0)}

switch(key)

{

case 0x11:keyval=7break

case 0x12:keyval=4break

case 0x14:keyval=1break

case 0x18:keyval=10break

case 0x21:keyval=8break

case 0x22:keyval=5break

case 0x24:keyval=2break

case 0x28:keyval=0break

case 0x41:keyval=9break

case 0x42:keyval=6break

case 0x44:keyval=3break

case 0x48:keyval=11break

case 0x81:keyval=12break

case 0x82:keyval=13break

case 0x84:keyval=14break

case 0x88:keyval=15break

default:keyval=0xffbreak

}

if(keyval!=0xff)return(1)

else return(0)

}

main()

{

uchar num

lcd1602_Init()

lcd1602_Display(str,0)

while(1)

{

if(getkey())

{

keystr[num]=keyval+0x30

lcd1602_Display(keystr,1)

num++

num%=16

}

}

}

这个是1602内部结构决定的,你只需要在初始化的时候先设置三次显示,然后再设置你的其他要求。

芯片厂家推荐的用法:

INT:

MOV

A,#30H

MOV

DATR,#CW_ADD

MOV

R2,#03H

INT1:

MOVX

@DPTR,A

CALL

DELAY

DJNZ

R2,INT1

这上面就是1602对于51单片机推荐的初始化之前加的三次模式设置

1、设置指针void *P,p=1602,memset()函数清零,如果是动态开辟的就要用free。

2、例程:

/* ME300B单片机开发系统演示程序 - DS18B20温度显示     */

/* LCD1602显示                                       */

/*******************************************************************/

#include < reg51.h >

#include < intrins.h >

#define uchar unsigned char

#define uint   unsigned int

sbit DQ = P3^3    //定义DS18B20端口DQ  

sbit BEEP=P3^7    //蜂鸣器驱动线

bit presence   

sbit LCD_RS = P2^0              

sbit LCD_RW = P2^1 

sbit LCD_EN = P2^2 

uchar code   cdis1[ ] =  

uchar code   cdis2[ ] =  

uchar code   cdis3[ ] =  

uchar code   cdis4[ ] =  

unsigned char data   temp_data[2] =  

unsigned char data   display[5] =     

unsigned char code   ditab[16] =     {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,

                                                         0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} 

void beep()  

unsigned char code   mytab[8] =  

#define delayNOP()   

/*******************************************************************/

void delay1(int ms)

{

unsigned char y 

   while(ms--)

{

   for(y = 0  y<250  y++)

   {

    _nop_() 

    _nop_() 

    _nop_() 

    _nop_() 

   }

}

}

/******************************************************************/

/*检查LCD忙状态                                                    */

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。    */

/******************************************************************/ 

bit lcd_busy()

{                          

     bit result 

     LCD_RS = 0 

     LCD_RW = 1 

     LCD_EN = 1 

     delayNOP() 

     result = (bit)(P0&0x80) 

     LCD_EN = 0 

     return(result)  

}

/*写指令数据到LCD                                                   */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。           */

/*******************************************************************/

void lcd_wcmd(uchar cmd)

{                          

    while(lcd_busy()) 

     LCD_RS = 0 

     LCD_RW = 0 

     LCD_EN = 0 

     _nop_() 

     _nop_()  

     P0 = cmd 

     delayNOP() 

     LCD_EN = 1 

     delayNOP() 

     LCD_EN = 0   

}

/*******************************************************************/

/*写显示数据到LCD                             */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。        */

/*******************************************************************/

void lcd_wdat(uchar dat)

{                          

    while(lcd_busy()) 

     LCD_RS = 1 

     LCD_RW = 0 

     LCD_EN = 0 

     P0 = dat 

     delayNOP() 

     LCD_EN = 1 

     delayNOP() 

     LCD_EN = 0  

}

/*   LCD初始化设定                                                   */

/*******************************************************************/

void lcd_init()

     delay1(15)    

     lcd_wcmd(0x01)        //清除LCD的显示内容            

     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_pos(uchar pos)

{                          

   lcd_wcmd(pos | 0x80)    //数据指针=80+地址变量

}

/*自定义字符写入CGRAM                                    */

/*******************************************************************/

void   writetab()  

{  

     unsigned char i 

     lcd_wcmd(0x40)              //写CGRAM

     for (i = 0  i< 8  i++)       

     lcd_wdat(mytab[ i ])         

}

/*us级延时函数                                         */

/*******************************************************************/

void Delay(unsigned int num)

{

   while( --num ) 

}

/*初始化ds1820                                       */

/*******************************************************************/

Init_DS18B20(void)

{  

      DQ = 1        //DQ复位

      Delay(8)      //稍做延时

      DQ = 0        //单片机将DQ拉低

      Delay(90)     //精确延时 大于 480us

      DQ = 1         //拉高总线

      Delay(8) 

      presence = DQ      //如果=0则初始化成功 =1则初始化失败

      Delay(100) 

      DQ = 1  

     

      return(presence)  //返回信号,0=presence,1= no presence

}

/* 读一个字节                      */

/*******************************************************************/

ReadOneChar(void)

{

unsigned char i = 0 

unsigned char dat = 0 

for (i = 8  i > 0  i--)

   {

     DQ = 0  // 给脉冲信号

     dat >>= 1 

     DQ = 1  // 给脉冲信号

     if(DQ)

      dat |= 0x80 

     Delay(4) 

   }

     return (dat) 

}

/* 写一个字节                                          */

/*******************************************************************/

WriteOneChar(unsigned char dat)

{

   unsigned char i = 0 

   for (i = 8  i > 0  i--)

   {

     DQ = 0 

     DQ = dat&0x01 

     Delay(5) 

     DQ = 1 

     dat>>=1 

   }

}

/* 读取温度                             */

/*******************************************************************/

Read_Temperature(void)

{

      Init_DS18B20() 

  

      WriteOneChar(0xCC)    // 跳过读序号列号的操作

      WriteOneChar(0x44)    // 启动温度转换

      Init_DS18B20() 

      WriteOneChar(0xCC)    //跳过读序号列号的操作

      WriteOneChar(0xBE)    //读取温度寄存器

      temp_data[0] = ReadOneChar()     //温度低8位

      temp_data[1] = ReadOneChar()     //温度高8位 

}

/* 数据转换与温度显示                                               */

/*******************************************************************/

Disp_Temperature()

{

   display[4]=temp_data[0]&0x0f 

   display[0]=ditab[display[4]]+0x30       //查表得小数位的值

  

   display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) 

   display[3]=display[4]/100+0x30 

   display[1]=display[4]%100 

   display[2]=display[1]/10+0x30 

   display[1]=display[1]%10+0x30 

     if(display[3]==0x30)         //高位为0,不显示

    { 

      display[3]=0x20               

      if(display[2]==0x30)       //次高位为0,不显示

      display[2]=0x20 

    }

      lcd_pos(0x48)              

      lcd_wdat(display[3])          //百位数显示 

      lcd_pos(0x49)              

      lcd_wdat(display[2])          //十位数显示 

   lcd_pos(0x4a)              

      lcd_wdat(display[1])          //个位数显示 

   lcd_pos(0x4c)              

      lcd_wdat(display[0])          //小数位数显示 

}  

/*******************************************************************/

/* 蜂鸣器响一声                  */

/*******************************************************************/

void beep()

   {

     unsigned char y 

     for (y=0 y<100 y++)

     {

       Delay(60) 

       BEEP=!BEEP                  //BEEP取反

     } 

     BEEP=1                        //关闭蜂鸣器

Delay(40000) 

   }

/* DS18B20 OK 显示菜单                                              */

/*******************************************************************/

void   Ok_Menu ()

     uchar   m 

     lcd_init()                  //初始化LCD 

            

     lcd_pos(0)                  //设置显示位置为第一行的第1个字符

      m = 0 

     while(cdis1[m] != '\0')

      {                          //显示字符

        lcd_wdat(cdis1[m]) 

        m++ 

      }

     lcd_pos(0x40)               //设置显示位置为第二行第1个字符

      m = 0 

     while(cdis2[m] != '\0')

      {

        lcd_wdat(cdis2[m])        //显示字符

        m++ 

      }

      writetab()                 //自定义字符写入CGRAM

      delay1(5) 

      lcd_pos(0x4d) 

      lcd_wdat(0x00)            //显示自定义字符

}

/* DS18B20 ERROR 显示菜单                              */

/*******************************************************************/

void   Error_Menu ()

{

      uchar   m 

      lcd_init()                  //初始化LCD 

     lcd_pos(0)                  //设置显示位置为第一行的第1个字符

      m = 0 

      while(cdis3[m] != '\0')

      {                          //显示字符

        lcd_wdat(cdis3[m]) 

        m++ 

      }

      lcd_pos(0x40)               //设置显示位置为第二行第1个字符

      m = 0 

      while(cdis4[m] != '\0')

      {

        lcd_wdat(cdis4[m])        //显示字符

        m++ 

      }

}

/* 主函数      */

/************************************/

void main()

{

      Ok_Menu () 

do

   {

       Read_Temperature() 

    Disp_Temperature() 

      }

     while(!presence)   

      Error_Menu () 

do

   {  

     Init_DS18B20() 

     beep() 

      }

while(presence) 

}