avr单片机+12864液晶动画显示
下面将源代码贴上:
/*
* _12864.c
*
* Created: 2011/7/30 23:16:04
* Author: YIN
*/
#include
#include
// #include "QQ.h"
// #include "chiken.h"
#include "TSJ.h"
#define uint unsigned int
#define uchar unsigned char
#define LCD_RS_0 PORTB&=(~(1
#define LCD_DATA_DIR DDRA
#define LCD_CONTROL_DIR DDRB
;uchar Busy_Flag=1;
/*点阵汉字坐标代码,便于根据汉字坐标求出地址*/
uchar Char_Location[4][8]=
{
{0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87},//第一行汉字位置
{0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97},//第二行汉字位置
{0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f},//第三行汉字位置
{0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f},//第四行汉字位置
};
uchar X_Pos[]={0,1,2,3,4,5,4,3,2,1,0};//图像显示的坐标,该坐标基于LCD液晶的图形显示说明部分
uchar Y_Pos[]={0,15,5,16,3,20,5,24,8,15,7};
void delay0()//短暂延时
{
uint i;
i=7;
while(i--);
}
void DelayMS(uint MS)//延时毫秒(自己估算的,不准确)
{
uint i,j;
for (i=0;i
}
// uint LCD_Busy()//忙标志判断,如果lcd速度较快可不用判忙
// {
// LCD_DATA_DIR=0x00;
// LCD_EN_1;
// LCD_RS_0;
// LCD_RW_1;
// Busy_Flag=PINA&0x80;
// LCD_EN_0;
// return Busy_Flag;
// }
void LCD_Write_Dat(uchar Data)//写入数据
{
// while(LCD_Busy());
LCD_DATA_DIR=0xff;
LCD_RS_1;
LCD_RW_0;
LCD_EN_1;
LCD_DATA_PORT=Data;
LCD_EN_0;
delay0();
}
void LCD_Write_Com(uchar Com)//向12864写入命令
{
// while(LCD_Busy());
LCD_DATA_DIR=0xff;
LCD_RS_0;
LCD_RW_0;
LCD_EN_1;
LCD_DATA_PORT=Com;
LCD_EN_0;
delay0();
}
void LCD_Write_Chinese(uchar x,uchar y,char *Chn) //从指定行、列开始写入文字
{
LCD_Write_Com(Char_Location[x-1][y-1]);//写入首地址
DelayMS(1);
while(*Chn>0)
{
LCD_Write_Dat(*Chn);//写入文字
Chn++;
}
}
void DisplayImage(uchar *PIC) //绘制128*64的图片
{
uint x=0,j=0,i=0,y=0;
uint tmp0=0;
LCD_Write_Com(0x34);
for(i=0;i<2;i++)//分两屏,上半屏和下半屏,每次写入一个半屏,2次完成整屏
{
for(y=0;y<32;y++) //32行,因此,y地址为0-31
{
LCD_Write_Com(0x80+y);//写入y地址
LCD_Write_Com(0x80+x);//x地址,x地址会自动加1,因此只给出初始地址
for(j=0;j<16;j++)
LCD_Write_Dat(~pgm_read_byte(&PIC[tmp0+j])); //读取数据写入LCD
tmp0+=16;//tmp0自动加16,下次操作时读取下一行的数据
}
x=8;
}
LCD_Write_Com(0x36);//扩充功能设定
LCD_Write_Com(0x30);//返回基本功能
}
void Draw_Pic(uchar Wide,uchar Height,uchar PX,uchar PY,uchar *PIC) //绘制Wide*Height的图片,宽度只能是8的倍数,否则出错
{
unsigned char j=0,y=0,flag=0,Height1=0;
unsigned int tmp0=0;
Height1=Height;
if(Height>32)
{
flag=1;
Height1=32;
}
LCD_Write_Com(0x34);
for(y=PY;y
LCD_Write_Com((0x80+y));//y地址
LCD_Write_Com((0x80+PX));//x地址,x地址会自动加1,因此只给出初始地址
for(j=0;j<(Wide/8);j++)
LCD_Write_Dat(~pgm_read_byte(&PIC[tmp0+j])); //读取数据写入LCD
tmp0+=(Wide/8);
}
if (flag=1)
{
for(y=0;y<(Height-32+PY);y++) //32行,因此,y地址为0-31
{
LCD_Write_Com((0x80+y));//y地址
LCD_Write_Com((0x88+PX));//x地址,x地址会自动加1,因此只给出初始地址
for(j=0;j<(Wide/8);j++)
LCD_Write_Dat(~pgm_read_byte(&PIC[tmp0+j])); //读取数据写入LCD
tmp0+=(Wide/8);
}
flag=0;
}
LCD_Write_Com(0x36);//扩充功能设定
LCD_Write_Com(0x30);//返回基本功能
}
void Clear_Draw()
{
unsigned char x=0,j,i,y;
unsigned int tmp0=0;
LCD_Write_Com(0x34);
for(i=0;i<2;i++)//分两屏,上半屏和下半屏
{
for(y=0;y<32;y++) //32行,因此,y地址为0-31
{
LCD_Write_Com((0x80+y));//y地址
LCD_Write_Com((0x80+x));//x地址,x地址会自动加1,因此只给出初始地址
for(j=0;j<16;j++)
LCD_Write_Dat(0x00);//清屏数据写入LCD
tmp0+=16;
}
x=8;
}
LCD_Write_Com(0x36);//扩充功能设定
LCD_Write_Com(0x30);//返回基本功能
}
void LCD_Init()//初始化函数
{
DDRA=0XFF; //LED IO口设为输出
DDRC=0XFF; //数码管段选设为输出
DDRF |=0X0E; //LED及数码管锁存IO口设为输出
PORTF|=0X0E;
PORTA=0XFF;
PORTC=0XFF;
PORTF&=0xF1; //锁存数据关闭数码管及LED
DDRB |=0X10; //PB4设为输出
PORTB|=0X10; //关闭PB4外接的LED
LCD_PSB;//串行方式传输
LCD_CONTROL_DIR=0xff;
LCD_Write_Com(0x30);//3次初始化,进入基本模式
DelayMS(1);
LCD_Write_Com(0x30);
DelayMS(1);
LCD_Write_Com(0x30);
DelayMS(1);
LCD_Write_Com(0x0c);//游标关闭
DelayMS(1);
LCD_Write_Com(0x01);//清屏
DelayMS(1);
}
avr单片机12864液晶动画显 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)