AVR的12864程序 画任意图像和线段 显示字符和汉字 还有uint_8
/************************************************************************************************************************************************/
//12864液晶一定要注意是工作在什么指令集模式还有AC工作在什么模式
//***********************************************************************
#ifndef _lcd12864_test_h
#define _lcd12864_test_h
#define LOW 0
#define HIGH1
#define FIRST_ADDR0 //定义字符/汉字显示起始位置
//12864相关初始化指令
#define CLEAR_SCREEN 0x01//清屏指令:清屏且AC值为00H
#define AC_INIT 0x02//将AC设置为00H。且游标移到原点位置
#define CURSE_ADD 0x06//设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
#define FUN_MODE 0x30//工作模式:8位基本指令集
#define DISPLAY_ON 0x0c//显示开,显示游标,且游标位置反白
#define DISPLAY_OFF 0x08//显示关
#define CURSE_DIR 0x14//游标向右移动:AC=AC+1
#define SET_CG_AC 0x40//设置AC,范围为:00H~3FH
#define SET_DD_AC 0x80
#define FUN_MODEK 0x36//工作模式:8位扩展指令集
#define X1address 0x80 //12864上半屏X轴起始地址
#define X2address 0x88 //12864下半屏X轴起始地址
#define Yaddress 0x80 //Y轴起始地址
//***********************************************************************
// 端口定义
//***********************************************************************
#define RS_PORT_DDRDDRA
#define RS_PORT_PORT PORTA
#define RS_PORT 4
#define RW_PORT_DDR DDRA
#define RW_PORT_PORTPORTA
#define RW_PORT 5
#define EN_PORT_DDR DDRA
#define EN_PORT_PORT PORTA
#define EN_PORT 6
#define PSB_PORT_DDR DDRA
#define PSB_PORT_PORT PORTA
#define PSB_PORT 0
#define RET_PORT_DDR DDRA
#define RET_PORT_PORT PORTA
#define RET_PORT 1
#define DATA_PORT_DDR DDRB
#define DATA_PORT_PIN PINB
#define DATA_PORT PORTB
/*******************************************************************************/
#define RS_CLR RS_PORT_PORT &= ~(1 << RS_PORT) //RS置低
#define RS_SET RS_PORT_PORT |= (1 << RS_PORT) //RS置高
#define RW_CLR RW_PORT_PORT &= ~(1 << RW_PORT) //RW置低
#define RW_SET RW_PORT_PORT |= (1 << RW_PORT) //RW置高
#define EN_CLR EN_PORT_PORT &= ~(1 << EN_PORT) //E置低
#define EN_SET EN_PORT_PORT |= (1 << EN_PORT) //E置高
//***********************************************************************
// 函数声明
//***********************************************************************
void LCD_init(void);//液晶初始化
void wait_BF(void); //等待忙信号
void LCD_write_com(unsigned char com); //写命令
void LCD_write_data(unsigned char data);//写数据
void LCD_clear(void);//清屏基本指令集
void SetPos(unsigned char x, unsigned chary);
void DisplayListChar( unsigned char x, unsigned char y ,unsigned char *hz);//显示字库中的字符
void DisplayOneChar(unsigned char x, unsigned char y, unsigned char data );
void Display_8int(unsigned char x, unsigned char y, unsigned char data );
void Display_photo1(unsigned char *img1) ;//写上半屏的数据
void Display_photo2(unsigned char *img2);//写下半屏的数据
unsigned charLCD_read_char(void );//在写数据时先将CGRAM中的数据读出来
void Clear_CGRAM(void );//清空CGRAM
void Draw_point(unsigned char x, unsigned char y);//画点
void Draw_Horizontal_line(unsigned char X0, unsigned char X1, unsigned char Y);//画横线
void Draw_Vertical_line(unsigned char X, unsigned char Y0, unsigned char Y1);//画竖线
void Draw_line( unsigned char StartX, unsigned char StartY, unsigned char EndX, unsigned char EndY );//画任意线
#endif
/************************************************************************
************************************************************************/
//12864液晶一定要注意是工作在什么指令集模式还有AC工作在什么模式
//***********************************************************************
// 包含文件
//***********************************************************************
#include "lcd12864_test.h"
#include"config.h"
//***********************************************************************
//函数名称:等待忙信号
//入口参数:无
//返回参数:无
//***********************************************************************
void wait_BF(void)
{
DATA_PORT = 0Xff;
DATA_PORT_DDR = 0X00;
RS_CLR;
RW_SET;
while(1)
{
EN_SET;
_delay_us(20);
if((DATA_PORT_PIN&(1<<7)) == 0)
break;
EN_CLR;
}
DATA_PORT = 0X00;
DATA_PORT_DDR = 0Xff;
return ;
}
//***********************************************************************
// 显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com)
{
wait_BF();
RS_CLR;
RW_CLR;
EN_SET;
DATA_PORT = com;
_delay_us(20);
EN_CLR;
}
//***********************************************************************
// 显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char data)
{
wait_BF();
RS_SET;
RW_CLR;
EN_SET;
DATA_PORT = data;
_delay_us(20);
EN_CLR;
}
//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD_clear(void)
{
wait_BF();
LCD_write_com(0x01);
}
void SetPos(unsigned char x, unsigned chary)
{
LCD_write_com(0x34);//绘图关闭
LCD_write_com(0X30);//回到基本指令集 并且关闭绘图显示
switch( y )
{
case 0: LCD_write_com(0x80 + x);break;
case 1: LCD_write_com(0x90 + x);break;
case 2: LCD_write_com(0x88 + x);break;
case 3: LCD_write_com(0x98 + x);break;
}
}
//***********************************************************************
//函数名称:显示单个ASCII字符
//入口参数:无
//返回参数:无
//***********************************************************************
void DisplayOneChar( unsigned char x, unsigned char y ,unsigned char data)//显示字库中的字符
{
SetPos(x , y);
LCD_write_data(data);
}
//***********************************************************************
//函数名称:显示8位整型数值
//入口参数:无
//返回参数:无
//***********************************************************************
void Display_8int( unsigned char x, unsigned char y ,unsigned char data)//显示字库中的字符
{
unsigned chara, b, c ;
a = data/100;
b = data%100/10;
c = data%10;
SetPos(x , y);
LCD_write_data(a +48);
LCD_write_data(b +48);
SetPos(x+ 1 , y);
LCD_write_data(c +48);
}
//***********************************************************************
//函数名称:Display显示CGROM里的汉字
//入口参数:无
//返回参数:无
//***********************************************************************
void DisplayListChar( unsigned char x, unsigned char y ,unsigned char *hz)//显示字库中的字符
{
SetPos(x , y);
while(*hz != '\0')
{
LCD_write_data(*hz);
hz++;
}
}
//***********************************************************************
// 显示屏初始化函数
//***********************************************************************
void LCD_init(void)
{
RS_PORT_DDR |= (1<<RS_PORT);
RW_PORT_DDR |= (1<<RW_PORT);
EN_PORT_DDR |= (1<<EN_PORT);
PSB_PORT_DDR |= (1<<PSB_PORT);
RET_PORT_DDR |= (1<<RET_PORT);
PSB_PORT_PORT |= (1<<PSB_PORT);//置位后 并行输出
RET_PORT_PORT |= (1<<RET_PORT);//低电平复位所以置高
DATA_PORT_DDR = 0XFF;
DATA_PORT = 0X00;
LCD_write_com(FUN_MODE); //显示模式设置
LCD_write_com(DISPLAY_ON); //显示开
LCD_write_com(CLEAR_SCREEN); //清屏
}
//****************************************************************
//函数名称:Display_photo(uchar *hz)显示自定义图形,分上下半屏来写
//上屏
//****************************************************************
void Display_photo1(uchar *img1) //写上半屏图形数据函数
{
int i,j;
LCD_write_com(FUN_MODEK); //扩展指令,开绘图显示
for(i=0;i<32;i++) //上半屏32行
{
LCD_write_com(Yaddress+i); //先写垂直地址,即Y地址,不能自动加一
LCD_write_com(X1address); //再写水平地址,即X地址
for(j=0;j<8;j++) //连续写入2个字节的数据,一共8次,为一行,即16*8位数据
{
LCD_write_data(img1);
//这个延时是必须的,因为没有对液晶进行判忙操作,所以进行延时
LCD_write_data(img1);
}
}
}
//****************************************************************
//函数名称:Display_photo(uchar *hz)显示自定义图形,分上下半屏来写
//下屏
//****************************************************************
void Display_photo2(uchar *img2) //写下半屏图形数据
{
int i,j;
LCD_write_com(FUN_MODEK); //扩展指令,开绘图显示
for(i=0;i<32;i++) //下半屏32行
{
LCD_write_com(Yaddress+i); //先写垂直地址,即Y地址,不能自动加一
LCD_write_com(X2address); //再写水平地址,即X地址
for(j=0;j<8;j++) //连续写入2个字节的数据,一共8次,为一行,即16*8位数据
{
LCD_write_data(img2);
LCD_write_data(img2);
}
}
}
//****************************************************************
//从CGRAM中读取该字节的数据
//wr_com设定地址设定到哪里时就显示哪里的数据
//读取RAM中值的时候不属于基本指令集和扩展指令集中
//****************************************************************
unsigned charLCD_read_char()
{
unsigned char temp;
DATA_PORT = 0Xff;
DATA_PORT_DDR = 0X00;
RS_SET;
RW_SET;
EN_CLR;
_delay_us(20);
EN_SET;
_delay_us(20);
temp = DATA_PORT_PIN ;
EN_CLR;
DATA_PORT = 0X00;
DATA_PORT_DDR = 0Xff;
return temp;
}
void Clear_CGRAM()
{
//将CGRAM中清零
int m;
unsigned char RamVar_1;
for(m=0;m<512;m++) //从flash中读取上半屏数据
{
RamVar_1 = 0;
}
Display_photo1(RamVar_1); //显示上半屏数据
for(m=0;m<512;m++) //从flash中读取下半屏数据
{
RamVar_1 = 0;
}
Display_photo2(RamVar_1); //显示下半屏数据
}
//****************************************************************
//函数名称:画点函数 在指定的位置画一个像素点
//下屏
//****************************************************************
void Draw_point(unsigned char x, unsigned char y)
{
uchar x_byte,x_bit;
uchar y_byte,y_bit;
uchar tmph,tmpl;
x &= 0x7f;
y &= 0x3f;
x_byte = x/16;
//x_bit =x & 0x0f;
x_bit =x%16;
y_byte = y/32;
y_bit = y%32;
//LCD_write_com(0x34);//扩展指令集
//LCD_write_com(0x34);//绘图关闭
//LCD_write_com(0x34);//如果老关显示时屏幕会颤动
//LCD_write_com(0x36);//干脆就开着显示
LCD_write_com( 0x80 +y_bit);
LCD_write_com(0x80 +x_byte + 8*y_byte);
LCD_read_char();
tmph = LCD_read_char();
tmpl = LCD_read_char();
LCD_write_com( 0x80 +y_bit);
//延时必须加上 否则报出错啊亲
LCD_write_com(0x80 +x_byte + 8*y_byte);
if(x_bit<8)
{
LCD_write_data( tmph|(0x01<<(7 - x_bit)));
LCD_write_data(tmpl);
}
else
{
LCD_write_data(tmph);
LCD_write_data(tmpl | (0x01<<(15 - x_bit)));
}
//LCD_write_com(0X36);//开绘图显示
//LCD_write_com(0X30);//回到基本指令集
return;
}
//****************************************************************
//函数名称:画水平线函数
//下屏
//****************************************************************
void Draw_Horizontal_line(unsigned char X0, unsigned char X1, unsigned char Y)//画横线
{
LCD_write_com(0x36);//干脆就开着显示
unsigned char Temp ;
if( X0 > X1 )
{
Temp = X1 ;
X1= X0 ;
X0= Temp ;
}
for( ; X0 <= X1 ; X0++ )
Draw_point( X0, Y ) ;
}
//****************************************************************
//函数名称:画竖直线函数 用于垂线画
//下屏
//****************************************************************
void Draw_Vertical_line(unsigned char X, unsigned char Y0, unsigned char Y1)//画竖线
{
LCD_write_com(0x36);//干脆就开着显示
unsigned char Temp ;
if( Y0 > Y1 )
{
Temp = Y1 ;
Y1= Y0 ;
Y0= Temp ;
}
for(; Y0 <= Y1 ; Y0++)
Draw_point( X, Y0 ) ;
}
//****************************************************************
//函数名称:画任意线函数输入线段的起始位置和终止位置即可。。
//下屏
//****************************************************************
void Draw_line( unsigned char StartX, unsigned char StartY, unsigned char EndX, unsigned char EndY )
{
LCD_write_com(0x36);//干脆就开着显示
int t, distance; /*根据屏幕大小改变变量类型(如改为int型)*/
int x = 0 , y = 0 , delta_x, delta_y ;
char incx, incy ;
delta_x = EndX - StartX ;
delta_y = EndY - StartY ;
if( delta_x > 0 )
{
incx = 1;
}
else if( delta_x == 0 )
{
Draw_Vertical_line( StartX, StartY, EndY ) ;
return ;
}
else
{
incx = -1 ;
}
if( delta_y > 0 )
{
incy = 1 ;
}
else if(delta_y == 0 )
{
Draw_Horizontal_line( StartX, EndX, StartY ) ;
return ;
}
else
{
incy = -1 ;
}
if(delta_x < 0) //delta_x = ABS( delta_x );
delta_x = -delta_x;
if(delta_y < 0) //delta_y = ABS( delta_y );
delta_y = -delta_x;
if( delta_x > delta_y )
{
distance = delta_x ;
}
else
{
distance = delta_y ;
}
Draw_point( StartX, StartY ) ;
/* Draw Line*/
for( t = 0 ; t <= distance+1; t++ )
{
Draw_point( StartX, StartY ) ;
x += delta_x ;
y += delta_y ;
if( x > distance )
{
x -= distance ;
StartX += incx ;
}
if( y > distance )
{
y -= distance ;
StartY += incy ;
}
}
} 这么多啊,头大。 {:lol:}谢谢。。。。mark 馬克帕克 学习了,{:smile:} 谢谢!学习了。{:smile:} {:lol:}很好用啊,谢谢楼主!!~ mark 下{:biggrin:} 学习了!亲测可用! 收了收了,谢谢楼主!
页:
[1]