您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > LCD1602的电路图和程序
MS基于1602字符型液晶显示器的显示系统姓名:杨越班级:电子11-1学号:110400104一、实习目的(1)了解飞思卡尔单片机的基本原理,掌握其基本的工作流程。(2)了解LCD1602的基本原理及用法。(3)能够熟练使用CodeWarrior软件编写C语言程序,使用BDM仿真器下载程序。(4)能够熟练焊接电路板。二、实验设备与器件CodeWarrior软件,BDM仿真器,万用电路板,飞思卡尔单片机,LCD1602液晶显示器,三、实验内容内容:利用飞思卡尔单片机制作基于1602字符液晶显示器的显示系统要求:用四个按键控制,按下第一个按键显示1,按下第二个按键显示2,以此类推。(1)LCD1602液晶显示器的原理:1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。以下具体阐述这三个管脚:RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。R/W为读写选择,高电平进行读操作,低电平进行写操作。E端为使能端,后面和时序联系在一起。除此外,D0~D7分别为8位双向数据线。操作时序:RSR/W操作说明00写入指令码D0~D701读取输出的D0~D7状态字10写入数据D0~D711从D0~D7读取数据注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.读取状态字时,注意D7位,D7=1,禁止读写操作;D7=0,允许读写操作;所以对控制器每次进行读写操作前,必须进行读写检测。(即后面的读忙子程序)指令集:LCD_1602初始化指令小结:0x38设置16*2显示,5*7点阵,8位数据接口0x01清屏0x0F开显示,显示光标,光标闪烁0x08只开显示0x0e开显示,显示光标,光标不闪烁0x0c开显示,不显示光标0x06地址加1,当写入数据的时候光标右移0x02地址计数器AC=0;(此时地址为0x80)光标归原点,但是DDRAM中断内容不变0x18光标和显示一起向左移动(2)飞思卡尔单片机的功能及特点:MC9S12XS128是16位单片机,由16位中央处理单元(CPU12X)、128KB程序、Flash(P-lash)、8KBRAM、8KB数据Flash(D-lash)组成片内存储器。主要功能模块包括:内部存储器,内部PLL锁相环模块,2个异步串口通讯SCI,1个串行外设接口SPIMSCAN模块,1个8通道输入/输出比较定时器模块TIM,周期中断定时器模块PIT,16通道A/D转换模块ADC,1个8通道脉冲宽度调制模块PWM,输入/输出数字I/O口。本次设计中主要用到PORTA,PORTB端口:PORTA:PORTA为通用I/O口,共8个,作为通用数字I/O口使用,未集成特殊功能.主要配置寄存器有:数据寄存器PORTA、数据方向寄存DDRA、上拉电阻控制寄存器PUCR和驱动控制寄存器RDR。a.数据寄存器PORTA通过写1/0使单片机对应引脚输出高低电平,或通过读取数据寄存器获得对应引脚的高低电平值。例:PORTA_PB0=1b.数据方向寄存器DDRADDRA寄存器配置引脚为输出口还是输入口,“0”,输入口;“1”,输出口。MCU复位后,DDRA值为0x00,引脚默认为输入口。例:DDRA=0xFF//配置PORTA口为输出PORTB:PORTB为通用数字I/O口,共8个。其使用与PORTA基本一样。主要配置寄存器有:数据寄存器PORTB、数据方向寄存DDRB。上拉电阻控制寄存器PUCR和驱动控制寄存器RDR与PORTA、PORTB、PORTE、PORTK共用。a.数据寄存器PORTBb.数据方向寄存器DDRB四、原理图:器件说明:LCD1602(16管脚),2个排阻,4个10k电阻,一个1K电阻,飞思卡尔芯片(64管脚)管脚连接:VSSGNDDB6PB6VCCVCCDB7PB7VEEGNDAVCCRSPA0KGNDRWPA1K1PA4EPA2K2PA5DB0PB0K4PA6DB1PB1K4PA7DB2PB2DB3PB3DB4PB4DB5PB5五、流程图否是六、程序设计1.voidPLL_Init(void):内部锁相环模块,单片机使用PLL功能能够获得更高的总线频率,这对于需要提高单片机运行速度的应用场合非常必要。2.voidLCD_init(void):初始化LCD1602液晶显示屏,3.voidLCD_write_command(uchardat):写指令4.voidLCD_write_data(uchardat):写数据5.voidLCD_disp_char(ucharx,uchary,uchardat):显示字符6.voidmain(void):主函数#includehidef.h/*commondefinesandmacros*/#includederivative.h/*derivative-specificdefinitions*/#includeMC9S12XS128.hunsignedchara=0;unsignedcharb=0;unsignedcharc=0;锁相环设置开始初始化LCD写指令写数据显示字符是否有键按下unsignedchard=0;voidPLL_Init(void)//PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1){//锁相环时钟=2*16*(2+1)/(1+1)=48MHzREFDV=1;//总线时钟=48/2=24MHzSYNR=2;while(!(CRGFLG&0x08));CLKSEL=0x80;//选定锁相环时钟}#defineLCD_DBPORTB#defineLCD_RSPORTA_PA0#defineLCD_RWPORTA_PA1#defineLCD_EPORTA_PA2voidLCD_init(void);//初始化函数voidLCD_write_command(ucharcommand);//写指令函数voidLCD_write_data(uchardat);//写数据函数voidLCD_disp_char(ucharx,uchary,uchardat);//在某个屏幕位置上显示一个字符,X(0-16),y(1-2)//voidLCD_check_busy(void);//检查忙函数。我没用到此函数,因为通过率极低。voiddelay_n25us(uintn);//延时函数//********************************//*******初始化函数***************voidLCD_init(void){LCD_write_command(0x38);//设置8位格式,2行,5x7LCD_write_command(0x0c);//整体显示,关光标,不闪烁LCD_write_command(0x06);//设定输入方式,增量不移位LCD_write_command(0x01);//清除屏幕显示delay_n25us(10);//实践证明,我的LCD1602上,用for循环200次就能可靠完成清屏指令。//LCD_write_command(0x06);//LCD_write_command(0x0c);}//********************************//********写指令函数************voidLCD_write_command(uchardat){LCD_DB=dat;delay_n25us(1);LCD_RS=0;delay_n25us(1);//指令LCD_RW=0;delay_n25us(1);//写入LCD_E=1;delay_n25us(1);//允许LCD_E=0;delay_n25us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。}//*******************************//********写数据函数*************voidLCD_write_data(uchardat){LCD_DB=dat;delay_n25us(1);LCD_RS=1;delay_n25us(1);//数据LCD_RW=0;delay_n25us(1);//写入LCD_E=1;delay_n25us(1);//允许LCD_E=0;delay_n25us(1);delay_n25us(1);}//********************************//*******显示一个字符函数*********voidLCD_disp_char(ucharx,uchary,uchardat){ucharaddress;if(y==1)address=0x80+x;elseaddress=0xc0+x;LCD_write_command(address);LCD_write_data(dat);}//********************************/*******检查忙函数*************voidLCD_check_busy()//实践证明,在我的LCD1602上,检查忙指令通过率极低,以{//至于不能正常使用LCD。因此我没有再用检查忙函数。而使do//用了延时的方法,延时还是非常好用的。我试了一下,用{LCD_E=0;//for循环作延时,普通指令只要1次循就可完成。清屏指令LCD_RS=0;//要用200次循环便能完成。LCD_RW=1;LCD_DB=0xff;LCD_E=1;}while(LCD_DB^7==1);}******************************///********延时函数***************voiddelay_n25us(uintn){uinti=0;ucharj=0;for(i=n;i0;i--)for(j=0;j2;j++);//在这个延时循环函数中我只做了2次循环,}//实践证明我的LCD1602上普通的指令只需1次循环就能可靠完成。//*******************************voidcheck_key(void)//判断按键是否可以控制单片机(如果键入正常,则单片机上的LED会亮{if(!PORTAB_PA4){PORTE_PE5=0;a=1;}elseif(!PORTAB_PA5){PORTE_PE5=0;a=2;}elseif(!PORTAB_PA6){PORTE_PE5=0;a=3;}elseif(!PORTAB_PA7){PORTE_PE5=0;a=4;}elsePORTE_PE5=1;}//*********主函数*****************voidport_init(){DDRB=0XFF;DDRA=0XFF;PORTB=0XFF;}voidmain(void){//PLL_Init();port_init();LCD_init();DDRE_DDRE5=1;PORTE_PE5=1;//不亮/*DDRA_DDRA0=1;DDRA_DDRA1=1;DDRA_DDRA2=1;DDRA_DDRA3=1;*/DDRA_DDRA4=0;//SETPORTAI/OINPUTDDRA_DDRA5=0;DDRA_DDRA6=0;DDRA_DDRA7=0;PORTAB_PA4=1;PORTAB_PA5=1;PORTAB_PA6=1;PORTAB_PA7=1;//LCD_disp_char(4,2,'1');for(;;){_FEED_COP();/*feedsthedog*/check_key();//检查按键while(1){/*if(a==1){delay(10);*///延时去抖if(a==1){LCD_disp_char(0,2,'1');//在LCD第二行第一位输出1}/*elseif(a==2){delay(10);*///延时去抖elseif(
本文标题:LCD1602的电路图和程序
链接地址:https://www.777doc.com/doc-4894460 .html