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

M16的1602驱动

发布时间:2020-06-08 发布时间:
|

/***************************/
/*头文件名:LCD液晶驱动    */
/* Target : m16            */
/* Crystal: 8.0000Mhz      */

#ifndef _LCD_H_
#define _LCD_H_
#include "DELAY.H"
/*------AVR与LCD连接信息-----------------------------------------
PA_2 ->RS
PA_3 ->EN
PA_4 ->D4
PA_5 ->D5
PA_6 ->D6
PA_7 ->D7            6根线
----------------------------------------------------------------*/

//===============使用本驱动,改变下面配置信息即可==================
#define uint    unsigned int
#define uchar   unsigned char

#define LEFT        0
#define RIGHT       1
#define RS_SET      PORTB |=  (1 << 6)
#define RS_CLR      PORTB &=~ (1 << 6)
#define EN_SET      PORTB |=  (1 << 7)
#define EN_CLR      PORTB &=~ (1 << 7)
#define DB          PORTA                  //定义数据口
#define DB_DDR_OUT  { DDRA |= 0XF0, DDRB |= 0xC0; }           //定义数据口方向 4,5,6,7为输出, 控制口6,7为输出
//=================================================================

//===================函数说明======================================
void LCD_en_write(void);             //使能
void LCD_write_command(uchar command);          //写指令
void LCD_write_data(uchar DATA);           //写数据
void LCD_init( void );                //初始化
void LCD_set_rc( uchar r, uchar c );          //写位置
void LCD_write_string(uchar r, uchar c, uchar *s);       //写字符串
void LCD_write_char(uchar r, uchar c, uchar DATA);       //写字符
void LCD_write_chardata( uchar r, uchar c, uchar chardata[]);      //写整型字符n
void LCD_write_datafloat( uchar r, uchar c, float datafloat, uint p, uint mm);      //
void LCD_write_datalongint( uchar r, uchar c, long int dataint);      //
void LCD_write_array( uchar r, uchar c, uchar array[] );     //写字符串
//==================================================================
#endif

 

#define _LCD_C_
#include "LCD.h"
#include
//==========================================
//函数名称:液晶模块使能
//函数作用: 使能液晶
//入口参数: 无
//返回类型:无
//==========================================
void LCD_en_write(void)
{
  EN_SET;
  delay_nus(4);
  EN_CLR;
}

//==========================================
//函数名称:写指令
//函数作用:
//入口参数: 液晶指令command
//返回类型:无
//==========================================
void LCD_write_command(uchar command)
{
  delay_nus( 16 );
  RS_CLR;
  DB &= 0X0F;           //清高四位
  DB |= command & 0xf0; //写高四位
  LCD_en_write();
  command=command << 4;   //低四位移到高四位
  DB &= 0x0f;             //清高四位
  DB |= command & 0xf0;   //写低四位
  LCD_en_write();
  //delay_nms(2);         //清屏指令时间很长, 保险起见,可以增加
}

//==========================================
//函数名称:写数据
//函数作用:
//入口参数: 数据DATA
//返回类型:无
//==========================================
void LCD_write_data(uchar DATA)
{
  delay_nus(16);
  RS_SET;           //RS=1
  DB &= 0X0f;       //清高四位
  DB |= DATA&0xf0;  //写高四位
  LCD_en_write();
  DATA = DATA << 4; //低四位移到高四位
  DB &= 0X0f;       //清高四位
  DB |= DATA&0xf0;  //写低四位
  LCD_en_write();
}

//==========================================
//函数名称:液晶初始化函数
//函数作用:
//入口参数: 无
//返回类型:无
//==========================================
void LCD_init( void )
{
  DB_DDR_OUT;
  LCD_write_command(0x28);
  LCD_en_write();           //********总结这里一定要加这液晶使能*********
  delay_nus(20);
  LCD_write_command(0x28);  //4位显示
  LCD_write_command(0x0c);  //显示开
  LCD_write_command(0x01);  //清屏
  delay_nms(5);             //延时一定要长
}

//==========================================
//函数名称:写地址
//函数作用:
//入口参数: 行位置r, 列位置c
//返回类型:无
//==========================================
void LCD_set_rc( uchar r, uchar c )
{
    uchar address;

    if (r == 1)
    address = 0x80 + c;
    else if(r == 2)
    address = 0xc0 + c;

    LCD_write_command( address );
}

//==========================================
//函数名称:写字符串
//函数作用: 在指定位置写一串字符串
//入口参数: 行位置r, 列位置c, 字符串*s
//返回类型:无
//==========================================
void LCD_write_string(uchar r, uchar c, uchar *s)
{
    LCD_set_rc( r, c ); //写地址

    while( *s )        // 写显示字符
    {
      LCD_write_data( *s );
      s++;
    }
}

void LCD_write_char(uchar r, uchar c, uchar DATA)       //写字符
{
   LCD_set_rc( r, c );
  LCD_write_data( DATA );
}

