原创 1602四线程序

2009-4-12 08:34 5779 9 11 分类: MCU/ 嵌入式

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 = 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);
}

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1398279 2009-4-12 08:36

不好意思,原先发的附件不知怎么的就稀里糊涂的弄丢了,刚才把资料源程序直接发到帖子上了,呵呵。

tengjingshu_112148725 2009-4-10 00:10

真言简意赅:)
相关推荐阅读
用户1398279 2010-07-08 00:12
C语言共享库的制作
C语言共享库的制作0推荐 作者:杨硕,华清远见嵌入式学院讲师。1)基本概念共享库也是.o文件的集合,但是这些文件由编译器按照一种特殊的方式生成(Linux中,共享库文件为"ELF"格式,共享库已经具备...
用户1398279 2010-07-04 22:37
Linux 2.6.11 MTD驱动情景分析
Linux 2.6.11 MTD驱动情景分析最近几天为了熟悉linux的驱动开发,我选择了其MTD驱动做了一些研究。我能找到的文章中我觉得有些部分不够细致,所以我还是自己写了一部分分析,希望对别人也能...
用户1398279 2010-05-05 14:25
automake使用及库和头文件的链接
automake使用及库和头文件的链接关于automake的实践今天弄了很久的automake,自动生成Makefile,这样写程序时就会方便很多。之前也花时间看过一次,但当时只是对着一个hello....
用户1398279 2010-05-05 11:33
HP总裁退休时的信件
HP总裁退休时的信件<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />我有个有趣的观察...
用户1398279 2010-04-23 18:04
VMWare的NAT配置(包括DHCP和固定IP配置)
NAT的DHCP配置:这个网上别人写过,自己实验了下,没有问题。1 .最重要的是你的两个服务必须开启:VMware DHCP Service 和VMware NAT Service。具体操作如下: 开...
用户1398279 2010-04-23 10:48
gcc命令objdump用法
gcc命令objdump用法2009年03月29日 星期日 23:49gcc命令之 objdump ---------------objdump是用查看目标文件或者可执行的目标文件的构成的GCC工具-...
EE直播间
更多
我要评论
2
9
关闭 站长推荐上一条 /3 下一条