1、写入指令码D0D71读取输出的D0D7状态字写入数据D0D7从D0D7读取数据注:关于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;(此时地址为0
2、x80) 光标归原点,但是DDRAM中断内容不变0x18 光标和显示一起向左移动(2)飞思卡尔单片机的功能及特点:MC9S12XS128 是 16 位单片机,由 16 位中央处理单元(CPU12X)、128KB 程序、Flash(P-lash)、8KB RAM、8KB 数据 Flash(D-lash)组成片内存储器。主要功能模块包括:内部存储器, 内部 PLL 锁相环模块 ,2 个异步串口通讯 SCI ,1个串行外设接口 SPI MSCAN 模块 ,1 个 8 通道输入/输出比较定时器模块 TIM ,周期中断定时器模块 PIT ,16 通道 A/D 转换模块 ADC ,1 个 8 通道脉冲宽度
3、调制模块 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 值为
4、 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管脚) 管脚连接:VSSGND DB6PB6VCCDB7PB7VEEAPA0
5、KRWPA1K1PA4EPA2K2PA5DB0PB0K4PA6DB1PB1PA7DB2PB2DB3PB3DB4PB4 DB5PB5五、流程图 否 是六、程序设计1.void PLL_Init(void):内部锁相环模块,单片机使用PLL功能能够获得更高的总线频率,这对于需要提高单片机运行速度的应用场合非常必要。2. void LCD_init(void):初始化LCD1602液晶显示屏,3. void LCD_write_command(uchar dat):写指令4. void LCD_write_data(uchar dat):写数据5. void LCD_disp_char(uchar
6、x,uchar y,uchar dat):显示字符6. void main(void):主函数#include /* common defines and macros */#include derivative.h /* derivative-specific definitions */MC9S12XS128.h unsigned char a=0; unsigned char b=0; unsigned char c=0; unsigned char d=0;void PLL_Init(void) /PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) /锁相环时钟=2*
7、16*(2+1)/(1+1)=48MHz REFDV=1; /总线时钟=48/2=24MHz SYNR=2; while(!(CRGFLG&0x08); CLKSEL=0x80; /选定锁相环时钟 # define LCD_DB PORTB# define LCD_RS PORTA_PA0# define LCD_RW PORTA_PA1# define LCD_E PORTA_PA2void LCD_init(void);/初始化函数void LCD_write_command(uchar command);/写指令函数void LCD_write_data(uchar dat);/写数据函
8、数void LCD_disp_char(uchar x,uchar y,uchar dat);/在某个屏幕位置上显示一个字符,X(0-16),y(1-2)/void LCD_check_busy(void);/检查忙函数。我没用到此函数,因为通过率极低。void delay_n25us(uint n);/延时函数/*/*初始化函数*void LCD_init(void)LCD_write_command(0x38);/设置8位格式,2行,5x7LCD_write_command(0x0c);/整体显示,关光标,不闪烁LCD_write_command(0x06);/设定输入方式,增量不移位LC
9、D_write_command(0x01);/清除屏幕显示delay_n25us(10);/实践证明,我的LCD1602上,用for循环200次就能可靠完成清屏指令。/LCD_write_command(0x06);/LCD_write_command(0x0c);/*写指令函数*void LCD_write_command(uchar dat)LCD_DB=dat;delay_n25us(1);LCD_RS=0;/指令LCD_RW=0;/写入LCD_E=1;/允许LCD_E=0;/实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。/*/*写数据函数*void LCD_wri
10、te_data(uchar dat)LCD_RS=1;/数据/*显示一个字符函数*void LCD_disp_char(uchar x,uchar y,uchar dat)uchar address;if(y=1) address=0x80+x;else address=0xc0+x;LCD_write_command(address);LCD_write_data(dat);/*检查忙函数*void LCD_check_busy() /实践证明,在我的LCD1602上,检查忙指令通过率极低,以 /至于不能正常使用LCD。因此我没有再用检查忙函数。而使do /用了延时的方法,延时还是非常好用的
11、。我试了一下,用 LCD_E=0; /for循环作延时,普通指令只要1次循就可完成。清屏指令 LCD_RS=0; /要用200次循环便能完成。 LCD_RW=1; LCD_DB=0xff; LCD_E=1; while(LCD_DB7=1);*/*延时函数*void delay_n25us(uint n) uint i=0; uchar j=0; for(i=n;i0;i-) for(j=0;j2;j+); /在这个延时循环函数中我只做了2次循环, /实践证明我的LCD1602上普通的指令只需1次循环就能可靠完成。void check_key(void) /判断按键是否可以控制单片机(如果键入
12、正常,则单片机上的LED会亮 if(!PORTAB_PA4) PORTE_PE5 = 0; a=1; else if(!PORTAB_PA5) a=2;PORTAB_PA6) a=3; PORTAB_PA7) a=4; else PORTE_PE5 = 1;/*主函数*void port_init() DDRB=0XFF; DDRA=0XFF; PORTB=0XFF;void main(void) /PLL_Init(); port_init(); LCD_init(); DDRE_DDRE5 = 1; /不亮 /*DDRA_DDRA0 = 1; DDRA_DDRA1 = 1; DDRA_DD
13、RA2 = 1; DDRA_DDRA3 = 1;*/ DDRA_DDRA4 = 0; /SET PORTA I/O INPUT DDRA_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(); /* feeds the dog */ check_key(); /检查按键 while(1) /*if (a=1) delay(10);*/ /延时去抖 if(a
14、=1) LCD_disp_char(0,2, /在LCD第二行第一位输出1 /*else if (a=2) else if(a=2) LCD_disp_char(1,2,2 /在LCD第二行第二位输出2 /*else if (a=3) else if(a=3) LCD_disp_char(2,2,3 /在LCD第二行第3位输出3 /*else if (a=4)/延时去抖 else if(a=4) LCD_disp_char(3,2,4 /在LCD第二行第4位输出4 / else LCD_disp_char(12,1,0 / / LCD_disp_char(2,1, /* loop foreve
15、r */ /* please make sure that you never leave main */七、调试过程(1)使用Altium画出电路图:在电路图设计过程中,注明所用器件名称,规格,注意管脚的连接,尽可能让电路原理图规范,正确,方便看图焊接的工作。(2)测量电路焊接是否正常:焊接好电路板后,首先用万用表测试是否连通,将表笔两端分别置于连接的两管脚,将万用表开关置于分贝档,若有响声,则电路已经联通,分别测试该设计所用的所有管脚。(3)检验输入I0:用万用表分别检测4个按键,看按键是否起到输入作用。将万用表开关置于电压档,分别测试按键按下前后的单片机电压。若按键前电压为5v,按键后为
16、0,则说明按键起到了输入的作用。(4)输出IO端口:输出口主要检验lcd1602的显示情况,首先用万用表测试,检查LCD1602管脚链接是否有问题。LCD1602的VEE串联一个电位器后接地,通过调节电位器,调节显示对比度,否则即使初始化程序正确,字符也可能显示不出来。(5)程序:程序中主要注意Lcd1602显示部分,因为LCD1602相对于单片机速度比较慢,所以在编写程序时应注意加延时。八、遇到的问题及解决办法 (1)初次焊接LCD1602后,屏幕不亮首先检查了电路板的焊接,及查阅了LCD1602的数据手册,因为使用的1602为16个管脚,需要将BLK接电源。(2)BDM仿真器下载不上程序
17、重新安装BDM仿真器,确认文件已拷入相应的路径。(3)重复下载程序后lLCD1602不显示 在检查硬件电路没有问题后,检查程序,并单步执行,发现初始化1602时循环次数设置过高。(4)LCD1602初始化成功后不能正常显示字符根据LCD1602连接电路图,发现D0-D7应接10K左右的排阻,然后与核心板引脚相连。 (5)LCD1602显示比较模糊 根据1602的使用手册,V0与GND相连的中间应接入10K左右电阻,并且电阻值越小对比度越大。(6)按键不起作用检查电路连接,发现上拉电阻接法错误,并改正。(7)按键输入的数字显示并不稳定在检查硬件电路没问题后,检查程序,查阅资料当得知,LCD1602需要初始化且速度较慢,所以应在初始化LCD1602时加入延时。九、附:图片截屏图1.使用FreescaleCodeWarrior软件编写程序图2.使用BDM仿真器下载程序图3.硬件电路板设计:九、实验总结与体会通过本次实习,使我对LCD1602及飞思卡尔单片机的应用都有了很深的理解,这是第一次独立的把软件及硬件相结合,包括改写程序及焊接电路板,整个过程中也有不成功的时候,例如在硬件的电路设计时,忽略了上拉电阻,导致LCD根本不能显示,在软件编程方面,因为缺少延时,LCD显示不正常,但经过不断修改检验,最终完成了本次的实习项目,使我对电子信息工程这个专业也有了深入的了解。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1