12864串行输入
- 格式:doc
- 大小:63.00 KB
- 文档页数:16
12864液晶显示串行程序(英飞凌xc824)
先说说我的调试初衷前一阵看实验室的兄弟姐妹们都闲的无聊,就有人DIY 了,有人个BF 做电子时钟,一个液晶30 多,一个12C887 20 多,板子加器件还有单片机算下来少说也有70 大洋。
感觉实在不划算,但是对液晶还是
蛮感兴趣的,一方面熟悉一下串行设备,一方面为以后做准备,毕竟液晶显示
操作起来要比LED 简单,而且能实时显示,到什么时候都能用上。
所以,这
次液晶屏的调试,我就想搜集一些常用的程序,适当的修改,让液晶屏达到拿
来就能用上的目的。
先说说我这次调试的液晶屏,12864,带子库的,蓝色屏幕。
就是这张图了
单片机我选的是英飞凌xc824,新出的哦。
不是有啥特殊偏好,手头就有这个,就先用这个吧,主要是我对这个最小系统板上的触摸按键比较感兴趣。
当
然了,它也有缺点,内存太小,连一个12864 的图片都装不下。
:Q 闲话少说,先从最基本的数据手册开始吧
中显液晶12864.pdf
这是中文资料,因为这种东西已经被使用的多的不能再多了,而且厂家众多,但是有细微差别,比如串行和并行,有的是焊点切换的,有的是软件切换的。
我这个是后者。
刚接线的时候还出了个笑话,太相信实物和datasheet 和对应的了,结果屏幕的背光接反了,幸好没烧。
硬件方面,我选串行是因为它用线少,我很懒的。
:) P1.0 口对应CS,P1.1 口对应SID,P1.2 口对应CLK.
参考时序在datasheet 上写的很清楚有这个当指导思想,照着写程序吧.动手之。
12864使用心得论文一、硬件连接1.1 12864引脚示意图1.2 本次实验中12864与MCU的连接示意图/****************晶振为11.0592**********************/sbit PSB = P1^0; //并1/串0选择//串行接法sbit CS = P1^3; //串片选sbit DS = P1^2; //串数据口sbit SCK = P1^1; //串时钟信号/*//并行接法sbit RS = P1^3; //数据/命令选择端sbit RW = P1^2; //读写选择端sbit E = P1^1; //使能信号端#define DataIO P0 //并行数据口*/二、底层基本程序(串行方式)2.1 基本写字节程序//写一个字节(以SCK上升沿接收一个位)void sendbyte(uint8 zdata){uint16 i;for(i=0; i<8; i++){if((zdata << i) & 0x80){DS = 1;}else {DS = 0;}SCK = 0;SCK = 1;}}2.2 写命令程序(若晶振频率>11.0592,则需加延时处理)//写命令void writeCmd(uint8 cmdcode){CS = 1;sendbyte(0xf8);sendbyte(cmdcode & 0xf0);sendbyte((cmdcode << 4) & 0xf0);// delayMs(1); //若晶振频率>11.0592,则需延时}2.3 写数据程序(若晶振频率>11.0592,则需加延时处理)//写数据void writeData(uint8 dispdata){CS = 1;sendbyte(0xfa);sendbyte(dispdata & 0xf0);sendbyte((dispdata << 4) & 0xf0);// delayMs(1); //若晶振频率>11.0592,则需延时}2.4 通用软件毫秒延时程序//延时程序void delayMs(uint16 xms){uint16 i,j;for (i=0;i<=xms;i++)for (j=0;j<=123;j++);}三、文本显示3.1 LCD12864初始化//LCD12864初始化void LCD12864Init(){PSB = 0; //串行writeCmd(0x30); //基本指令模式writeCmd(0x04); //游标右移一位writeCmd(0x0c); //显示开,关光标writeCmd(0x01); //清除LCD的内容(仅字符模式) }模块控制芯片提供两套控制命令,基本指令和扩充指令如下:指令表1:(RE=0:基本指令)指令表2:(RE=1:扩充指令)3.2 LCD12864字符串的显示//写字符串函数,参数line第1/2行beSpace字符前面的空格数pString指针uint8 write12864String(uint8 line,uint8 beSpace,char *pString){uint8 i=0;uint8 sLength = strlen(pString); //字符串长度if (pString == NULL) //空字符串return -1;writeCmd(0x30); //基本指令模式//设置写在的位置if (line == 1){writeCmd(0x80 + beSpace); //写在第一行的位置}else if (line == 2){writeCmd(0x90 + beSpace); //写在第二行的位置}else if (line == 3){writeCmd(0x88 + beSpace); //写在第三行的位置}else if (line == 4){writeCmd(0x98 + beSpace); //写在第四行的位置}else{return -1;}//写数据for (i=0;i< sLength;i++){writeData ( *pString );pString ++;}return 0;}12864每屏可显示4行8列共32个16×16点阵的汉字,每个显示RAM可显示1个中文字符或2个16×8点阵全高ASCII码字符,即每屏最多可实现32个中文字符或64个ASCII码字符的显示。
12864串行显示中文,按键选择显示页面,并且可调数值。
单片机P1 口接矩阵按键,其它接口按程序中定义去接只需要接12864LCD 上GND VCC程序如下/********************************12864 h 头文件 *******************************/#ifndef 12864 h #defi ne _12864_h /***** 句]头文彳牛 **************/ #in clude<reg51.h> /******** 定义 I/0 口 **********/LCD12864_SCLK = P 2人7; //E LCD12864_SID = P 2人5; //RW RS RW E PSB RST A K #defi ne GPI O_KEYP1sbitsbitsbitsbitsbit LCD12864_CS = P 2人6; //RS LCD12864_RET= P 2人0; LCD12864_ PSB =P 2人2;/*声明全局变量*/extern unsigned char keyvalue;/****** 声明全局函数 *********/void Delay1ms(unsigned int); // 声明延时函数 un signed char KeyDow n( void);void LCD_se ndbyte( un sig ned char);void WrCom(un sig ned char);void WrDat( un sig ned char);void Lcdin it(void);//void Pnnt(un sig ned char);void SetAddress( un sig ned char,u nsig ned char );void Disp layStri ng(un sig ned char x ,un sig ned char y,un sig ned char *add); #e ndif/********************************12864 C*************************************/#i nclude"12864.h"#in clude<reg51.h>#in clude"stri ng.h"//#defi ne LCM_ST7920_FIRST_LINE_ADDRESS//#define LCM ST7920 SECOND LINE ADDRESS0x80 0x90 //#defi ne LCM_ST7920_THIRD_LINE_ADDRESS//#defi ne LCM_ST7920_FOURTH_LINE_ADDRESS 0x88 0x98/*定义全局变量*/un sig ned char keyvalue=0;/******************************************************************************:c e :无 :该函数是在12MHZ 晶振下,12分频单片机的延时。
12864串行显示(字符、字符串)/************************************************************** ******* 文件名:串行12864显示.c* 描述 : 该程序实现了12864以串行的方式进行通信。
液晶上的R9。
R10决定液晶的串行或者并行通讯方式。
液晶上的PSB已经拉为高电平。
如果使用串行,需要取掉R9。
* 创建人:* 版本号:*************************************************************** ********/#include#include#define uchar unsigned char#define uint unsigned intsbit CS=P2^5; //片选信号sbit SID=P2^6; //数据信号sbit SCLK=P2^7; //时钟信号sbit RST=P2^2; //复位信号sbit CH = P2^4; //并行、串行选择信号/************************************************************** ******* 名称 : delay()* 功能 : 延时,延时时间为 100us * t。
这是通过软件延时,有一定误差。
* 输入 : t* 输出 : 无*************************************************************** ********/void delay(unsigned int t){unsigned int i,j;for(i=0; ifor(j=0; j<10; j++);}/************************************************************** ******* 名称 : sendbyte()* 功能 : 按照液晶的串口通信协议,发送数据* 输入 : zdata* 输出 : 无*************************************************************** ********/void sendbyte(unsigned char zdata){unsigned int i;for(i=0; i<8; i++){if((zdata << i) & 0x80){SID = 1;}else{SID = 0;}SCLK = 0;SCLK = 1;}}/************************************************************** ******* 名称 : write_com()* 功能 : 写串口指令* 输入 : cmdcode* 输出 : 无*************************************************************** ********/void write_com(unsigned char cmdcode){CS = 1;sendbyte(0xf8);sendbyte(cmdcode & 0xf0);sendbyte((cmdcode << 4) & 0xf0);delay(2);}/************************************************************** ******* 名称 : write_data()* 功能 : 写串口数据* 输入 : cmdcode* 输出 : 无***********************************************************************/void write_data(unsigned char Dispdata){CS = 1;sendbyte(0xfa);sendbyte(Dispdata & 0xf0);sendbyte((Dispdata << 4) & 0xf0);delay(2);}/************************************************************** ******* 名称 : lcdinit()* 功能 : 初始化函数* 输入 : cmdcode* 输出 : 无*************************************************************** ********/void lcdinit(){RST = 0;delay(100);RST = 1;delay(20000);write_com(0x30);delay(50);write_com(0x0c);delay(50);}/************************************************************** ******* 名称 : L1602_num(uchar hang,uchar lie,char sign)* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示(0~9) ,调用该函数如下L1602_char(1,5,9)* 输入 : 行,列,需要输入1602的数据* 输出 : 无*************************************************************** ********/void L12864_num(uchar hang,uchar lie,char sign){switch(hang){case 1: write_com(0x80+lie);break;case 2: write_com(0x90+lie);break;case 3: write_com(0x88+lie);break;case 4: write_com(0x98+lie);break;default:break;}write_data(sign+48);}/************************************************************** ******* 名称 : L1602_char(uchar hang,uchar lie,char sign)* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下L1602_char(1,5,'b')* 输入 : 行,列,需要输入1602的数据* 输出 : 无*************************************************************** ********/void L12864_char(uchar hang,uchar lie,char sign){switch(hang){case 1: write_com(0x80+lie);break;case 2: write_com(0x90+lie);break;case 3: write_com(0x88+lie);break;case 4: write_com(0x98+lie);break;default:break;}//write_data(00);write_data(sign);}/************************************************************** ******* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下L1602_string(1,5,"ab cd ef;")* 输入 : 行,列,需要输入1602的数据* 输出 : 无*************************************************************** ********/void L12864_string(uchar hang,uchar lie,uchar *p){switch(hang){case 1: write_com(0x80+lie);break;case 2: write_com(0x90+lie);break;case 3: write_com(0x88+lie);break;case 4: write_com(0x98+lie);break;default:break;}while(*p>0){write_data(*p);p++;}}/************************************************************** ******* 名称 : Test()* 功能 : 显示子函数* 输入 : 无* 输出 : 无*************************************************************** ********/void Test(){//write_com(0x03);//delay(50);L12864_num(1,0,8);L12864_char(2,0,'m');L12864_string(3,0,"sffds");L12864_string(4,0,"是电池");}/************************************************************** ******* 名称 : Main()* 功能 : 主函数* 输入 : 无* 输出 : 无*************************************************************** ********/void Main(){CH = 0;delay(1);lcdinit();delay(10);while(1){Test();delay(5000);}}。
#include "stm32f10x_lib.h"//#include "stm32f10x_it.h"GPIO_InitTypeDef GPIO_InitStructure;ErrorStatus HSEStartUpStatus;/* 函数申明-----------------------------------------------*/void RCC_Configuration(void);void GPIO_Configuration(void);void WWDG_Configuration(void);void Delay(u32 nTime);void Delayms(vu32 m);/* 变量定义----------------------------------------------*//********************************************************************************* ** 函数名称:main(void)** 函数功能:主函数** 输入:无** 输出:无** 返回:无******************************************************************************** */#define uchar unsigned char#define uint unsigned intvoid write_com(uchar com);void write_data(uchar data);void LCD_init(void);uint com,num,i;uchar data;/* 变量定义----------------------------------------------*//*矩阵键盘PC口好用,PB口不好用,因为PB4复位后功能特定*///数据uchar ss1[]={"0123456789"};u8 ss2[]={"jizhundianya"};/********************************************************************************* ** 函数名称:main(void)** 函数功能:主函数** 输入:无** 输出:无** 返回:无******************************************************************************** */int main(void){RCC_Configuration();GPIO_Configuration();LCD_init();Delayms(100); //初始化LCDwrite_com(0x80); //显示位置第一行for(num=0;num<10;num++){write_data(ss1[num]);Delayms(1);}write_com(0x90);for(num=0;num<12;num++){write_data(ss2[num]);Delayms(1);} //显示位置第二行}void write_com(uchar com) //命令语句{uchar i;uchar i_com;i_com=0xf8;//写命令GPIO_SetBits(GPIOA, GPIO_Pin_5); // CS选通。
pA.5作为片选位。
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // SCLK低电平,PA.3作为时钟信号。
for(i=0;i<8;i++){if((i_com&0x80)){GPIO_SetBits(GPIOA, GPIO_Pin_4); //pa.4作为串行数据口。
}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);}GPIO_ResetBits(GPIOA, GPIO_Pin_3); //拉低时钟口。
Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3);//拉高时钟口。
Delayms(1);i_com=i_com<<1; // 依次移位从高到低送到4号管脚即SID中}i_com=com;i_com&=0xf0;for(i=0;i<8;i++){if(i_com&0x80){GPIO_SetBits(GPIOA, GPIO_Pin_4);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 按位输入}GPIO_ResetBits(GPIOA, GPIO_Pin_3);Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3); //Delayms(1);i_com=i_com<<1; // 依次移位从高到低送到4号管脚即SID中}i_com=com;i_com<<=4;for(i=0;i<8;i++){if(i_com&0x80){GPIO_SetBits(GPIOA, GPIO_Pin_4);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);}GPIO_ResetBits(GPIOA, GPIO_Pin_3);Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3); //Delayms(1);i_com=i_com<<1; // 依次移位从高到低送到4号管脚即SID中}GPIO_ResetBits(GPIOA, GPIO_Pin_5); // CS不选通// Delayms(10);}void write_data(uchar data) //数据语句{uchar i;uchar i_data;i_data=0xfa;GPIO_SetBits(GPIOA, GPIO_Pin_5); // CS选通GPIO_ResetBits(GPIOA, GPIO_Pin_3); // SCLK低电平for(i=0;i<8;i++)if(i_data&0x80){GPIO_SetBits(GPIOA, GPIO_Pin_4);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);}GPIO_ResetBits(GPIOA, GPIO_Pin_3);Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3); //Delayms(1);i_data=i_data<<1; // 依次移位从高到低送到4号管脚即SID中}i_data=data;i_data&=0xf0;for(i=0;i<8;i++){if(i_data&0x80){GPIO_SetBits(GPIOA, GPIO_Pin_4);else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);}GPIO_ResetBits(GPIOA, GPIO_Pin_3);Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3); //Delayms(1);i_data=i_data<<1; //依次移位从高到低送到4号管脚即SID中}i_data=data;i_data<<=4;for(i=0;i<8;i++){if(i_data&0x80){GPIO_SetBits(GPIOA, GPIO_Pin_4);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);}GPIO_ResetBits(GPIOA, GPIO_Pin_3);Delayms(1);GPIO_SetBits(GPIOA, GPIO_Pin_3); //Delayms(1);i_data=i_data<<1; // 依次移位从高到低送到4号管脚即SID中}GPIO_ResetBits(GPIOA, GPIO_Pin_5); // CS不选通// Delayms(10);}void LCD_init(){write_com(0x30);//基本指令模式8位数据接口Delayms(10);write_com(0x02);//清DDRAMDelayms(10);write_com(0x06);//游标显示右移一位Delayms(10);write_com(0x0e);//开显示显示光标光标位置反白开启Delayms(10);write_com(0x01);//清屏Delayms(10);write_com(0x80);//设定首次显示的位置Delayms(10);}/********************************************************************************* ** 函数名称:RCC_Configuration(void)** 函数功能:时钟初始化** 输入:无** 输出:无** 返回:无******************************************************************************** */void RCC_Configuration(void){/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* PLLCLK = 8MHz * 9 = 72 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){}}}/*********************************************************************************** 函数名称:GPIO_Configuration(void)** 函数功能:端口初始化** 输入:无** 输出:无** 返回:无*********************************************************************************/void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE ); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 |GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_11 |GPIO_Pin_12 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最高输出速率50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); // 选择A 端口}/*********************************************************************************** 函数名称:NVIC_Configuration(void)** 函数功能:中断初始化** 输入:无** 输出:无** 返回:无*********************************************************************************//*********************************************************************************** 函数名称:WWDG_Configuration(void)** 函数功能:看门狗初始化** 输入:无** 输出:无** 返回:无*********************************************************************************/void WWDG_Configuration(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);WWDG_SetPrescaler(WWDG_Prescaler_8); // WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms)WWDG_SetWindowValue(0x41); // Set Window value to 0x41WWDG_Enable(0x50); // Enable WWDG and set counter value to 0x7F, WWDG timeout = ~4 ms * 64 = 262 msWWDG_ClearFlag(); // Clear EWI flagWWDG_EnableIT(); // Enable EW interrupt}/********************************************************************************* ** 函数名称:Delay(vu32 nCount)** 函数功能:延时函数** 输入:无** 输出:无** 返回:无******************************************************************************** */void Delay(vu32 nCount){for(; nCount != 0; nCount--);}/********************************************************************************* ** 函数名称:void Delayms(vu32 m)** 函数功能:长延时函数m=1,延时1ms** 输入:无** 输出:无** 返回:无******************************************************************************** */void Delayms(vu32 m){u32 i;for(; m != 0; m--)for (i=0; i<7200; i++);}/********************************************************************************* ** 函数名称:WWDG_IRQHandler(void)** 函数功能:窗口提前唤醒中断** 输入:无** 输出:无** 返回:无******************************************************************************** */void WWDG_IRQHandler(void){/* Update WWDG counter */WWDG_SetCounter(0x50);/* Clear EWI flag */WWDG_ClearFlag();}。