专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

串行1602的四位数据线程序-avr单片机

作者:佚名   来源:本站原创   点击数:  更新时间:2013年08月06日   【字体:

1602的四位数据线程序,节省了IO。单片机用的是Atmega16,编译环境ICC6.31A,1602驱动头文件。


1602Driver.h
/*********************LCD模块1602底层驱动库***********************
*  LCD模块与单片机的硬件连接:
*           /端口名称 /端口符号 /MCU端口 / LCD引脚号/
*
*          RS数据/指令选择线
*            RS    PD3  4
*          R/W读写选择线  
*            R/W   GND  5
*          EN写使能线
*            EN    PD2    6
*          三态双向数据总线  
*           D0-D3    NC  7-10
*           D4          PD4  11
*           D5          PD5  12
*           D6          PD6  13           
*           D7          PD7       14
*                         
*  其他端口连接:
*    电源负     VSS             1
*    电源正+4.5--+5.5V   VDD         2
*    对比度调节    VL    GND  3
*    背光负     BLK   NC  15    
*    背光正              BLA   NC  16
*  说明:采用节省端口的4线线连接方式,即将8位的数据分两次传输;同
*        时将R/W接地RW(只用W不需要R,所以可以省一根线)
*  日期:2006/02/03


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

 

/*****************定义MCU与LCD的接口******************/
#define LCD_EN_PORT      PORTC         //写使能。高有效,下降沿时锁定数据
#define LCD_RS_PORT      PORTC         //指令/数据选择
#define LCD_DATA_PORT    PORTC                        //数据总线

 

#define LCD_EN           0x04                          //PORTD2         out
#define LCD_RS           0x08                          //PORTD3   out
#define LCD_DATA         0xf0                       //PORTD4/5/6/7   out


#define Data_Write       LCD_RS_PORT |=  LCD_RS      //写数据模式
#define Command_Write    LCD_RS_PORT &= ~LCD_RS     //写指令模式


#define Write_En         LCD_EN_PORT |=  LCD_EN     //写使能
#define Write_Lock      LCD_EN_PORT &= ~LCD_EN     //锁定数据


//#define Graph_Right_Run  LCD_Write_Char(0x02,0)     //画面右移


 


const char CHR[16] = {'0','1','2','3','4','5','6','7','8'
                     ,'9','a','b','c','d','e','f'};
unsigned char LCD_Buff[] = {0,0,0,0,0,0,0,0};    


/*******************N us延时函数**********************/
void Delay_nus(unsigned int j)                       
{
   unsigned int i="0";
   for(i=j;i>0;i--)
   {
      asm("nop");
   }  
}


/********************N ms延时函数*********************/
void Delay_nms(unsigned int n)                        
{
   unsigned int m = 0;
   unsigned int k = 0;
   for (m=n;m>0;m--)
   {
      for (k=1140;k>0;k--)
   { 
      Delay_nus(1);
      }  
   }  
}

 

/******读写使能(高电平有效,下降沿锁定数据 )********/
void Write_Enable(void)
{
   Write_En;
   Delay_nus(1);
   Write_Lock;
}

 

/*---------------------------------------------------------------------
* LCD_Write_Char      :英文单字符显示函数
*
* 向LCD发送数据/指令。  Command="1"    发送显示数据
*       Command=0    发送指令数据
*
* 输入参数     :Command         数据/指令寄存器选择
*      Data   显示内容  
*                        
-----------------------------------------------------------------------*/
void LCD_Write_Char(char Command,char Data)           
{
   unsigned Command_Temp,Data_Temp;
   Command_Temp = Command;
   Data_Temp    = Data;
   Delay_nms(1);                     //延时1ms,以避开"写繁忙"时期
 
 
   if (Command == 0)        //数据输入模式
   {
      Data_Write;
   LCD_DATA_PORT &= 0x0f;                   //数据口清零
   LCD_DATA_PORT |= Data_Temp&0xf0;       //先送高4位
   }  
   else                //指令输入模式
   {
      Command_Write;
   LCD_DATA_PORT &= 0x0f;
   LCD_DATA_PORT |= Command_Temp&0xf0;
   }
   Write_Enable();


 Command_Temp=Command_Temp << 4;              
    Data_Temp=Data_Temp       << 4;
 
    LCD_DATA_PORT &= 0X0F;                   //数据口清零
    if (Command==0)                //再送低4位
 {
       LCD_DATA_PORT |= Data_Temp&0xf0;
 }
    else
    {
    LCD_DATA_PORT |= Command_Temp&0xf0;
 } 
   
 Write_Enable();
}


