您的位置:首页 > 其它

基于ATmega64的液晶12864学习心得(一)

2015-09-02 20:45 267 查看
声明:该程序是基于ATmega64单片机的,采用7.3728Mhz晶振,并采用串行传输的方式。

PC5 = CS; PC6 = SID; PC7 = SCLK;



上图是液晶12864的时序图。

#include <avr/io.h>
#include <util/delay.h>

//位操作宏定义
#define SETB(bit) (1 << (bit))
#define CLRB(bit) ~(1 << (bit))
//LCD_PIN管脚定义
#define LCD_CS_H        PORTC |= SETB(PIN5)             //CS拉高
#define LCD_CS_L        PORTC &= CLRB(PIN5)             //CS拉低

#define LCD_SID_H       PORTC |= SETB(PIN6)
#define LCD_SID_L       PORTC &= CLRB(PIN6)

#define LCD_SCLK_H      PORTC |= SETB(PIN7)
#define LCD_SCLK_L      PORTC &= CLRB(PIN7)
//____________________________________________
//初始化io端口
void initPort()
{
DDRC = 0xE0;            //端口c,设置为输出
PORTC = 0xff;           //输出为高电平
}

//向LCD发送一个8位的命令
void LCD_Sendbyte_command(unsigned char command)
{
unsigned char i,LCD_COMMAND = 0xf8;     //i用于循环计数,LCD_COMMAND是LCD发送命令(1111-1000)
unsigned char LCD_COMMAND_High = (command & 0xF0);      //数据高四位
unsigned char LCD_COMMAND_Low = ((command << 4) & 0xF0);    //数据低四位

LCD_CS_H;                   //LCD使能
for(i = 0; i < 8; i++)      //循环发送八位数据——液晶控制
{
LCD_SCLK_L;
if(LCD_COMMAND & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);
LCD_COMMAND <<= 1;
}
for(i = 0; i < 8; i++)      //循环发送命令高四位
{
LCD_SCLK_L;
if(LCD_COMMAND_High & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);

LCD_COMMAND_High <<= 1;
}
for(i = 0; i < 8; i++)      //循环发送命令低四位
{
LCD_SCLK_L;
if(LCD_COMMAND_Low & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);

LCD_COMMAND_Low <<= 1;
}
LCD_CS_L;                   //LCD关闭
}

//向LCD发送一个8位的数据
void LCD_Sendbyte_data(unsigned char data)
{
unsigned char i, LCD_DATA = 0xfa;               //i用于循环计数,LCD_DATA是发送数据的指令(1111-1010)
unsigned char LCD_DATA_High = data & 0xf0;      //发送的数据的高四位
unsigned char LCD_DATA_Low = ((data << 4) & 0xf0);  //发送数据的低四位

LCD_CS_H;                   //LCD使能
for(i = 0; i < 8; i++)      //循环发送八位发送数据命令
{
LCD_SCLK_L;
if(LCD_DATA & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);
LCD_DATA <<= 1;
}
for(i = 0; i < 8; i++)      //循环发送数据高四位
{
LCD_SCLK_L;
if(LCD_DATA_High & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);
LCD_DATA_High <<= 1;
}
for(i = 0; i < 8; i++)      //循环发送数据低四位
{
LCD_SCLK_L;
if(LCD_DATA_Low & 0x80)
LCD_SID_H;
else
LCD_SID_L;
LCD_SCLK_H;
_delay_us(2);
LCD_DATA_Low <<= 1;
}
LCD_CS_L;                   //关闭LCD
}

//初始化LCD
void Init_LCD()
{
LCD_Sendbyte_command(0x02);     //DDRAM位址计数器设为00h
LCD_Sendbyte_command(0x0c);     //打开LCD整体显示;关闭游标;关闭游标位置反白
LCD_Sendbyte_command(0x01);     //清除显示,DDRAM到20h
LCD_Sendbyte_command(0x80);     //设定DDRAM地址到位置计数器
LCD_Sendbyte_command(0x40);     //设定CGRAM到位址计数器ac
}

int main()
{
unsigned char i;

initPort();     //初始化端口
Init_LCD();     //舒适化LCD

for(i = 0; i < 3; i++)
{
LCD_Sendbyte_command(0x80);        //液晶显示的位置
LCD_Sendbyte_data('H');          //显示Hello World!
LCD_Sendbyte_data('e');
LCD_Sendbyte_data('l');
LCD_Sendbyte_data('l');
LCD_Sendbyte_data('o');
LCD_Sendbyte_data(' ');
LCD_Sendbyte_data('W');
LCD_Sendbyte_data('o');
LCD_Sendbyte_data('r');
LCD_Sendbyte_data('l');
LCD_Sendbyte_data('d');
LCD_Sendbyte_data('!');
}
}


以上便是本菜的程序。虽然是个小程序但过程中也发现了BUG,请各位博友多多指教啊。

Q:

1.当液晶显示没有for循环(循环一次)时,液晶就什么都不显示?

2.当液晶显示循环两次时,只显示“llo World!”?

3.当把液晶显示地址设为0x90即第二行,循环大于等于3,


A:

1.只有循环大于等于3时显示才正常,但在0x80处会有BUG,不知为何?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: