打印
[demo程序]

基于纳瓦特MCU+LCD1602模块

[复制链接]
1500|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
      利用中午休息的时间写了一下NV32与LCD1602的驱动,采用四线制接法,接口定义可以参考程序,程序还需要进一步完善,在此贴出来与大家分享。


lcd1602.c
#include "main.h"

//实际测试可用任意IO读写LCD1602//系统时钟16MHz


///////////////////////////////4线LCD1602////////////////////////////////////////////////
//函数名:  delay
//函数功能:LCD1602延时
//注释:   
void delay(unsigned char z)
{
  unsigned char x,y,j;
        for(j=0;j<4;j++)
    for(x=z;x>0;x--)
      for(y=110;y>0;y--);
}


//函数名:  LCD1602_GPIO_INIT
//函数功能:LCD1602用GPIO初始化
//注释:
void LCD1602_GPIO_INIT(void)
{
        //控制位
        GPIO_Init(GPIOB, GPIO_PTE0_MASK, GPIO_PinOutput);
        GPIO_Init(GPIOB, GPIO_PTE1_MASK, GPIO_PinOutput);
        GPIO_Init(GPIOA, GPIO_PTC5_MASK, GPIO_PinOutput);
       
        //数据位
        GPIO_Init(GPIOB, GPIO_PTG0_MASK, GPIO_PinOutput);
        GPIO_Init(GPIOB, GPIO_PTG1_MASK, GPIO_PinOutput);
        GPIO_Init(GPIOB, GPIO_PTG2_MASK, GPIO_PinOutput);
        GPIO_Init(GPIOB, GPIO_PTG3_MASK, GPIO_PinOutput);
}


//函数名:  LCD1602_INIT
//函数功能:LCD1602初始化
//注释:    DATA可以是指令或者数据
void LCD1602_INIT(void)
{
        LCD1602_GPIO_INIT();
        //GPIO_Init(GPIOD,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_LOW_FAST);
        //GPIO_Init(GPIOC,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_OUT_PP_LOW_FAST);
        RW_L();
        E_L();
        RS_L();//指令
        //GPIO_Write(GPIOB,0X20);
        //GPIO_Write(GPIOB,GPIOB->PDOR|0xFFF2FFFF);
       
    if(0X20&0x10)
          D4_H();
        else
          D4_L();
        if(0X20&0x20)
          D5_H();
        else
          D5_L();
        if(0X20&0x40)
          D6_H();
        else
          D6_L();
        if(0X20&0x80)
          D7_H();
        else
          D7_L();
       
  E_H();//允许
        delay(50);
        E_L();//4线制,在该位四线制通讯时,数据线切换必须是半字节的,之后延时必须超过40US
    //        LCD1602_DATA_write(Write_order,0X28);//4位数据总线模式,显示2行数据,5*10点阵每字符        0X38为8位数据模式, 显示2行数据,5*10点阵每字符
        delay(10);
        LCD1602_DATA_write(Write_order,0x0c); //开显示,有光标,光标闪烁
        delay(10);
        LCD1602_Clear_Screen(); //清屏       
        delay(10);
        LCD1602_DATA_write(Write_order,0x06); //写入数据光标右移,写入新数据显示屏不移动
    delay(10);
        LCD1602_DATA_write(Write_order,0x80); //
}

//函数名:  LCD1602_Clear_Screen
//函数功能:LCD1602清屏
//注释:   
void LCD1602_Clear_Screen(void)
{
        LCD1602_DATA_write(Write_order,0x01); //清屏
}



//函数名:  write_com
//函数功能:LCD1602写指令
//注释:   
void write_com(unsigned int dat)
{
  unsigned char j;
  RS_L();//指令
  for(j=0;j<2;j++)
  {
                //GPIO_Write(GPIOB,(dat&0x00f0));
                //GPIO_Write(GPIOB,GPIOB->PDOR&(((dat&0x000000f0)<<12)|0xFFF0FFFF));
                //GPIO_Write(GPIOB,GPIOB->PDOR | ((dat&0x000000f0)<<12));
               
          if(dat&0x10)
            D4_H();
          else
            D4_L();
          if(dat&0x20)
            D5_H();
          else
            D5_L();
          if(dat&0x40)
            D6_H();
          else
            D6_L();
          if(dat&0x80)
            D7_H();
          else
            D7_L();
               
    E_H();//允许
          delay(50);
          E_L();
          dat<<=4;
  }
}