/***********LCD模块初始化**************/
void LCD_Init(void)                                  
{
 Delay_nms(5);
 
 LCD_Write_Char(0x28,0);          //4位数据线格式
 Delay_nus(10);
 LCD_Write_Char(0x0d,0);              //显示开,光标闪烁
 Delay_nus(10);
 LCD_Write_Char(0x01,0);          //清屏
 Delay_nms(1);
 LCD_Write_Char(0x06,0);          //光标模式设置
}

 

/*-----------------------------------------------------------------------
* Locate              : 设置LCD显示的起始位置
*
* 输入参数:x、y      : 显示字符串的位置,X:0-1,Y:0-15
*                      LCD第一行显示寄存器地址:0X80-0X8F
*                      LCD第一行显示寄存器地址:0XC0-0XCF 
-----------------------------------------------------------------------*/
void Locate( unsigned char x, unsigned char y )
{
    unsigned char  Address;
 if (x == 0)
     Address = 0x80 + y;                   //第一行显示的地址
    else
     Address = 0xc0 + y;           //第二行显示的地址
    LCD_Write_Char(Address,0);
}


/*-----------------------------------------------------------------------
* LCD_Write_String    : 英文字符串显示函数
*
* 输入参数:*s        :英文字符串指针
*          X、Y       :显示字符串的位置
-----------------------------------------------------------------------*/
void LCD_Write_String(unsigned char X,unsigned char Y,unsigned char *String)
  {
 Locate( X, Y);                        //先送显示起始坐标
   
    while (*String)                 //再依次送显示字符
      {
        LCD_Write_Char( 0, *String );
     String ++;
      }
  
  }


/*-----------------------------------------------------------------------
* DEC_Num_Disp        :10进制数值显示函数
*
* 输入参数            :X     字符起始显示行坐标2
*         Y     字符起始显示列坐标
*      Num   需要显示的数值(最长8位)
*              Bit   有效显示的位数
* 输出                :
-----------------------------------------------------------------------*/
void DEC_Num_Disp(unsigned char X,unsigned char Y,unsigned long Num,char Bit)
{
   unsigned char i   = 0;
   Locate( X, Y );
   for (i=0 ; i<Bit ; i++)
   {
   LCD_Buff[i] = CHR[Num%10];
   Num = Num/10;
   }
   for (i=0 ; i<Bit ; i++)
   {
      LCD_Write_Char(0,LCD_Buff[Bit-i-1]);   //先写高位再写低位
   } 
}


/*-----------------------------------------------------------------------
* HEX_Num_Disp        :16进制数值显示函数
*
* 输入参数            :X     字符起始显示行坐标
*         Y     字符起始显示列坐标
*      Num   需要显示的数值(最长8位)
*              Bit   有效显示的位数
* 输出                :
-----------------------------------------------------------------------*/
void HEX_Num_Disp(unsigned char X,unsigned char Y,unsigned long Num,char Bit)
{
   char a = 0;
   Locate( X, Y );
   for(a=8-Bit ; a<8 ; a++)
   {
      LCD_Write_Char(0,CHR[(Num<< (a << 2)) >>28]);   
   }
}


1602测试程序LCD.c


/*********************************************
* "1602Driver.h"库测试程序
*********************************************/


#include <iom16v.h>
#include "1602Driver.h"

 

void Port_Init(void)
{
   DDRD  = 0xff;
   DDRC  = 0xff;
}
void main (void)
{
   int counter;
   OSCCAL="0XA5";
   Port_Init();
   LCD_Init();
   LCD_Write_Char(0x01,0);               //清屏
  
   HEX_Num_Disp(0,0,13,1);
   DEC_Num_Disp(0,1,4,1);
   //LCD_Write_String(2,0,"T");
   LCD_Write_String(1,0,"Disp");


   while(1);
}

关闭窗口

相关文章