* 【編譯環境】: ICCAVR
* 【函數功能】: 1602字符顯示
* 【晶 振】: 8M
* 【芯 片】: ATMEGA16A
#include<iom16v.h>
#define uchar unsigned char
#define uint unsigned int
uchar wz[]={"mcustudio1com-cn"};
uchar gd[]={"Tel:15980xx5601"};
#define uchar unsigned char
#define uint unsigned int
#define RS 0
#define RW 1
#define EN 2
void s_ms(uint ms)
{
for(;ms>1;ms--);
}
//查忙
void busy(void)
{
uchar temp;
s_ms(500);
PORTA&=~(1<<RS); //RS=0
s_ms(500);
PORTA|=(1<<RW); //RW=1
s_ms(500);
while(temp)
{
PORTA|=(1<<EN); //EN=1
s_ms(500);
DDRB=0x00; //A口變輸入
PORTB=0xff; //上拉使能
s_ms(500);
temp = PINB&0x80; //讀取A口
s_ms(500);
DDRB=0xff;
PORTB=0xff; //A口變輸出
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
}
//寫指令
void writecom(uchar com)
{
busy();
s_ms(500);
PORTA&=~(1<<RS); //RS=0
s_ms(500);
PORTA&=~(1<<RW); //RW=0
s_ms(500);
PORTA|=(1<<EN); //EN=1
s_ms(500);
PORTB = com; //輸出指令
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
//1602初始化
void LcdInit(void)
{
DDRB = 0xff;
PORTB = 0x00;
writecom(0x38);
s_ms(1000);
writecom(0x01);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
writecom(0x02);
s_ms(1000);
writecom(0x06);
s_ms(1000);
writecom(0x0c);
s_ms(1000);
writecom(0x38);
s_ms(1000);
}
//寫數據
void writedata(uchar data)
{
busy();
s_ms(500);
PORTA|=(1<<RS); //RS=1
s_ms(500);
PORTA&=~(1<<RW); //RW=0
s_ms(500);
PORTA|=(1<<EN); //EN=1
s_ms(500);
PORTB = data; //輸出數據
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
//讀數據
uchar readdata(void)
{
uchar temp;
busy();
s_ms(500);
PORTA|=(1<<RS); //RS=1
s_ms(500);
PORTA|=(1<<RW); //RW=1
s_ms(500);
PORTA|=(1<<EN); //EN=1
s_ms(500);
DDRB=0x00; //A端口變輸入
s_ms(500);
temp = PINB; //讀A端口
s_ms(500);
DDRB=0xff; //A端口變輸出
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
return temp;
}
//=================================================
// 描述: 寫LCD內部CGRAM函數
// 入口: ‘num’要寫的數據個數
// ‘pbuffer’要寫的數據的首地址
// 出口: 無
//================================================
void WriteCGRAM(uint num, const uint *pBuffer)
{
uint i,t;
writecom(0x40);
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
for(i=num;i!=0;i--)
{
t = *pBuffer;
PORTA|=(1<<EN);
PORTB = t;
PORTA&=~(1<<EN);
pBuffer++;
}
}
//=================================================
//描述:寫菜單函數,本程序使用的LCD規格為 16 * 2
//入口:菜單數組首地址
//出口:無
//=================================================
void WriteMenu(const uchar *pBuffer)
{
uchar i,t;
writecom(0x80); //數據地址
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
s_ms(50);
for(i=0;i<16;i++)
{
t = *pBuffer;
PORTB = t;
PORTA|=(1<<EN);
s_ms(50);
PORTA&=~(1<<EN);
pBuffer++;
}
writecom(0xC0);
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
s_ms(50);
for(i=0;i<16;i++)
{
t = *pBuffer;
PORTB = t;
PORTA|=(1<<EN);
s_ms(50);
PORTA&=~(1<<EN);
pBuffer++;
}
}
//====================================================
// 描述:在任意位置寫數字函數
// 入口:’row‘表示要寫數字所在的行地址,只能為1或2
// ’col‘表示要寫數字所在的列地址,只能為0--15
// ‘num’表示要寫的數字,只能為0--9
// 出口:無
//===================================================
void WriteNum(uint row,uint col,uint num)
{
if (row == 1) row = 0x80 + col;
else row = 0xC0 + col;
writecom(row);
if (num<=0 | num>9) num =0x30;
else num = 0x30 + num;
PORTA|=(1<<RS);
s_ms(500);
PORTA&=~(1<<RW);
s_ms(500);
PORTB = num;
s_ms(500);
PORTA|=(1<<EN);
s_ms(500);
PORTA&=~(1<<EN);
s_ms(500);
}
//================================================================
// 描述:在任意位置寫任意多個字符
// 入口:’row‘要寫的字符所在的行,只能為1或2;
// ‘col’要寫的字符所在的列,只能為0---15
// ‘num’要寫字符的個數
// ‘pbuffer’要寫字符的首地址
//==================================================================
void WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
uchar i,t;
if (row == 1) row = 0x80 + col;
else row = 0xC0 + col;
writecom(row);
//if (num<=0 | num>9) num =0x30;
//else num = 0x30 + num;
PORTA|=(1<<RS);
s_ms(500);
PORTA&=~(1<<RW);
s_ms(500);
for(i=num;i!=0;i--)
{
t = *pBuffer;
s_ms(500);
PORTDB = t;
s_ms(500);
PORTA|=(1<<EN);
s_ms(500);
PORTA&=~(1<<EN);
s_ms(500);
pBuffer++;
}
}
void main()
{
DDRA=0xff;
PORTA=0xff;
DDRD=0xff;
PORTD=0xff;
s_ms(5000); //延時
LcdInit(); //1602初始化
WriteChar(1,1,13,wz); //顯示第一行
WriteChar(2,1,16,gd); //顯示第二行
} |