写在最前: 装载请注明出处,谢谢。
写在之前: 写博客的目的是为了记录自己的一些工作生活,其中可能有些由于本人水平有限而说的不对或者不准确,也请各位不吝赐教。之前在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;
for(x=time;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--)
for(i=900;i>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);
Send_OrderOrDate_To_LCD(((column>>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[2] ;
data1[0] = data;
CS=0;
while(text>0x00)
{
if((text>=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[j][k+8*n],0);
}
}
i++;
column+=8;
}
else
{
i++;
}
}
while(data1>0x00)
{
i=n=k=0;
j = data1 /10; //求出data与0的十位
m = data1 % 10; // 个位
//j = 1;
//m = 2;
//if(data>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[j+0x10][k+8*n],0);
//column += 8;
}
}
LCDAddr(page+n,column+10);
for(k=0;k<8;k++)
{
Send_OrderOrDate_To_LCD(ascii_table_8x16[m+0x10][k+8*n],0);
}
}
i++;
column+=8;
}
CS=1;
}
/***********************************************************************/
/***********************************************************************/
//输出中文
ulong fontaddr=0;
void display_GB2312_string(uchar page,uchar column,uchar *text)
{
uchar i= 0;
while((text>0x00))
{
if(((text>=0xb0) &&(text<=0xf7))&&(text[i+1]>=0xa1))
{
//国标简体(GB2312)汉字在晶联讯字库 IC 中的地址由以下公式来计算:
//Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
//由于担心 8 位单片机有乘法溢出问题,所以分三部取地址
fontaddr = (text- 0xb0)*94;
fontaddr += (text[i+1]-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;
}
else if(((text>=0xa1) &&(text<=0xa3))&&(text[i+1]>=0xa1))
{
//国标简体(GB2312)15x16 点的字符在晶联讯字库 IC 中的地址由以下公式来计算:
//Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0
//由于担心 8 位单片机有乘法溢出问题,所以分三部取地址
fontaddr = (text- 0xa1)*94;
fontaddr += (text[i+1]-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;
}
else if((text>=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++;
}
}
/***********************************************************************/
好了,函数的解析就到这里,谢谢大家。以上函数都经过测试,没有问题。
作者: Bruce-Woo, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-1850657.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
Bruce-Woo 2015-12-2 16:11
用户377235 2015-11-27 20:40
用户377235 2015-11-25 12:58