图2 电路仿真图
注意,这是仿真电路图,实际设计中要加上电源,晶振,电位器等部件,这个电路图只说明一下LCD与LPC2134的数据接口。
说一下程序,程序包括main.c与display.c两个C源程序代码,只是简单的测试一下lpc2134与LCD12864为后面的实验做一个铺垫,以后的实验可能会用到这个驱动,由于程序东东比较多,所以就只贴出display.c这个源程序,其它的程序在附件中,如果有兴趣可以下载下来查看:
/*************************************************************************/
//文件名称:display.c
//功 能:LCD12864驱动函数
//作 者:懒猫爱飞
//备 注:MCU -- LPC2134
// Crystal -- 12MHz
// RTC -- 32.768KHz
// 开发环境 -- RealView MDK-ARM Verxion 4.12
/*************************************************************************/
#define IN_DISPLAY
#include "config.h"
#include "display.h"
//LCD12864引脚配置
#define LCD_CS1 4 /*-- P0.4 --*/
#define LCD_CS2 3 /*-- P0.3 --*/
#define LCD_RST 5 /*-- P0.5 --*/
#define LCD_DI 21 /*-- P0.21 --*/
#define LCD_RW 11 /*-- P0.11 --*/
#define LCD_EN 10 /*-- P0.10 --*/
//LCD12864操作宏定义
#define LCD_DE() IO0SET |= 1<<LCD_DI /*写数据*/
#define LCD_IE() IO0CLR |= 1<<LCD_DI /*写命令*/
#define LCD_RE() IO0SET |= 1<<LCD_RW /*读选通*/
#define LCD_WE() IO0CLR |= 1<<LCD_RW /*写选通*/
#define LCD_EH() IO0SET |= 1<<LCD_EN /*使能高电平*/
#define LCD_EL() IO0CLR |= 1<<LCD_EN /*使能低电平*/
//LCD12864命令宏定义
#define LCDSTARROW 0xC0 /*-- 设置起始行指令 --*/
#define LCDPAGE 0xB8 /*-- 设置页指令 --*/
#define LCDLINE 0x40 /*-- 设置列指令 --*/
/**********************************************************************************
//函数名称:void delay_us(void)
//功 能:简短微秒级延时
//入口参数:uint32 t -- 延时长度
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void delay_us(uint32 us)
{
while(us--);
}
/**********************************************************************************
//函数名称:void Out_Data(uint8 Odata)
//功 能:向端口输出数据
//入口参数:uint8 Odata -- 要输出的数据
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Out_Data(uint8 Odata)
{
IO1CLR |= (uint32)(0xFF<<16); // 将输出端口置0
IO1SET |= (uint32)(Odata<<16); // 输出要输出的数据Odata
}
/**********************************************************************************
//函数名称:void Write_Data(uint8 Wdata)
//功 能:向LCD12864端口写入数据
//入口参数:uint8 Wdata -- 要写入的数据
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Write_Data(uint8 Wdata)
{
LCD_DE(); // 写数据使能
delay_us(1); // 延时等待端口电平稳定
LCD_WE(); // 写命令使能
delay_us(1); // 延时等待数据写进端口寄存器
Out_Data(Wdata); // 输出要写入LCD12864的数据
delay_us(1); // 延时等待端口电平稳定
LCD_EH(); // 数据在EN下降沿写入LCD12864中
delay_us(3); // 延时
LCD_EL(); // EN下降沿
delay_us(3); // 延时一下
}
/**********************************************************************************
//函数名称:void Write_Cmd(uint8 Wcmd)
//功 能:向LCD12864端口写入命令
//入口参数:uint8 Wcmd -- 要写入的命令
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Write_Cmd(uint8 Wcmd)
{
LCD_IE(); // 写命令使能
delay_us(1);
LCD_WE(); // 写命令使能
delay_us(1);
Out_Data(Wcmd); // 写入命令
delay_us(1);
LCD_EH(); // 数据在EN下降沿写入LCD12864中
delay_us(3);
LCD_EL(); // EN下降沿
delay_us(3);
}
/**********************************************************************************
//函数名称:void Init_LCDIO(void)
//功 能:LCD端口初始化函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Init_LCDIO(void)
{
IO0DIR |= (1<<LCD_DI) // 初始端口方向
|(1<<LCD_RW)
|(1<<LCD_EN)
|(1<<LCD_CS1)
|(1<<LCD_CS2)
|(1<<LCD_RST);
IO0SET |= (1<<LCD_CS2)|(1<<LCD_CS1); // 先不选通页
IO0CLR |= 1<<LCD_EN ; // 初始化时EN脚置低
IO0CLR |= 1<<LCD_RST; // 初始化时先复位一下
delay_us(50);
IO0SET |= 1<<LCD_RST; // 再重新启动LCD12864
delay_us(50);
IO0SET |= (1<<LCD_CS1)|(1<<LCD_CS2); // 选通页
Write_Cmd(0x3F); //开显示, 关显示为 -- 0x3e
Write_Cmd(0x38); // 8位形式,两行字符
Write_Cmd(0x0F); // 开显示
Write_Cmd(0x01); // 清屏
Write_Cmd(0x06); // 画面不动,光标右移
Write_Cmd(0xC0); // 设置起始行
}
/**********************************************************************************
//函数名称:void Show_Row(uint8 ucPage,uint8 ucLine,uint8 ucWidth,uint8 const *ucaRow)
//功 能:在8×128的格子里显示自定义长度的一行
//入口参数:uint8 ucPage -- 取值范围0~7
// uint8 ucLine -- 取值范围0~127
// uint8 ucWidth -- 取值范围0~127
// ucLine+ucWidth<1128
// uint8 const *ucaRow -- 要显示的数组
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Show_Row(uint8 ucPage,uint8 ucLine,uint8 ucWidth,uint8 const *ucaRow)
{
uint8 ucCount = 0;
if(ucLine<64)
{
IO0SET |= 1<<LCD_CS1; // 选通左屏
IO0CLR |= 1<<LCD_CS2;
Write_Cmd(LCDPAGE+ucPage); // 设定页号
Write_Cmd(LCDLINE+ucLine); // 设定列号
Write_Cmd(0x34);
if(ucLine+ucWidth<64) // 位于左半屏
{
for(ucCount = 0;ucCount<ucWidth;ucCount++)
{
Write_Data(*(ucaRow+ucCount)); // 写入数据
}
}
else // 跨越两个半屏先写完左半屏
{
for(ucCount=0;ucCount<64-ucLine;ucCount++)
{
Write_Data(*(ucaRow+ucCount)); // 写入数据
}
IO0CLR |= 1<<LCD_CS1; // 再写右半屏
IO0SET |= 1<<LCD_CS2;
Write_Cmd(LCDPAGE+ucPage); // 设定页号
Write_Cmd(LCDLINE); // 设定列号
Write_Cmd(0x34);
for(ucCount=64-ucLine;ucCount<ucWidth;ucCount++)
{
Write_Data(*(ucaRow+ucCount));// 写入数据
}
}
}
else // 位于右半屏
{
IO0CLR |= 1<<LCD_CS1;
IO0SET |= 1<<LCD_CS2;
Write_Cmd(LCDPAGE+ucPage); // 设定页号
Write_Cmd(LCDLINE+ucLine-64); // 设定列号
Write_Cmd(0x34);
for(ucCount=0;ucCount<ucWidth;ucCount++)
{
Write_Data(*(ucaRow+ucCount)); // 写入数据
}
}
}
/**********************************************************************************
//函数名称:void Show_Onehz(uint8 ucPage,uint8 ucLine,uint8 const *ucaChinMap)
//功 能:将16×16汉字显示在8×128的格子里
//入口参数:uint8 ucPage -- 取值范围 0~7
// uint8 ucLine -- 取值范围 0~127
// int8 const *ucaChinMap -- 要显示的汉字数组
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Show_Word(uint8 ucPage,uint8 ucLine,uint8 const *ucaChinMap)
{
Show_Row(ucPage,ucLine,16,ucaChinMap); // 汉字上半部分
Show_Row(ucPage+1,ucLine,16,ucaChinMap+16); // 汉字下半部分
}
/**********************************************************************************
//函数名称:void Display_HZ(uint8 pagenum,uint8 colnum,uint8 num)
//功 能:LCD显示汉字
//入口参数:uint8 pagenum -- 页码
// uint8 colnum -- 列数
// uint8 num -- 第几个汉字
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Display_HZ(uint8 pagenum,uint8 colnum,uint8 num)
{
//uint8 k;
uint8 const *p1;
//k=colnum*16;
p1=hz_mode[num];
Show_Word(pagenum,colnum,p1);
}
/**********************************************************************************
//函数名称:void Show_Char(uint8 ucPage,uint8 ucLine,uint8 const *ucaCharMap)
//功 能:将8×16字符显示在8×128的格子里。
//入口参数:uint8 ucPage – 要写入的页
// uint8 ucLine – 要写入的列
// uint8 const *ucaCharMap – 要写入的数值
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Show_Char(unsigned char ucPage,unsigned char ucLine,unsigned char const *ucaCharMap)
{
Show_Row(ucPage,ucLine,8,ucaCharMap);
Show_Row(ucPage+1,ucLine,8,ucaCharMap+8);
}
/**********************************************************************************
//函数名称:void Clear_Screen()
//功 能:清屏函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Clear_Screen()
{
uint8 i,j;
for(i=0;i<8;i+=2) //共8页
{
for(j=0;j<128;j+=8) //共128列
{
Show_Char(i,j,CHAR_B);
}
}
}
/**********************************************************************************
//函数名称:void Init_LCD(void)
//功 能:LCD初始化函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
***********************************************************************************/
void Init_LCD(void)
{
Init_LCDIO(); // 初始化LCD接口
Clear_Screen(); // 要先清屏,不然会显示不正常
/*-- 以下显示函数显示“懒猫爱飞,学习日志” --*/
Display_HZ(2,0,10); // 懒
Display_HZ(2,16,11); // 猫
Display_HZ(2,32,12); // 爱
Display_HZ(2,48,13); // 飞
Display_HZ(3,64,14); // 学
Display_HZ(3,80,15); // 习
Display_HZ(3,96,16); // 日
Display_HZ(3,112,17); // 志
}
当然这个程序还不完善,还没显示图片的函数,以后会慢慢加上的,现在还只是在LPC2134中裸奔,主要是为了了解一下它内部结构与内部资源,以后的资料会涉及到ucos可其它嵌入式系统,这个慢慢再总结。
好了,今天说就先到这吧
最后再吼一下懒猫的口号:
每天进步一点点,开心多点^_^ |