热度 18
2015-12-16 22:33
3710 次阅读|
3 个评论
写在最前: 装载请注明出处,谢谢。 写在之前: 写博客的目的是为了记录自己的一些工作生活,其中可能有些由于本人水平有限而说的不对或者不准确,也请各位不吝赐教。之前在STM32F1上的移植没有意识到留下照片, 现在就用当前的STM8S作为演示(好吧,其实是因为我懒得重新接线哈) 上一篇:https://mbb.eet-china.com/blog/1850657-370272.html 我分享的附件清单如下,待有空再详细补足。 1.JLX12864G-086-PC的中文字库编程说明书 里面有C51的例程 2,LCD显示 在STM32上的显示 3,《JLX12864G-086》 里面有JLX12864G-086的指令。JLX12864G-086中有一些数字有着其特定的意义,当他作为命令发送时候,代表一条指令,作为数字时候就是普通的数据。 4,《JLX12864G-1016中文说明书》 JLX12864G-1016中文说明书.pdf是一本参考资料,对JLX12864G-086的学习很有意义,里面也提供了C51的例程 平台: STM32F1 和STM8S105 软件:STLINK IAR for STM8 功能: 实现数字输入 汉字输入 和带参数输入 关于JLX12864G-086-PC的若干事 1,JLX12864G-086-PC 是一款比较优良的显示屏,能做很低的功耗,也比较容易上手。 2,JLX12864G-086-PC 容易编写,SPI时序。 3,JLX12864G-086-PC 扩展性高。 4,.... 就初始化做一些解析 void JLX12864G_086_GPIOIntI(void) { PC_DDR |= (1<<1)+(1<<2)+(1<<4)+(1<<7);//RST SCK SDA CS PC_CR1 |= (1<<1)+(1<<2)+(1<<4)+(1<<7); PC_CR2 &=~((1<<1)+(1<<2)+(1<<4)+(1<<7)); // PC_DDR &=~(1<<4); //PC7悬浮输入 SDO // PC_CR1 &=~(1<<4); // PC_CR2 &=~(1<<4); PE_DDR |= (1<<5); //RS PE_CR1 |= (1<<5); PE_CR2 &=~(1<<5); PB_DDR |= (1<<0)+(1<<1)+(1<<2); // sck cs# ROM_in PB_CR1 |= (1<<0)+(1<<1)+(1<<2); PB_CR2 &=~((1<<0)+(1<<1)+(1<<2)); PB_DDR &=~(1<<3); //Rom_out PB_CR1 |= (1<<3); PB_CR2 &=~ (1<<3); //不要中断上拉输入 上拉输入 } 初始化的重点: 1,选的引脚不能是特殊引脚,比如VSS VDD 串口等 新手常会犯这种错误 2,上拉输入和中断上拉输入是不同的,如果你配置了中断上拉输入而不做中断函数配置,会提示进入 UNEXPECT HANDLE(未预计错误) Tip: UNEXPECT HANDLE 的错误很多情况下是因为你初始化了中断然而并没有配置好 3, ROM_OUT引脚对应字符库芯片的输入引脚,ROM_IN引脚对应字符库芯片的输出引脚,所以ROM_OUT要配置成上拉输入 4,延时要准确,我在这里分享给大家两个在示波器上得到验证的演示函数,当然大家最好在示波器上验证一下,此外,该延时只是大概延时,误差多多少少会有的,切不可当作准确演示。 Tip:任何时序的延时都是非常重要的,如果程序运行不对,程序也没有问题的情况下,很可能是延时不够准确。 /***************************************************** //在16M晶振下,必须在16M的情况下 void delay_us( unsigned int time) { unsigned int x; 0;x--) { asm("nop"); //一个asm("nop")函数经过示波器测试代表100ns asm("nop"); asm("nop"); asm("nop"); asm("nop"); //一个asm("nop")函数经过示波器测试代表100ns } } void delay_ms(unsigned int time) { unsigned int i; while(time--) 0;i--) delay_us(1); } **********************************************************/ void JLX12864G_086_IntI(void) //初始化 { //RST=1; //delay_ms(1000); //CS=0; delay_ms(20); RST=0; delay_ms(5); RST=1; Send_OrderOrDate_To_LCD(0xE2, 1); delay_ms(5); Send_OrderOrDate_To_LCD(0x2c, 1);/*升压步聚1*/ delay_ms(5); Send_OrderOrDate_To_LCD(0x2e, 1);/*升压步聚2*/ delay_ms(5); Send_OrderOrDate_To_LCD(0x2f, 1);/*升压步聚3*/ delay_ms(5); Send_OrderOrDate_To_LCD(0x24, 1);/*粗调对比度,可设置范围20~27*/ Send_OrderOrDate_To_LCD(0x81, 1);/*微调对比度*/ Send_OrderOrDate_To_LCD(0x1a, 1);/*微调对比度的值,可设置范围0~63 1f*/ Send_OrderOrDate_To_LCD(0xa2, 1);/*1/9偏压比(bias)*/ Send_OrderOrDate_To_LCD(0xc8, 1);/*行扫描顺序:从上到下*/ Send_OrderOrDate_To_LCD(0xa0, 1);/*列扫描顺序:从左到右*/ Send_OrderOrDate_To_LCD(0x40, 1);/*起始行:从第一行开始*/ ClearScreen(); //清屏 Send_OrderOrDate_To_LCD(0xaf, 1);/*开显示*/ //delay_ms(20); //CS=1; } Tip:如上所述,JLX12864G-086-PC 中有些数字代表着一个命令,在这里我不做解析。大家如有兴趣,可自行查阅我分享的第三份和第四份参考资料。 那么你就要问了,那怎么区别命令和数字呢?这里给大家一个我写的函数 /***********************************************************************/ //** 发送命令或数据 void Send_OrderOrDate_To_LCD(unsigned char data,unsigned char OrderorDateFlag) //OrderorDateFlag 1 :命令 0:data { unsigned char i; //ROM_CS=1; //delay_ms(10); CS=0; if(OrderorDateFlag) RS=0; //区别在这里 else RS=1; //区别在这里 //SPI 时序 for(i=0;i<8;i++) { SCK = 0; //if(!OrderorDateFlag) delay_us(2); //少量延时 delay_us(2); //少量延时 if(data & 0x80) SDA=1; //输出 1 else SDA = 0 ; SCK = 1; delay_us(2); //少量延时 data = data << 1; } } /***********************************************************************/ /***********************************************************************/ // 指定行和列写入 void LCDAddr(unsigned char page,unsigned char column) // { CS=0; column--; page--; Send_OrderOrDate_To_LCD(0xb0+page,1); 4)&0x0f)+0x10,1); Send_OrderOrDate_To_LCD(column&0x0f,1); } Tip; 要有间隔 如; DisplayWithParameter(1,10,"WenDu:",WenDu); DisplayWithParameter(3,10,"ShiDu:",ShiDu); 其中 “1”和 “3”是行 如果显示一半,很可能是你的传输数据时候 “i++”的问题 /***********************************************************************/ /***********************************************************************/ //带参数显示 void DisplayWithParameter(unsigned short page,unsigned short column,unsigned char *text,unsigned char data) { unsigned short i=0,j,m,k,n; static unsigned char data1 ; data1 = data; CS=0; 0x00) { =0x20)&&(text <=0x7e)) { j=text -0x20; for(n=0;n<2;n++) { LCDAddr(page+n,column); for(k=0;k<8;k++) { Send_OrderOrDate_To_LCD(ascii_table_8x16 ,0); } } i++; column+=8; } else { i++; } } 0x00) { i=n=k=0; j = data1 /10; //求出data 与0的十位 m = data1 % 10; // 个位 //j = 1; //m = 2; 9) j+=6; // j=data / 10; //求出data 与0的绝对值 for(n=0;n<2;n++) { if(j) { LCDAddr(page+n,column+2); for(k=0;k<8;k++) { Send_OrderOrDate_To_LCD(ascii_table_8x16 ,0); //column += 8; } } LCDAddr(page+n,column+10); for(k=0;k<8;k++) { Send_OrderOrDate_To_LCD(ascii_table_8x16 ,0); } } i++; column+=8; } CS=1; } /***********************************************************************/ /***********************************************************************/ //输出中文 ulong fontaddr=0; void display_GB2312_string(uchar page,uchar column,uchar *text) { uchar i= 0; 0x00)) { =0xb0) &&(text =0xa1)) { //国标简体(GB2312)汉字在晶联讯字库 IC 中的地址由以下公式来计算: //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0 //由于担心 8 位单片机有乘法溢出问题,所以分三部取地址 fontaddr = (text - 0xb0)*94; fontaddr += (text -0xa1)+846; fontaddr = (ulong)(fontaddr*32); get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 //get_and_write_5x8(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 i+=2; column+=16; } =0xa1) &&(text =0xa1)) { //国标简体(GB2312)15x16 点的字符在晶联讯字库 IC 中的地址由以下公式来计算: //Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0 //由于担心 8 位单片机有乘法溢出问题,所以分三部取地址 fontaddr = (text - 0xa1)*94; fontaddr += (text -0xa1); fontaddr = (ulong)(fontaddr*32); get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 //get_and_write_5x8(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 i+=2; column+=16; } =0x20) &&(text <=0x7e)) { fontaddr = (text - 0x20); fontaddr = (unsigned long)(fontaddr*16); fontaddr = (unsigned long)(fontaddr+0x3cf80); get_and_write_8x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 //get_and_write_8x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中 i+=1; column+=8; } else i++; } } /***********************************************************************/ 好了,函数的解析就到这里,谢谢大家。以上函数都经过测试,没有问题。