文章导航
大三上嵌入式实验报告4 5
(一)实验目的
较全面掌握RL78/G13系列嵌入式微控制器的程序设计技术。 利用基础模块设计实验的积累,完成较为复杂的综合实验任务。
(二)实验要求
第四次: 在前三周工程的基础上,学习并调通例程文件夹里RL78_FunctionDemoCodenew例程,在第3次工程基础上,添加完成在LCD循环显示不同的界面:1、个人信息(或自己设计的显示内容,键盘可以输入,修改后的内容参与新一轮的循环显示),2、代表交大的图片,3、谢谢+“笑脸”图片;实验后写好实验报告下次实验提交(电子版),实验报告包括实验步骤(必要时截图),附上所添程序段并标明位置,运行结果拍图或视频、工程文件。 第五次: 新建工程,要求设计一个菜单并在液晶上显示(例如:秒表、个人信息、图片循环显示),通过按键选择并启动菜单项,实现第2-4次实验所有功能。实验后写好实验报告下次实验提交(电子版),实验报告包括实验步骤(必要时截图),附上所添程序段并标明位置,运行结果拍图或视频、工程文件。
(三)程序分析
1.实现输入信息、循环播放
使用了一个标志变量mydisplay,初始化置其值为0。在主循环刚开始再加入一个循环,做输入循环,循环条件为mydisplay=0在这个循环内可以实现前面几次实验所提到的功能。包括显示姓名班级学号、定时计数、还有输入日期(包括日期的删除修改等等)。在确认输入完毕以后按下16键,置mydisplay为1,跳出输入循环。此时程序进入主循环,由于标志变量mydisplay=1,在每次执行到输入循环位置时,都不进如循环,实现笑脸、交大图片、个人信息的循环播放。其中,个人信息(包括输入的日期)用数组实现,对日期的输入即为对数组的修改,在循环播放时调用的是同一个数组,因此实现了输入信息加入循环的要求。
程序流程图如下:
2.实现菜单选择
前面的实验虽然实现了功能,但是其本身还有一些小问题,比如说日期只能输入一次,加入循环以后就不能修改内容。因此我定义了一个菜单界面,在菜单界面可以选择修改信息,定时计数,循环播放。在修改、计数界面可以进行前面几次实验的定时、修改信息等等功能;在循环播放界面可以实现第四次实验的循环播放图片功能,而且个人信息保留为最后一次修改的内容。 在菜单界面按1进入修改、计数界面,按2进入循环播放界面。在另外两个子界面按16即可退出。 为了保证程序的可读性,我把两个子界面的功能封装为两个子函数void setdate() 和void Loop_display(),在主函数中直接调用即可实现功能。 程序流程图如下:
(四)程序代码
1.实现输入信息、循环播放
1)输入日期循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| while (mydisplay==0) { lcd_display(0," 任泽华 " " 自动化71班 " " 2171411498 "); lcd_display(48,date); Keyboard_scan(); if(num_keyboard==14){sflag=1;} if(sflag==1)num_10 = num/10; else {num=0;num_10=0;} if(bflag==0 && num_10==10){ R_PCLBUZ0_Start(); bflag=1; delaya();R_PCLBUZ0_Stop();} if(num_keyboard==13){bflag=0; num=0;num_keyboard=0;sflag=0;}
if(num_keyboard!=0) display(); if(num_keyboard==13){bflag=0; num=0;num_keyboard=0;sflag=0;} leddispaly();
NOP(); WDTE = 0xAC; if(num_keyboard==16) {num_keyboard=0; mydisplay=1;break;} }
|
2)循环显示(主循环)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| while (1U) { while (mydisplay==0) { } lcd_write(0x01,0); LcdFill_REC(); delayb(1000); delayb(1000); WDTE = 0xAC; lcd_displayth(0,string); delayb(1000); delayb(1000); WDTE = 0xAC; LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); WDTE = 0xAC; LcdFill_REC2(); delayb(1000); delayb(1000); WDTE = 0xAC; LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); LcdFill_REC3(); delayb(1000); delayb(1000); WDTE = 0xAC; LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); lcd_display(0," 任泽华 " " 自动化71班 " " 2171411498 "); lcd_display(48,date); delayb(1000); delayb(1000); lcd_write(0x01,0); delayb(1000); delayb(1000); }
|
3)半屏显示笑脸的子函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void lcd_displayth(unsigned char pos, void *str) { unsigned char *p, *p1; unsigned char i,lenth; if(pos > 63) return; p = p1 = (unsigned char *)str; lenth = 0; while(*p1) { lenth++; p1++; if(lenth >= 64 - pos) break; } if((pos%16)!=0) CursorSet(pos); for(i = pos; i - pos < lenth; i++) { if(i == 0) lcd_write(0x80+4, 0); else if(i == 8) lcd_write(0x90+4, 0); else if(i == 16) lcd_write(0x88+4, 0); else if(i == 24) lcd_write(0x98+4, 0); lcd_write(*p++, 1); delay(200); } }
|
2.实现菜单选择
1)主循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| while (1U) { lcd_display(0," 菜 单 " "1.键盘输入 定时" "2.循环显示图片 " "3.按16退出 ");
Keyboard_scan(); switch(num_keyboard) { case(1):mydisplay=0;setdate();break; case(2):Loop_display();break; }
}
|
2)输入日期的子函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| void setdate() { while (mydisplay==0) { num_keyboard=0; lcd_display(0," 任泽华 " " 自动化71班 " " 2171411498 "); lcd_display(48,date); Keyboard_scan(); if(num_keyboard==14){sflag=1;} if(sflag==1)num_10 = num/10; else {num=0;num_10=0;} if(bflag==0 && num_10==10){ R_PCLBUZ0_Start(); bflag=1; delaya();R_PCLBUZ0_Stop();} if(num_keyboard==13){bflag=0; num=0;num_keyboard=0;sflag=0;}
if(num_keyboard!=0) display(); if(num_keyboard==13){bflag=0; num=0;num_keyboard=0;sflag=0;} leddispaly(); NOP(); WDTE = 0xAC; if(num_keyboard==16) {num_keyboard=0; mydisplay=1;lcd_write(0x01,0);break;} } }
|
3)循环显示子函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| void Loop_display() { while(1) { Keyboard_scan();if(num_keyboard==16){num_keyboard=0; LcdClear();break;} lcd_write(0x01,0); LcdFill_REC(); delayb(1000); delayb(1000); WDTE = 0xAC; Keyboard_scan();if(num_keyboard==16){num_keyboard=0;LcdClear(); break;} lcd_displayth(0,string); delayb(1000); delayb(1000); WDTE = 0xAC; Keyboard_scan();if(num_keyboard==16){num_keyboard=0;LcdClear(); break;} LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); WDTE = 0xAC; Keyboard_scan();if(num_keyboard==16){num_keyboard=0;LcdClear(); break;} LcdFill_REC2(); delayb(1000); delayb(1000); WDTE = 0xAC; Keyboard_scan();if(num_keyboard==16){num_keyboard=0; LcdClear();break;} LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); LcdFill_REC3(); delayb(1000); delayb(1000); WDTE = 0xAC; Keyboard_scan();if(num_keyboard==16){num_keyboard=0;LcdClear(); break;} LcdClear(); lcd_write(0x01,0); delayb(1000); delayb(1000); lcd_display(0," 任泽华 " " 自动化71班 " " 2171411498 "); lcd_display(48,date); delayb(1000); delayb(1000); lcd_write(0x01,0); delayb(1000); delayb(1000); Keyboard_scan();if(num_keyboard==16){num_keyboard=0;LcdClear(); break;} } }
|
(五)实验效果(详见视频)
(六)实验总结
在刚开始我第四次实验的功能是轮流播放笑脸、交大图片以后停在输入日期界面不动,等输入完成以后继续轮流播放,到此处以后仍然不动。老师说这并不是实验要实现的功能。经过思考与讨论,我决定采用双重循环的方式,通过标志变量的修改实现输入与循环的切换。第五次实验当中有一个小问题,就是在循环显示图片的时候不能同步实现对键盘的扫描,无法按键退出。我想到的办法是每幅图片播放完成以后扫一次键盘,这样就能实现按键的响应。 本次实验是瑞萨开发板的最后一次实验,这几周对于瑞萨开发板的学习让我收获良多。瑞萨也是我接触到的第一个嵌入式系统开发板,刚刚接触一个全新的软件,确实有些困难,按着老师的教程和视频一步步建立自己的第一个工程。其实这都是涉足一个新领域所必然经历的,经过几次实验,我对于这个软件的一些功能已经有了一些了解,也可以在读懂例程的基础上进行一些修改,加入自己的功能。我明白了在实际的工程当中,有时在一开始就完完全全搞懂一个东西是不现实的,应该先做起来,动手去运行一些例程代码,修改一些参数观察输出情况。然后在他人工作的基础上增加一些自己的东西。这对于新手来说是一个很快掌握一项技能的好方法。在老师的耐心指导和与同学们的探讨中,我逐渐学会了如何写代码,如何打断点调试,出了问题要怎么排查。这个过程虽然痛苦,但是真正把问题想明白了以后的心情是非常开心的。看着自己一行行敲出来的代码可以实现一个小小的功能,心里也会有小小的成就感。 就像老师说的,我们这些实验虽然是验证型的,也就是重复做别人做过的东西,但是我们正是在不断地实验中发现自己的短板,磨练自己的代码能力与思维能力。从这个方面来说,我认为这次的实验对我来说是很有意义的。