//函数名:  write_data
//函数功能:LCD1602写数据
//注释:   
void write_data(unsigned int dat)
{
  unsigned char j;
  RS_H();//数据
  for(j=0;j<2;j++)
  {
                //GPIO_Write(GPIOB,(dat&0x00f0));
                //GPIO_Write(GPIOB,GPIOB->PDOR&(((dat&0x000000f0)<<12)|0xFFF0FFFF));
                //GPIO_Write(GPIOB,GPIOB->PDOR | ((dat&0x000000f0)<<12));
               
          if(dat&0x10)
            D4_H();
          else
            D4_L();
          if(dat&0x20)
            D5_H();
          else
            D5_L();
          if(dat&0x40)
            D6_H();
          else
            D6_L();
          if(dat&0x80)
            D7_H();
          else
            D7_L();
          
          E_H();//允许
          delay(50);
          E_L();
          dat<<=4;
  }
}

//函数名:lcd1602_write
//作用:将数据或者指令写入LCD1602
//注释:
void LCD1602_DATA_write(LCD1602_Write_TypeDef order,unsigned char dat)
{
        if(order==Write_data)
                write_data(dat);
        else
          write_com(dat);
}

//函数名:lcd1602_show_character
//作用:  在制定坐标,显示单个字符
void lcd1602_show_character(unsigned char x,unsigned char y,unsigned char dat)
{
        unsigned char address;
        x=x%16;
        y=y%2;
        if(y==1)
                address=0xc0+x;
        else
                address=0x80+x;  
        LCD1602_DATA_write(Write_order,address);
        LCD1602_DATA_write(Write_data,dat);
}

//函数名:lcd1602_show_number
//作用:
//     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
//注释:
//     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
unsigned char lcd1602_show_number(unsigned char x,unsigned char y,unsigned short dat)
{
        unsigned short pow=1,instead;
        unsigned char increase=0,lengh=0;
        instead=dat;
        while(instead!=0)
        {
                instead=instead/10;
                increase++;
        }
        lengh=increase;
        if(increase==0)
        {
                lcd1602_show_character(x,y,0x30);
                return 1;
        }
        else
        {
                for(;increase>1;increase--)
                pow=pow*10;
                while(pow!=0)
                {
                        instead=dat/pow;
                        lcd1602_show_character(x,y,(0x30+instead));
                        x++;
                        if(((x%16)==0)&&(x!=0))
                        {
                                y++;
                                y=y%2;
                                x=x%16;
                        }
                        dat=dat%pow;
                        pow=pow/10;  
          }
        }
        return lengh;
}


//函数名:lcd1602_show_string
//作用:
//     以(X,Y)坐标为起始,显示一个字符串
//注释:
//     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分,字符长度小于256
unsigned char lcd1602_show_string(unsigned char x,unsigned char y,unsigned char *dat)
{
        unsigned char lengh=0;
        while(dat[lengh]!='\0')
        {
                if(((x%16)==0)&&(x!=0))
                {
                    y++;
                                y=y%2;
                    x=x%16;
                }
    lcd1602_show_character(x,y,dat[lengh]);       
                x++;
                lengh++;
        }
        return (lengh);
}


//函数名:lcd1602_show_number
//作用:
//     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
//注释:
//     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
unsigned char lcd1602_show_s32(unsigned char x,unsigned char y,short dat)
{
        short pow=1,instead;
        unsigned char increase=0,lengh=0;
        if(((dat&0x80000000)==0x80000000)&&(dat!=0xffffffff))//负数
        {
          instead=-dat;
          y=y%2;
          lcd1602_show_character(x,y,0x2D);//"-"
          x++;
        }
        else if((dat&0x80000000)!=0x80000000)//正数
        {
          instead=dat;
          y=y%2;
          lcd1602_show_character(x,y,0X2B);//"+"
          x++;     
        }
        else//0
        {
          instead=0;   
        }
        dat=instead;
        while(instead!=0)
        {
                instead=instead/10;
                increase++;
        }
        lengh=increase;
        if(increase==0)
        {
                lcd1602_show_character(x,y,0x30);
                return 1;
        }
        else
        {
                for(;increase>1;increase--)
                pow=pow*10;
                while(pow!=0)
                {
                        instead=dat/pow;
                        lcd1602_show_character(x,y,(0x30+instead));
                        x++;
                        if(((x%16)==0)&&(x!=0))
                        {
                                y++;
                                y=y%2;
                                //x=x%16;
                        }
                        dat=dat%pow;
                        pow=pow/10;  
          }
        }
        return lengh+1;
}

