/*****************************************************************
* 函数库说明:ATMEGA8 NOKIA 12864LCD 驱动
* 版本: v1.02
* 修改: 庞辉 芜湖联大飞思卡尔工作室
* 修改日期: 2011年08月08日
*
* 说明: ST7920(带字库)
* AVR只可以运行在4Mhz晶振下,8Mhz就已经无法显示
atmega8的PB6和PB7为晶振引脚,使用外部晶振时这两个口不能做IO口用
* 版本更新: 详见readme.txt
*
* 20110805 V1.00
*
******************************************************************
*注意: RS/CS PC0
* RW/SID PC1
* E/SCLK PC2
* PSB PC3
* RST PC4
* DATA PORTB
******************************************************************/
#include "includes.h"
int main(void)
{
//12864初始化
LCD_Init();
//清屏,全部填0
LCD12864_DisplayCLR();
while(1)
{
//汉字显示
LCD_Pos(1,1);
// LCD_Write_String(dis1);
LCD_Write_String("芜湖联大");
Delay_MS(5);
LCD_Pos(2,1);
// LCD_Write_String(dis2);
LCD_Write_String("飞思卡尔工作室");
Delay_MS(5);
LCD_Pos(3,1);
// LCD_Write_String(dis3);
LCD_Write_String("20110808");
Delay_MS(5);
LCD_Pos(4,1);
// LCD_Write_String(dis4);
LCD_Write_String("庞辉");
Delay_MS(500);
}
return 0;
}
view plainprint?
#include "includes.h"
/***********************************************************
** 名称:void Delay_MS(uint16 xms)
** 功能:LCD12864驱动类延时函数
** 入口参数:xms 需要延时的毫秒数
** 出口参数:无
** 使用说明:无
**********************************************************/
void Delay_MS(uint16 xms)
{
uint16 i,j;
for(j=0;i<xms;j++)
{
for(i=0;i<1100;i++)
{
;
}
}
}
/***********************************************************
** 名称:uint8 LCD_Busy(void)
** 功能:LCD忙检测函数
** 入口参数:无
** 出口参数:result 状态值
** 使用说明:无
**********************************************************/
uint8 LCD_Busy(void)
{
uint8 result = 0;
uint8 temp = 0;
Part = 0xff;
//
DDR_DATA = 0x00;
LCD_RS=0;
LCD_RW=1;
LCD_EN= 1;
temp = Part_Pin;
result=(temp & 0x80);
LCD_EN=0;
//
DDR_DATA = 0xff;
return result;
}
/***********************************************************
** 名称:void LCD_Write_Cmd(uint8 com)
** 功能:液晶写一个命令函数
** 入口参数:com 写命令值
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD_Write_Cmd(uint8 com)
{
while(LCD_Busy());
LCD_RS=0; //选择指令寄存器
LCD_RW=0; //写
LCD_EN=0;
Part=com; //指令值赋给P0口
//这句延迟不能丢,不然有花屏
Delay_MS(1);
LCD_EN=1;
//Delay_MS(1);
LCD_EN=0;
}
/***********************************************************
** 名称:uint8 LCD_Read_Dat(void)
** 功能:液晶读一个字符数据函数
** 入口参数:无
** 出口参数:ReturnValue 读字符数据
** 使用说明:无
**********************************************************/
uint8 LCD_Read_Dat(void)
{
uint8 ReturnValue;
while(LCD_Busy());
Part = 0xff;
//
DDR_DATA = 0x00;
LCD_RS = 1;
LCD_RW = 1;
LCD_EN = 1;
//Delay_MS(1);
ReturnValue = Part_Pin;
LCD_EN = 0;
//
DDR_DATA = 0xff;
//Delay_MS(1);
return ReturnValue;
}
/***********************************************************
** 名称:void LCD_Write_Dat(uint8 date)
** 功能:液晶写一个字符数据函数
** 入口参数:date 写字符数据
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD_Write_Dat(uint8 date)
{
while(LCD_Busy());
LCD_RS=1; //选择数据寄存器
LCD_RW=0; //写
LCD_EN=0;
Part=date; //数据值赋给P0口
//Delay_MS(1);
LCD_EN=1;
//Delay_MS(1);
LCD_EN=0;
}
/***********************************************************
** 名称:void LCD_Write_String(uint8 *str)
** 功能:液晶写一个字符串函数
** 入口参数:str 写字符串
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD_Write_String(uint8 *str)
{
while(*str!='\0') //未结束
{
LCD_Write_Dat(*str++);
//Delay_MS(1);
}
}
/***********************************************************
** 名称:void LCD_Pos(uint8 x,uint8 y)
** 功能:液晶显示位置函数,从第X行的第Y位置开始显示
** 入口参数:x 第x行
** y 第y列
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD_Pos(uint8 x,uint8 y)
{
uint8 pos;
if(x==1) //第一行
{
x=0x80;
}
else if(x==2) //第二行
{
x=0x90;
}
else if(x==3) //第三行
{
x=0x88;
}
else if(x==4) //第四行
{
x=0x98;
}
pos=x+y-1; //首地址为0X80
LCD_Write_Cmd(pos);
}
/***********************************************************
** 名称:void LCD_Init(void)
** 功能:液晶初始化函数
** 入口参数:无
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD_Init(void)
{
DDR_RS = 1;
DDR_RW = 1;
DDR_EN = 1;
DDR_PSB = 1;
DDR_RST = 1;
DDR_DATA = 0xff;
LCD_PSB=1; //并行方式
LCD_RST=1; //不复位
LCD_Write_Cmd(0x30);
Delay_MS(5);
LCD_Write_Cmd(0x0c); //开显示,不显示光标
Delay_MS(5);
LCD_Write_Cmd(0x06); //写一个字符后地址指针自动加1
Delay_MS(5);
LCD_Write_Cmd(0x01); //清屏
Delay_MS(5);
}
/**********************************************************
** 名称:GUI_Point(uint8 y,uint8 x,unsigned colour)
** 功能:在指定位置上画点。
** 入口参数:x 指定点所在行的位置
** y 指定点所在列的位置
** color 显示颜色(对于黑白色LCD12864,为0时灭,为1时显示)
** 出口参数:无
** 使用说明:无
**********************************************************/
void GUI_Point(uint8 x,uint8 y,uint8 color)
{
uint8 Row , Tier , Tier_bit ;
uint8 ReadOldH, ReadOldL ;
LCD_Write_Cmd( 0x34 ) ;
//打开绘图
LCD_Write_Cmd(0x36);
Tier = x >> 4 ;
Tier_bit = x & 0x0f;
//上半屏
if( y < 32 )
{
Row = y ;
}
//下半屏
else
{
Row = y - 32 ;
Tier += 8 ;
}
//垂直坐标
LCD_Write_Cmd( Row + 0x80 );
//水平坐标
LCD_Write_Cmd( Tier + 0x80 );
LCD_Read_Dat() ;
ReadOldH = LCD_Read_Dat();
ReadOldL = LCD_Read_Dat();
LCD_Write_Cmd( Row + 0x80 );
LCD_Write_Cmd( Tier + 0x80 );
if( Tier_bit < 8 )
{
switch( color)
{
case 0 : ReadOldH &=( ~( 0x01 << ( 7 - Tier_bit ))); break ;
case 1 : ReadOldH |= ( 0x01 << ( 7 - Tier_bit )); break ;
case 2 : ReadOldH ^= ( 0x01 << ( 7 - Tier_bit )); break ;
default : break;
}
LCD_Write_Dat( ReadOldH );
LCD_Write_Dat( ReadOldL );
}
else
{
switch(color)
{
case 0 : ReadOldL &= (~( 0x01 << ( 15 - Tier_bit ))) ; break ;
case 1 : ReadOldL |= ( 0x01 << ( 15 - Tier_bit )) ; break ;
case 2 : ReadOldL ^= ( 0x01 << ( 15 - Tier_bit )) ; break ;
default : break ;
}
LCD_Write_Dat( ReadOldH );
LCD_Write_Dat( ReadOldL );
}
LCD_Write_Cmd( 0x30 );
}
/***********************************************************
** 名称:GUI_Line(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour)
** 功能:在指定位置上画线。
** 入口参数:x0 指定线起点所在行的位置
** y0 指定线起点所在列的位置
** x1 指定线终点所在行的位置
** y1 指定线终点所在列的位置
** color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
** 出口参数:无
** 使用说明:无
**********************************************************/
void GUI_Line(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour)
{
int temp;
int dx,dy; //定义起点到终点的横、纵坐标增加值
int s1,s2,status,i;
int Dx,Dy,sub;
dx = x1 - x0;
if(dx >= 0) //X的方向是增加的
s1 = 1;
else //X的方向是降低的
s1 = -1;
dy = y1 - y0; //判断Y的方向是增加还是降到的
if(dy >= 0)
s2 = 1;
else
s2 =- 1;
Dx = _abs(x1-x0); //计算横、纵标志增加值的绝对值
Dy = _abs(y1-y0);
if(Dy > Dx)
{ //以45度角为分界线,靠进Y轴是status=1,靠近X轴是status=0
temp = Dx;
Dx = Dy;
Dy = temp;
status = 1;
}
else
status = 0;
/*********Bresenham算法画任意两点间的直线********/
sub = Dy + Dy - Dx; //第1次判断下个点的位置
for(i = 0;i < Dx;i ++)
{
GUI_Point(x0,y0,colour); //画点
if(sub >= 0)
{
if(status == 1) //在靠近Y轴区,x值加1
x0 += s1;
else //在靠近X轴区,y值加1
y0 += s2;
sub -= (Dx + Dx); //判断下下个点的位置
}
if(status == 1)
y0 += s2;
else
x0 += s1;
sub += Dy + Dy;
}
}
/***********************************************************
** 名称:void LCD12864_DisplayCLR(void)
** 功能:清屏
** 入口参数:无
** 出口参数:无
** 使用说明:无
**********************************************************/
void LCD12864_DisplayCLR(void)
{
uint8 i, j, k ;
while(LCD_Busy());
LCD_Write_Cmd(0x34);
LCD_Write_Cmd(0x36);
for( i = 0 ; i < 2 ; i++ )//分上下两屏写
{
for( j = 0 ; j < 32 ; j++ )
{
while(LCD_Busy());
LCD_Write_Cmd( 0x80 + j ) ;//写Y坐标
Delay_MS(1);
if( i == 0 ) //写X坐标
{
LCD_Write_Cmd( 0x80 ) ;
Delay_MS(1);
}
else
{
LCD_Write_Cmd( 0x88 ) ;
Delay_MS(1);
}
for( k = 0 ; k < 16 ; k++ ) //写一整行数据
{
while(LCD_Busy());
LCD_Write_Dat(0x00) ;
Delay_MS(1);
}
}
}
LCD_Write_Cmd( 0x30 ) ;
}
/****************************************************************************
** 名称:plotC(int x,int y,int xc,int yc,uint8 colour)
** 功能:八分点画圆函数
** 入口参数:x 指定线起点所在行的位置
** y 指定线起点所在列的位置
** color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
** 出口参数:无
** 使用说明:无
****************************************************************************/
void plotC(int x,int y,int xc,int yc,uint8 colour)
{
GUI_Point(xc+x,yc+y,colour);
GUI_Point(xc+x,yc-y,colour);
GUI_Point(xc-x,yc+y,colour);
GUI_Point(xc-x,yc-y,colour);
GUI_Point(xc+y,yc+x,colour);
GUI_Point(xc+y,yc-x,colour);
GUI_Point(xc-y,yc+x,colour);
GUI_Point(xc-y,yc-x,colour);
}
/****************************************************************************
** 名称:GUI_Circle(int xc,int yc,int r,uint8 colour)
** 功能:画圆
** 入口参数:xc 圆心的行坐标
** yc 圆心的列坐标
** r 半径
** color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
** 出口参数:无
** 使用说明:无
****************************************************************************/
void GUI_Circle(int xc,int yc,int r,uint8 colour)
{
int x,y,d;
y = r;
d = 3 - (r + r);
x = 0;
while(x <= y)
{
plotC(x,y,xc,yc,colour);
if(d < 0)
d += (x + x + x + x) + 6;
else
{
d+=((x - y) + (x - y) + (x - y) + (x - y)) + 10;
y = y - 1;
}
x = x + 1;
}
}
/****************************************************************************
** 名称:GUI_Full(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour)
** 功能:用绘图的方法填充一个矩形
** 入口参数:x0 起始点横坐标
** y0 起始点纵坐标
** x1 终止点横坐标
** y1 终止点纵坐标
** color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
** 出口参数:无
** 使用说明:无
****************************************************************************/
void GUI_Full(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour)
{
uint8 i,j;
for(j = y0;j <= y1;j ++)
for(i = x0;i <= x1;i ++)
GUI_Point(i,j,colour);
}
/************************************************************************
//废弃函数区
//水平画线
void v_Lcd12864DrawLineX_f( uint8 X0, uint8 X1, uint8 Y, uint8 Color )
{ uint8 Temp ;
if( X0 > X1 )
{
Temp = X1 ;
X1 = X0 ;
X0 = Temp ;
}
for( ; X0 <= X1 ; X0++ )
GUI_Point( X0, Y, Color);
}
//垂直画线
void v_Lcd12864DrawLineY_f( uint8 X, uint8 Y0, uint8 Y1, uint8 Color )
{
uint8 Temp ;
if( Y0 > Y1 )
{
Temp = Y1 ;
Y1 = Y0 ;
Y0 = Temp ;
}
for(; Y0 <= Y1 ; Y0++)
GUI_Point( X, Y0, Color);
}
************************************************************************/
view plainprint?
/******************************************************************************
** 12864 LCD模块
******************************************************************************/
#ifndef _12864_LCD_
#define _12864_LCD_
#include "math.h"
/******************************************************************************
** 宏定义
******************************************************************************/
//IO口定义
//8bit数据接入IO口
#define Part PORTB
#define Part_Pin PINB
//控制数据端
//定义12864液晶RS端,寄存器选择信号 H:数据寄存器 L:指令寄存器
#define LCD_RS PORTC_PC0
//定义12864液晶RW端,读/写信号 H:读 L:写
#define LCD_RW PORTC_PC1
//定义12864液晶LCDEN端, 片选信号 下降沿触发,锁存数据
#define LCD_EN PORTC_PC2
//定义12864液晶PSB端, H:并行 L:串行
#define LCD_PSB PORTC_PC3
//定义12864液晶RST端, H:不复位 L:复位
#define LCD_RST PORTC_PC4
//IO数据方向定义
#define DDR_DATA DDRB
#define DDR_RS DDRC_DDRC0
#define DDR_RW DDRC_DDRC1
#define DDR_EN DDRC_DDRC2
#define DDR_PSB DDRC_DDRC3
#define DDR_RST DDRC_DDRC4
/******************************************************************************
** 全局变量声明
******************************************************************************/
/******************************************************************************
** 函数声明
******************************************************************************/
//毫秒延时函数
void Delay_MS(uint16 xms);
//LCD忙检测函数
uint8 LCD_Busy(void);
//液晶写命令函数
void LCD_Write_Cmd(uint8 com);
//液晶读命令函数
uint8 LCD_Read_Dat(void);
//液晶写一个字符数据函数
void LCD_Write_Dat(uint8 date);
//液晶写一个字符串函数
void LCD_Write_String(uint8 *str);
//液晶显示位置函数,从第X行的第Y位置开始显示
void LCD_Pos(uint8 x,uint8 y);
//液晶初始化函数
void LCD_Init();
//清屏
void LCD12864_DisplayCLR(void);
//在指定位置上画点。
void GUI_Point(uint8 x,uint8 y,uint8 color);
//在指定位置上画线。
void GUI_Line(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour);
//八分点画圆函数
void plotC(int x,int y,int xc,int yc,uint8 colour);
//画圆
void GUI_Circle(int xc,int yc,int r,uint8 colour);
//用绘图的方法填充一个矩形
void GUI_Full(uint8 x0,uint8 y0,uint8 x1,uint8 y1,uint8 colour);
#endif