热度 28
2011-5-30 16:51
3313 次阅读|
3 个评论
由于项目所需,所以这段时间,抽空学了一下LPC2134,它是基于ARM7核的微处理器,内部有128K的flash与16k的RAM,所以一般的处理程序,内部空间就够用了,当然你要上想在上面跑跑操作系统什么的,那就另当别论了。关于这个处理器其它方面的内部资料,如果你想了解,建议你好好翻翻它的数据手册,如果你说英文太难啃,网上有大把中文的资料,当然懒猫还是建议你看英文原版,一它是厂家的资料,比较真实可靠一般不会有什么大错,二你还可以凑这个空档学学英语,真学好了这也是你要工资的筹码。 今天只是实验一下它的IO端口功能,如何实验,懒猫就不再从流水灯开始了,懒猫选择从LCD12864开始,说实在看着这么大一块屏,挺吓人的,其实LCD也没有那么可怕,处理好时序就能让它乖乖的显示,所以想写好LCD12864的驱动首先还是要好好翻看它的数据手册,这里懒猫就不再详述数据手册上的内容了。不过在这里懒猫要先啰嗦一句,想让LCD12864正确显示,一定要记住先清屏,其实也就是清它内部寄存器,否则初始化时它内部的RAM中不知道是什么乱七八糟的东东,一旦你没有清屏,很可能在显示时会出现乱码或显示不正常,如下图所示: 图1-1 初始化时没有加清屏函数 其实懒猫在上大学时就试着用51写LCD12864的驱动程序,所以这次使用还算顺利,记得当时初次使用LCD12864出现这种情况,懒猫非常郁闷,以为自己的驱动程序没有写好,于是使劲翻看数据手册,仔细的看时序,最后还单步调试,发现问题还是没有解决,最后懒猫看到LCD12864中RAM时,突然想到单片机的设置变量时,初值也是随机的,于是就想着清一下RAM,结果问题还真解决了,呵呵,当时那个兴奋呀,无以言表。现在想想那时真的有点傻的可爱,网上有好多现成的程序,自己却一个人死扣自己的程序。可惜时光如梭,转眼间懒猫毕业就要两年了,那些激情燃烧的岁月已渐渐远去,却永远无法抹去我美好的记忆…… 好了,不费话,说一说这次测试的电路,外围电路很简单,没有接什么东东,就接了一块LCD12864,2134的晶振是12MHz的,实时时钟频率是32.768KHz,下面给出仿真电路图,上面省略了很多东东,这次仿真用的是proteus7.5的版本,仿真不能代替实物,懒猫的程序都是通过实物测试通过的,仿真只是为了调试之用,如果你真想学到真本领,做项目是最好的途径。 图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 #define LCD_IE() IO0CLR |= 1 #define LCD_RE() IO0SET |= 1 #define LCD_WE() IO0CLR |= 1 #define LCD_EH() IO0SET |= 1 #define LCD_EL() IO0CLR |= 1 //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)(0xFF16); // 将输出端口置0 IO1SET |= (uint32)(Odata16); // 输出要输出的数据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 ) |(1 ) |(1 ) |(1 ) |(1 ) |(1 ); IO0SET |= (1 )|(1 IO0CLR |= 1 IO0CLR |= 1 ; delay_us(50); IO0SET |= 1 ; delay_us(50); IO0SET |= (1 )|(1 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+ucWidth1128 // uint8 const *ucaRow -- 要显示的数组 //出口参数:NULL //备 注:NULL ***********************************************************************************/ void Show_Row(uint8 ucPage,uint8 ucLine,uint8 ucWidth,uint8 const *ucaRow) { uint8 ucCount = 0; if(ucLine64) { IO0SET |= 1 ; IO0CLR |= 1 ; Write_Cmd(LCDPAGE+ucPage); // 设定页号 Write_Cmd(LCDLINE+ucLine); // 设定列号 Write_Cmd(0x34); if(ucLine+ucWidth64) // 位于左半屏 { for(ucCount = 0;ucCount ;uccount++) { Write_Data(*(ucaRow+ucCount)); // 写入数据 } } else // 跨越两个半屏 先写完左半屏 { for(ucCount=0;ucCount64-ucLine;ucCount++) { Write_Data(*(ucaRow+ucCount)); // 写入数据 } IO0CLR |= 1 ; IO0SET |= 1 ; Write_Cmd(LCDPAGE+ucPage); // 设定页号 Write_Cmd(LCDLINE); // 设定列号 Write_Cmd(0x34); for(ucCount=64-ucLine;ucCount ;uccount++) { Write_Data(*(ucaRow+ucCount));// 写入数据 } } } else // 位于右半屏 { IO0CLR |= 1 ; IO0SET |= 1 ; Write_Cmd(LCDPAGE+ucPage); // 设定页号 Write_Cmd(LCDLINE+ucLine-64); // 设定列号 Write_Cmd(0x34); for(ucCount=0;ucCount ;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 ; 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;i8;i+=2) //共8页 { for(j=0;j128;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可其它嵌入式系统,这个慢慢再总结。 好了,今天说就先到这吧 最后再吼一下懒猫的口号: 每天进步一点点,开心多点 ^_^