2019年整理06ZigBee学习笔记LCD_第1页
2019年整理06ZigBee学习笔记LCD_第2页
2019年整理06ZigBee学习笔记LCD_第3页
2019年整理06ZigBee学习笔记LCD_第4页
2019年整理06ZigBee学习笔记LCD_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、05_ZigBee LED学 习笔记-(转载请注明出处 774910349)Everhua写于2011-12-5今天来学习一下LCD,虽然我也认同在实际的项目中, LCD用得不多,但我肯定自己是 必然要与LCD打交道的,所以我想了解一下别人对 LCD是如何处理的。至W候自己要用就 可以借鉴借鉴。74HC595D对10 口进行扩展,电路如下:我所使用的无线龙开发板使用了一个0JuH7uFJ6JV1 VCC'亠31 < l> KS4Lt l> KW5It D R自G RCK(JA QB OCSR< 1 ROf)SK( KtjlQISFROGGNDOHQlll>

2、 JqrrlILL Ul誌Yv< t.10LtDCKlI1Lio II下 £.LlliJ4门悶EOADIMtl i5Di5-JJ. J6D亦n 17i>ir'N91 .( l> t s1Lvh ksT(7tmHR呱!16VSS VDDW AQ 覆怙EDULDR1RliX门I巧 DMDIP rs NfKSi MlLE1> LtdVCCR15100kS8 SW-PBccCPL2 卩】.2 LCD BKCCCCCO卩0.3 TXD卩D.2 RXDRESETPl.3 LCD LDP2IP22PO O PHOTOjpj1234561*91011121314151

3、617IS1920LCD CS LCD CK卩L4 pi.5 Pl 7 pL6 >0.12> LCD RS;LCD ELCD RW;P0*7 ADC INP04 KEYCANCEL< P0,6_ADC_KEYr,PO.5-KEYOKLCD DATP2&这样就必须对74HC595有所了解。这是一款具有锁存功能的串入并出芯片,真值表如下:其值表卫输入管抑输出许WSISCKSCLRRCKOEXXXXHQAQH 输fiiKPilXXXXLQAQH输興有效值XXLXX移桩窗右綸零L上沿HXX移椀宙存器存储LH上沿HXX移位商仃器価HX上世HXX楞位寄存器驶态持XXX上沿X薪t忆

4、si烝锁“移&崙1? S币佩态槁XXX下沿X输H屛f储器状态保持这里我们只是用到了 3根信号线:SI、SCK RCK其余接固定电平。当然不同文档名称可能会有不同。今天直接进入LCD初始化函数。int main( void )/ Initialze HAL driversHalDriverlnit();/* LCD */ #if (defined HA LCD) && (HALCD = TRUE)HalLcdInitO;#endif void HalLcdInit(void)delay_us(10000);P1DIR |= 0xFC;P2DIR |= 0x01;P0DIR

5、 |= 0x02;P1_2 = 0;delay_us(100);WriteLCD(COMMAND , 0xE2);/复位SetContrast(iIntRegValuea,ContrastValue);ClearScreen();/ HalLcdWriteString(”IEEE:”,1);/ HalLcdWriteString("Init lcd",2);/ HalLcdWriteString("Init lcd",3);/PrintCh8(30,30,'0',1);那么我们今天的重点就是 Hal_lcd.c文件。在初始化函数的开头设置

