电路图如下
下面是lcd1602.c文件内容:
#include <avr/io.h>
#include <util/delay.h>
#define INT8U unsigned char
//定义LCD1602对应的端口,方便后面使用。
#define LCD1602_CTL_DDR DDRB
#define LCD1602_CTL_PORT PORTB
#define LCD1602_PIN PINC
#define LCD1602_DDR DDRC
#define LCD1602_PORT PORTC
#define RS_1() LCD1602_CTL_PORT |= _BV(PB0)
#define RS_0() LCD1602_CTL_PORT &= ~_BV(PB0)
#define RW_1() LCD1602_CTL_PORT |= _BV(PB1)
#define RW_0() LCD1602_CTL_PORT &= ~_BV(PB1)
#define E_1() LCD1602_CTL_PORT |= _BV(PB2)
#define E_0() LCD1602_CTL_PORT &= ~_BV(PB2)
//avr忙检测
void Busy_Check()
{
LCD1602_DDR = 0x00; //把端口设置为输入
RS_0(); RW_1();
E_1(); _delay_us(20);
while((LCD1602_PIN & 0X80) == 1); //最高位为1表示忙;
E_0();
LCD1602_CTL_DDR = 0XFF; //把端口设置回输出状态
}
//写一个命令到lcd1602
void Write_Command(INT8U CMD)
{
Busy_Check();
RS_0(); RW_0();
LCD1602_PORT = CMD;
E_1(); E_0();
}
//写一个字节到lcd1602
void Write_Data(INT8U DAT)
{
Busy_Check();
RS_1(); RW_0();
LCD1602_PORT = DAT;
E_1(); E_0();
}
//在x位,y行,写入字符串str;
void Display_String(INT8U x,INT8U y,char *Str)
{
INT8U len,i;
if (y ==0)
{
Write_Command(0x80 | x);
}else if (y == 1)
{
Write_Command(0xC0 | x);
}
for (i=0; i<16 && Str[i] != '\0'; i++)
{
Write_Data(Str[i]);
}
}
//初始化lcd1602,在main.c中直接调用该函数就可以初始化lcd1602;
void Init_LCD1602()
{
LCD1602_DDR = 0XFF; LCD1602_PORT = 0X00;
LCD1602_CTL_DDR |= 0X0F; LCD1602_CTL_PORT = 0X00;
Write_Command(0x38);
_delay_ms(15);
Write_Command(0x01);
_delay_ms(15);
Write_Command(0x06);
_delay_ms(15);
Write_Command(0x0c);
_delay_ms(15);
}
下面是lcd1602.h的定义:
#ifndef LCD1602_H_
#define LCD1602_H_
#define F_CPU 4000000UL
#define INT8U unsigned char
extern void Busy_Check();//忙检测
extern void Write_Command(INT8U Command);//写指令
extern void Write_Data(INT8U DATA);//写数据
extern void Display_String(INT8U x,INT8U y,char *Str);//从y行x位开始按序写Str字符串
extern void Init_LCD1602();//初始化LCD1602
#endif
下面是main.c的内容,简单测试一下,功能是否实现
#include "lcd1602.h"
int main(void)
{
Init_LCD1602();
Display_String(0,0,"POWER: 32.25 dBm");
Display_String(0,1," OR 1.007 W");
while(1);
}