锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2024-05-21 04:07:11

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


1602Driver.h
/*********************模块1602底层驱动库***********************
* LCD模块与单片机的硬件连接:
* /端口名称 /端口符号 /端口 / 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 C[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 {
LCD_Buff[i] = CHR[Num%10];
Num = Num/10;
}
for (i=0 ; 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
#include "1602Driver.h"

void Port_Init(void)
{
D = 0xff;
DDRC = 0xff;
}
void main (void)
{
int counter;
OAL="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);
}


-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章