6、 10 口为输出,大家都看 得懂。延时函数从函数名上看就知道是微妙级延时,我们今天就不管它了。 下面我们要看的由第一个参数来选择是数据还是WriteLCD(COMMAND , 0xE2函数,这是一个数据命令复用的函数,是命令。void WriteLCD(uint8fs, uint8 da)delay1(2);LCD_CS1 = 0;/ 片选LCD_RW = 0;/ 写操作/delay1(0);if(fs)LCD_RS = 1;elseLCD_RS = 0;/ delay1(0);Write595(da);LCD_E = 1;/ = 1;/ 给时钟沿,写入数据delay1(2);LCD_E =

7、0;/ = 0;/delay1(0);LCD_CS1 = 1;其实这个 if 判断完全不必,直接写如下语句即可:LCD_RS = fs;由于我们使用的 595进行 IO 口扩展,所以我们会看到这样一个函数Write595(da):void Write595(uint8 dat)uint8 ii;for(ii = 0 ; ii < 8; ii+)if(dat & 0x80)LCD_595_DAT = 1;elseLCD_595_DAT = 0;dat <<= 1;LCD_595_CK = 1;LCD_595_CK = 0;LCD_595_LD = 1;LCD_595_L

8、D = 0;该函数用来把一字节数据送到LCD并行数据口。如对该函数还不理解的可以对照595 的真值了很多次,这是用来初始化LCD的。用过LCD12864的都知道在初始化 LCD时,需要写入一WriteLCD(调 用表与时序图进行分析。 剩下的操作就完全与 595 无关了。 在初始化函数中对函数串命令对 LCD 进行初始化。具体这些命令都代表什么意思最好去查对应的数据手册,不同 的LCD会有所不同。函数SetContrast(ilntRegValuea,ContrastValu同样是向LCD写入了几条命令,虽然不知道这些命令具体的意思, 但从函数名与其参数的注释中我们可以猜到这是通过调整内部电阻

9、来调整对比度的。最后一个Clearscreen函数当然也能猜到是清屏的:void ClearScreen(void)uint8 x,y;for(x = 0;x < 8 ;x+)setRamAddr(x , 0);for(y = 0 ; y < 128 ; y+)WriteLCD(DATA , 0x00);这里出现了一个新的函数,看就知道是用来设置写入的位置的。从这里也可以知道该 LCD为 8*8*128 。我们还是先来看下系统提供的LCD接口函数吧。打开 Hallcd.h文件:/* Initialize LCD service*/ extern voidHalLcdInit(voi

10、d);/* Write a string to the LCD*/ extern voidHalLcdWritestring( char *str, uint8 option);/* Write a value to the LCD*/ extern voidHalLcdWriteValue( uint32 value, const uint8 radix, uint8 option);/* Write a value to the LCD*/ extern voidHalLcdWritescreen( char *line1, char *line2 );/* Write a string

11、followed by a value to the LCD*/ extern voidHalLcdWritestringValu(echar *title, uint16 value, uint8 format, uint8 line );/* Write a string followed by 2 values to the LCD*/ extern voidHalLcdWriteStringValueValu(echar *title, uint16 value1, uint8 format1, uint16 value2, uint8 format2, uint8 line );/*

12、 Write a percentage bar to the LCD*/ extern voidHalLcdDisplayPercentBa( rchar *title, uint8 value );由此可见我们的系统提供了 7个LCD接口函数。下面我们依次来看。void第一个是初始化函数,前面已经看过了。下面看的是第二个写入字符串函数HalLcdWriteString ( char *str, uint8 option:) void HalLcdWriteString ( char *str, uint8 option)unsigned char i;uint8 LcdBuf20;osal_

13、memcpy(LcdBuf,str,20);i = strlen(str);LcdBufi = '0'switch (option)case 1:case 2:case 3:case 4:case 5:case 6:HalLcdClearLin(eoption%7 );Print8(option%7,0,(unsigned char *)LcdBuf,1);/* */Print8(option%7,0,(unsigned char *)LcdBuf,1);break;default :op tion%7是为了保break;这里HalLcdClearLine函数是用来进行清除操作

14、的,并且是清除一整行。代数式,证参数的正确性,前面讲过我们的屏为 8*8*128 即只有 8 行,行号为 07。/* / 函数名: void Print8(uint16 y,uint16 x, uint8 ch,uint16 yn) / 功能:显示 8*8 字符串/ 输入: xx ,yy 坐标 ,ch1 待显示的字符串 ,yn 是否反黑/ 输出:无*/void Print8(uint16 y,uint16 x, uint8 ch,uint16 yn)uint8 wm ,ii = 0;uint16 adder;while(chii != '0')adder = (chii - 0

15、x20) * 16;/ 计算数据在数组中的地址for(wm = 0;wm < 8;wm+)/ 上半部SetRamAddr(y , x);if(yn = 0)WriteLCD(DATA, Font8X8adder);elseWriteLCD(DATA, Font8X8adder);adder += 1;x += 1;y += 1;/ / 下一行x -= 8;/ 回退 8bitfor(wm = 0;wm < 8;wm+)/ 下半部SetRamAddr(y , x);if(yn = 0)WriteLCD(DATA, Font8X8adder);elseWriteLCD(DATA, Fon

16、t8X8adder);adder += 1;x += 1;ii += 1;y -= 1;该函数咋看之下会以为是写入了一个8*8的字符,其实打开数组Font8X8就可以知道其实是8*16字符。 从另一个角度想, 若是 8*8 字符也就没必要写下半部了。 第三个 void HalLedWriteValue ( uint32 value, const uint8 radix, uint8 op tion)函数是空函数,有兴趣的读者可以自己去实现,只要把需要显示 的数值转换为字符串,再调用写入字符串函数即可。这里我就不演示了。接下来的函数 HalLedWriteSereen是写两串字符到固定位置。既然

17、是写到特定位置,那么肯定也具有特定用处。 接下来两个函数同样是空函数,最后一个函数 voidHalLcdDisplayPercentBa(rchar *title, uint8 value )根本就 没 有 实 现 , 当 我 在 main() 函 数 中 调 用 时 错 误 提 示 为 Errore46: Undefined external,就是找不到该函数,所以该函数不是被封装在操作系统中,而是没有实现! 当然,实际的函数肯定是要比接口函数多得多的,下面我们就来看下 那些不是接口的函数。首先要看的当然是前面遇到过的设置地址函数: void SetRamAddr(uint8 x ,uint

18、8 y)Hal_lcd.c 文件中uint8 temp;temp = 0x0f & x;WriteLCD(COMMAND ,PageAddr|temp);temp = 0x0f & (y >> 4);WriteLCD(COMMAND ,ColAddrH|itemp);temp = 0x0f & y;WriteLCD(COMMAND ,ColAddrLo|temp);这里有一个疏忽,回顾一下Print8()函数会发现有这样一条语句SetRamAddr(y, x);,然而形参却是(x,y),稍不留神就会被忽悠。其实我个人更习惯于把正对时往右的方向定义为X,这样就

19、有0<=x<=127;O<=y<=7其实在函数SetRamAddr(的外层也是这样子定义的。红色部分是定义的宏,这是用于区别不同命令的部分,用过 LCD12864的应该都有印象,在其 pdf文档中会告诉我们一 条命令, 比如清屏命令会告诉我们某些位必须是哪些值, 这些值就是用来确认写入的命令是 一个清屏命令的。函数void InitDisplay(void是用来设定led为正常显示状态的,我们通过宏可以大致了解每条命令的用处:void InitDisplay(void)WriteLCD(COMMAND , DisplayOff);WriteLCD(COMMAND , S

20、egRemapOn);/ 关显示/ks0713/ssd1815/ssd1815WriteLCD(COMMAND , ComRemapOn);SetContrast(iIntRegValue, iContCtrlRegValue)/;/ 设定缺省对比度WriteLCD(COMMAND , PwrCtrlReg | IntVolBstr | IntReg | OPampBuffer); /turn on booster, regulator & dividerWriteLCD(COMMAND , DisplayOn);/ 开显示 证提取字模的大小与扫描方式与显示时一致就可以了。Print6

21、()显示6*8的字符;Printn8(函数则显PrintCh8()函数用于显示一个8*16的字符;Print()函数用于实现P rint16()函数实现汉字的显示。Print8()前面已经分析过了。制作简单字库我想对于玩过点阵的是不会太难的。 只要保 当然字模在数组中的摆放顺序同样是接下来的5个print相关函数都是与显示相关的。其中 示一个数字,需要指定有效长度; 汉字与字母的混合显示,通过调用 我们这里使用的字库是自己做的。有讲究的。我们的程序中使用一维数组进行存放,并以连续 16 个数组成员保存一个字符。 通过查询 ascii 码表知道可打印字符是从 0x20 开始的,且刚好是空格。这就是为什么我们使 用式子 adder = (chii - 0x20) * 16; 来计算字符在数组中的起始地址。起始我更喜欢使用二维数组来 保存字模,二维数组中的每个一维数组成员代表一个字符,这样后面的 *16 就可以直接省掉。 就连adder长度都可以只使用 8位。下面同样是对前面做一下简单的总

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论