lcd1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__

//为了适应任意IO驱动LCD1602做的定义
#define RW_L() GPIO_PinClear(GPIO_PTE0)//RW=0
#define RW_H() GPIO_PinSet(GPIO_PTE0)  //RW=1

#define RS_L() GPIO_PinClear(GPIO_PTE1)//RS=0
#define RS_H() GPIO_PinSet(GPIO_PTE1)  //RS=1

#define E_L()  GPIO_PinClear(GPIO_PTC5)//E=0
#define E_H()  GPIO_PinSet(GPIO_PTC5)  //E=1


//#define D0_L() P2 &=~BIT0//D0=0
//#define D0_H() P2 |=BIT0 //D0=1
//#define D1_L() P2 &=~BIT1//D1=0
//#define D1_H() P2 |=BIT1 //D1=1
//#define D2_L() P2 &=~BIT2//D2=0
//#define D2_H() P2 |=BIT2 //D2=1
//#define D3_L() P2 &=~BIT3//D3=0
//#define D3_H() P2 |=BIT3 //D3=1
#define D4_L() GPIO_PinClear(GPIO_PTG0)//D4=0
#define D4_H() GPIO_PinSet(GPIO_PTG0)  //D4=1
#define D5_L() GPIO_PinClear(GPIO_PTG1)//D5=0
#define D5_H() GPIO_PinSet(GPIO_PTG1)  //D5=1
#define D6_L() GPIO_PinClear(GPIO_PTG2)//D6=0
#define D6_H() GPIO_PinSet(GPIO_PTG2)  //D6=1
#define D7_L() GPIO_PinClear(GPIO_PTG3)//D7=0
#define D7_H() GPIO_PinSet(GPIO_PTG3)  //D7=1

typedef enum
{
        Write_data  =0X00,
        Write_order =0x01/*BIT0*/
}LCD1602_Write_TypeDef;

//函数名:  delay
//函数功能:LCD1602延时
//注释:   
void delay(unsigned char z);

//函数名:  LCD1602_GPIO_INIT
//函数功能:LCD1602用GPIO初始化
//注释:
void LCD1602_GPIO_INIT(void);

//函数名:  LCD1602_INIT
//函数功能:LCD1602初始化
//注释:    DATA可以是指令或者数据
void LCD1602_INIT(void);

//函数名:  LCD1602_Clear_Screen
//函数功能:LCD1602清屏
//注释:   
void LCD1602_Clear_Screen(void);



//函数名:  write_com
//函数功能:LCD1602写指令
//注释:   
void write_com(unsigned int dat);


//函数名:  write_data
//函数功能:LCD1602写数据
//注释:   
void write_data(unsigned int dat);

//函数名:lcd1602_write
//作用:将数据或者指令写入LCD1602
//注释:
void LCD1602_DATA_write(LCD1602_Write_TypeDef order,unsigned char dat);

//函数名:lcd1602_show_character
//作用:  在制定坐标,显示单个字符
void lcd1602_show_character(unsigned char x,unsigned char y,unsigned char dat);

//函数名:lcd1602_show_number
//作用:
//     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
//注释:
//     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
unsigned char lcd1602_show_number(unsigned char x,unsigned char y,unsigned short dat);


//函数名:lcd1602_show_string
//作用:
//     以(X,Y)坐标为起始,显示一个字符串
//注释:
//     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分,字符长度小于256
unsigned char lcd1602_show_string(unsigned char x,unsigned char y,unsigned char *dat);

//显示有符号S32
unsigned char lcd1602_show_s32(unsigned char x,unsigned char y,short dat);

#endif



相关帖子

沙发
123ycli| | 2018-7-22 22:59 | 只看该作者
支持下,想起一句话,铁打的1602,流水的MCU。

使用特权

评论回复
板凳
tang87633187| | 2018-8-3 09:35 | 只看该作者
1602LCD 是3.3V供电,还是5V供电

使用特权

评论回复
地板
lxs0026| | 2018-8-26 11:53 | 只看该作者
恩恩恩,不错不错,期待下文。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎参与LabVIEW版块的讨论学习! 点我一键即达

157

主题

2338

帖子

41

粉丝