//==========================================
//函数名称:写字符数组
//函数作用: 在指定位置写一串字符串
//入口参数: 行位置r, 列位置c, 字符数组chardata[], 字符个数
//返回类型:无
//==========================================
void LCD_write_array( uchar r, uchar c, uchar array[] )
{
  uchar i = 0;
    while( array[i] != '\0' )
 {
    LCD_write_char( r, c, array[i] );
      if( ++c == 16 )
   {
       if( r == 1 )
    {   
        c = 0;
     r = 2;
         LCD_write_char( r, c, array[i] );
    }
    
    else if( r == 2 )
    {
       c = 0;
     r = 1;
     LCD_write_char( r, c, array[i] );
       }
      }
   i++;
 }  
}

//返回整形数据的长度
char lengh_longint( long unsigned datalongint )
{
    long signed datatmp = datalongint;
    uchar data_n = 0;
    while( datatmp != 0 )
    {
        datatmp /= 10;
        data_n++;
    }

    if( datalongint == 0 )
    {
        data_n = 1;
    }

    return data_n;
}


//==========================================
//函数名称:显示一个整型数据
//函数作用: 在指定位置显示整数
//入口参数: 行位置r, 列位置c, 字符数组dataint[]
//返回类型:无
//==========================================
void LCD_write_datalongint( uchar r, uchar c, long int dataint )
{
    uchar datachar1[8];
    uchar datachar2[8];
    uchar n = 0;
    uchar i =0;
    uchar k =0;        //取字符个数
    uchar kk = 0;      //取字符个数
 long int datainttmp = dataint;
 
    while( datainttmp != 0 )
    {
        datachar1[n++] = ( datainttmp % 10 ) + 0x30;  //转换为字符
        datainttmp /= 10;
    }

    if( dataint != 0 )                   //*/*//*/
    {
        k = n - 1;
        kk = n;

        for( i = 0; i < kk; i++, k-- )
        {
            datachar2[k] = datachar1[i];               //将数字符串倒过来
        }

     LCD_set_rc( r, c );
        for( i = 0; i < kk; i++ )
        {
            LCD_write_char( r, c++, datachar2[i] );
        }
    }
    
    else
    LCD_write_char( r, c, '0' );
}

//==========================================
//函数名称:显示一个实型数据
//函数作用: 在指定位置显示实型数据
//入口参数: 行位置r, 列位置c, 浮点型数据datafloat, 放大倍p, 倍数mm, 
//返回类型:无
//示例    :LCD_write_datafloat( 1, 2, 0.0123, 10000, 4)
//==========================================
void LCD_write_datafloat( uchar r, uchar c, float datafloat, uint p, uint mm)
{
    uchar zhengshu_no = 0;
    uchar whole_fact_n;
    uchar xiaoshu_act_n;
    uchar ling_n;
    
    
    uchar i = 0;
    uchar n = 0;
    uchar k = 0;
    uchar kk = 0;
    uchar datachar1[9];
    uchar datachar2[9];
    uint zhengshu;                 //定义变量zhengshu来存放实数的整数部分
    uint xiaoxhu;                  //定义变量xiaoshu来存放实数的小数部分
    
    long int datawhole;
    long int datawholetmp;
    
    uchar zhengshu_n = 0;          //定义整数部分整数位数
    uchar xiaoshu_n = 0;           //定义小数部分整数位数
    uchar datawhole_n = 0;             //定义实数放大后的位数
    float datatemp1_f;
    float datatemp2_f;
    
    datatemp1_f = datafloat;
    datatemp2_f = datafloat;

    zhengshu = ( uint )datatemp1_f;       //取实数的整数部分

    zhengshu_n = lengh_longint( zhengshu );       //如果整数部分为0, 则只有一位整数, 取整数位数
    
    datawhole = datatemp1_f * p;         //将实数放大,变成整数, datawhole为放大后的数

    datawhole_n = lengh_longint( datawhole ); //如果整数部分为0, datawhole_n 不一定等于小数的位数

    whole_fact_n = mm + zhengshu_n;           ///*/*实际

    if( zhengshu  == 0 )
    {
        xiaoshu_act_n = lengh_longint( datawhole );
        ling_n = mm - xiaoshu_act_n;   //如果整数为0, 小数有效位为xiaoshu_act_n
    }

    else xiaoshu_act_n = mm;

    ling_n = mm - xiaoshu_act_n;  //用ling_0记录小数部分前面0的位数

    for( i = 0; i < xiaoshu_act_n; i++ )
    {
        datachar1[n++] = ( datawhole % 10 ) + 0x30;  //转换为字符
        datawhole /= 10;
    }

    k = n - 1;
    kk = n;                                         //记录存入的个数

   for( i = 0; i < kk; i++, k-- )
    {
        datachar2[k] = datachar1[i];               //将数字符串倒过来
    }
 
 LCD_write_datalongint( r, c, zhengshu );    //显示整数部分
 c = c + zhengshu_n;
 LCD_write_char( r, c, '.' );
    c++;
    for( i = 0; i < ling_n; i++ )            
    {
        LCD_write_char( r, c++, '0' );
    }

    for( i = 0; i < kk; i++ )
    {
        LCD_write_char( r, c++, datachar2[i] );
    }
}






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

热门文章 更多
FPGA和AVR单片机的自动调谐系的设计