小学期单片机设计实验报告.docx
- 文档编号:10509751
- 上传时间:2023-05-26
- 格式:DOCX
- 页数:44
- 大小:612.51KB
小学期单片机设计实验报告.docx
《小学期单片机设计实验报告.docx》由会员分享,可在线阅读,更多相关《小学期单片机设计实验报告.docx(44页珍藏版)》请在冰点文库上搜索。
小学期单片机设计实验报告
2012年小学期单片机设计实验报告
题目:
基于PIC32的电子宠物
班级:
班内序号:
学号:
学生姓名:
指导教师:
葛顺民老师
基于PIC32的电子宠物娱乐系统
--*************
实验摘要:
我们制作的电子宠物娱乐系统是一个基于Microchip公司生产的PIC32MX795F512L单片机的小型娱乐系统。
该系统可以实现选择领养的宠物,给宠物喂食、洗澡、睡觉、抚摸以及看医生等一系列人性化操作,用单片机内置的计时器以及中断来控制宠物各项生命指标的变化,通过显示宠物的各项生命值、自定义字符以及LED灯的亮暗程度来提醒玩家选择操作。
整个娱乐系统非常贴近小时候我们玩过的学习机上的电子宠物,操作人性化,并且较全面地运用了单片机的核心知识。
在该电子宠物娱乐系统的实现中,我们使用了计时器、中断优先级、自定义字符、PWM脉冲宽度调制等单片机技术,通过mplab编程软件实现电子宠物的功能,先在面包板上调试,再用焊接固定所用的单片机以及外部设备。
Abstract
TheelectronicpetentertainmentsystemwemadeisbasedonPIC32MX795F512LmadebytheMicrochipcompany.Theentertainmentsystemcanrealizesuchfunctionsaschoosingapet,feedingthepet,helpingthepettobathandsleep,pattingthepetandsendingittoadoctor.Weusethetimerandinterruptsectorsbuiltinthechiptochangethelifeindexofyourpet.Thegameplaycandecidewhattodobyshowingthepet’svariouslifeindexvalue,thecustomcharacterandthelightintensityoftheLEDlamp.Theentertainmentsystemisveryclosetotheelectronicpetweplayedinourchildhoodandtheoperationishumanity.ItalsoexcisesustousetheSCMmoreskilled.
Intherealizationofthiselectronicpet,weusethetimer,interruptpriority,customcharacters,PWMpulsewidthmodulation.Werealizetheelectronicpetfunctionsbyusingthemplabprogrammingsoftware.Firstly,wedebuggedonthebreadplate.Thenweweldedalltheequipment.
关键字
单片机——microcontroller脉宽调制——pulsewidthmodulation
计时器——timer中断优先级——interruptpriority
一.实验论证与比较:
1.显示屏设置:
将控制显示屏显示的C语言工程捎进PIC主机,通过PIC芯片与显示屏的连接控制显示屏的输出。
我们实验采用的LCD1602型号的显示屏,使用了LCD的1—16号引脚,其中引脚1,、3、16接地,引脚2,15接5V正电源,RS,R/W,E用来控制输入指令和数据,写入或读取信息,产生下降沿脉冲使能信号。
7—14引脚用来做输入输出端口,15和16引脚用来调节背光度。
在每次显示时,都会采用delay函数进行延迟处理,以便玩家有足够时间看清楚显示屏上的显示。
图一LCD显示屏
/*********************液晶初始化函数定义*************************************/
voidInitscreen()//初始化函数
{
write_com(0x38);//初始化液晶
delay1(20);
write_com(0x0c);//不显示光标也不闪烁
delay1(20);
write_com(0x06);//光标向右移
delay1(20);
write_com(0x01);//屏幕清零
delay1(20);
write_com(0x80);//第一行光标定位
}
/*********************显示各项指标*************************************/
voidshow(ucharh,ucharb,uchars,ucharp)
{
if(hunger>98)
{
hunger=0;
write_com(0x01);
Write_ListChar(0,0,"foodenough!
");
delay1(100000);
}
if((sleep>10)&&(sleep<12))
{
sleep=10;
write_com(0x01);
Write_ListChar(0,0,"sleepenough!
");
delay1(100000);
}
if((pat>10)&&(pat<12))
{
pat=10;
write_com(0x01);
Write_ListChar(0,0,"patenough!
");
delay1(100000);
}
if((bath>10)&&(bath<12))
{
bath=10;
write_com(0x01);
Write_ListChar(0,0,"bathenough!
");
delay1(100000);
}
write_com(0x01);
Write_ListChar(0,0,"hunger:
");
change(hunger);
Write_ListChar(0,8,y);
delay1(60000);
ucharhe=health(b,s);
Write_ListChar(1,0,"health:
");
change(he);
Write_ListChar(1,8,y);
delay1(60000);
write_com(0x01);
ucharmo=mood(h,b,s,p);
Write_ListChar(0,0,"mood:
");
change(mo);
Write_ListChar(0,7,y);
delay1(60000);
Write_ListChar(1,0,"Whattodo?
");
delay1(60000);
write_com(0x01);
Write_ListChar(0,0,"1feed2bath3sleep");
Write_ListChar(1,0,"4pat5doctor");
//delay1(30000);
uinti=0;
for(i=0;i<3;i++)
write_pic(i,pic[i]);
write_com(0xc0+0x0c);
for(i=0;i<0x03;i++)
write_data(i);
delay1(30000);
}
2.键盘设置:
键盘共有四行四列,8个引脚,通过行列扫描的方式确定按下的是哪一个按键,先确定列,再确定行,返回PIC主机进行处理。
为了防止键盘误读,在每次扫描键盘值之间加入了一次防抖动检测,以提高键盘按键性能的稳定性。
图二矩阵键盘
按键
功能
1键
喂食
2键
洗澡
3键
睡觉
4键
抚摸
5键
看医生
表一键盘功能
/*********************键盘函数*************************************/
ucharkbscan()
{
unsignedintrow,col;
uintflag=0,a=1,b=1,c=1,d=1;
ucharkey;
PORTClearBits(IOPORT_B,BIT_9|BIT_12|BIT_13|BIT_14);
PORTSetBits(IOPORT_B,BIT_12|BIT_13|BIT_14);
a=y1;b=y2;c=y3;d=y4;
if((a&b&c&d)!
=1)
{
delay1(1000);
if((a&b&c&d)!
=1)
{
flag=1;
row=1;
if(a==0)col=1;
if(b==0)col=2;
if(c==0)col=3;
if(d==0)col=4;
}
}
if(flag!
=1)
{
PORTClearBits(IOPORT_B,BIT_9|BIT_12|BIT_13|BIT_14);
PORTSetBits(IOPORT_B,BIT_9|BIT_13|BIT_14);
a=y1;b=y2;c=y3;d=y4;
if((a&b&c&d)!
=1)
{
delay1(1000);
if((a&b&c&d)!
=1)
{
flag=1;
row=2;
if(a==0)col=1;
if(b==0)col=2;
if(c==0)col=3;
if(d==0)col=4;
}
}
}
if(flag!
=1)
{
PORTClearBits(IOPORT_B,BIT_9|BIT_12|BIT_13|BIT_14);
PORTSetBits(IOPORT_B,BIT_9|BIT_12|BIT_14);
a=y1;b=y2;c=y3;d=y4;
if((a&b&c&d)!
=1)
{
delay1(1000);
if((a&b&c&d)!
=1)
{
flag=1;
row=3;
if(a==0)col=1;
if(b==0)col=2;
if(c==0)col=3;
if(d==0)col=4;
}
}
}
if(flag!
=1)
{
PORTClearBits(IOPORT_B,BIT_9|BIT_12|BIT_13|BIT_14);
PORTSetBits(IOPORT_B,BIT_9|BIT_12|BIT_13);
a=y1;b=y2;c=y3;d=y4;
if((a&b&c&d)!
=1)
{
delay1(1000);
if((a&b&c&d)!
=1)
{
flag=1;
row=4;
if(a==0)col=1;
if(b==0)col=2;
if(c==0)col=3;
if(d==0)col=4;
}
}
}
if(flag!
=0)
{
if(row==1&&col==1)key='1';
if(row==1&&col==2)key='2';
if(row==1&&col==3)key='3';
if(row==1&&col==4)key='4';
if(row==2&&col==1)key='5';
if(row==2&&col==2)key='6';
if(row==2&&col==3)key='7';
if(row==2&&col==4)key='8';
if(row==3&&col==1)key='9';
if(row==3&&col==2)key='0';
if(row==3&&col==3)key='A';
if(row==3&&col==4)key='B';
if(row==4&&col==1)key='C';
if(row==4&&col==2)key='D';
if(row==4&&col==3)key='E';
if(row==4&&col==4)key='F';
}
else
key='P';
returnkey;
}
3.宠物生命状态模块:
宠物的生命状态由4个参数和两个指数控制。
四个参数为:
hunger饥饿程度,bath洗澡值,sleep睡觉值,pat抚摸值。
两个指数为:
健康指数health,心情指数mood。
四个参数由时间控制,而两个指数,即健康指数和心情指数由上述4个参数所计算得来。
每过一段时间,hunger值加一,bath,sleep,pat分别减一,表示宠物变饿了,而更需要洗澡,睡觉和主人的安抚。
health=5*sleep+5*bath,mood=(10-hunger)*2+bath*2+sleep*2+pat*2,分别反映宠物的健康和心情如何。
当宠物的饥饿程度hunger=10时宠物饿死,健康指数health<5时宠物生病死了,心情指数mood<30宠物心情抑郁而离家出走。
/*********************健康指数的计算*************************************/
ucharhealth(ucharb,uchars)
{
ucharh=b*5+s*5;
if(h>100)
h=100;
returnh;
}
/*********************心情指数的计算*************************************/
ucharmood(ucharh,ucharb,uchars,ucharp)
{
ucharm=(10-h)*2+b*2+s*2+p*4;
if(m>100)
m=100;
returnm;
}
4.计时器中断模块:
我们设置了两个计时器中断,一个用来计算宠物生命状态,一个用来使用PWM脉冲宽度调制控制小灯亮度。
为了计算宠物各项生命值(饥饿程度hunger,洗澡值bath,睡觉值sleep,抚摸值pat,健康指数health,心情指数mood),我们设置的计时器中断优先级为3,每隔固定时间改变一次宠物各项生命数值(当到了该固定时间时,若有按键操作则先处理中断里的改变参数操作)hunger++,bath--,sleep--,pat--,health=bath*5+sleep*5,mood=(10-hunger)*2+bath*2+sleep*2+pat*4,从而确定此时宠物的生命状态。
为了通过宠物的饥饿程度控制小灯的亮度——当hunger饥饿程度越高时小灯越亮,hunger饥饿程度越低时小灯越暗,采用了优先级为2的计时器中断。
每隔固定时间检测hunger值的变化,通过调制电压方波的占空比来改变小灯的亮度。
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。
通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
高电平时间越长,灯就越亮,即占空比越大灯越亮。
从而可以采用PWM技术实现控制小灯的亮暗变化,从而给游戏玩家提供信息决定是否喂食。
void__ISR(_TIMER_3_VECTOR,ipl1)T3InterruptHandler(void)
{
asm("ei");
if(mT3GetIntFlag())
{
num++;
if(num>100)
{
hunger++;
pat--;
bath--;
sleep--;
num=0;
}
mT3ClearIntFlag();
}
}
void__ISR(_TIMER_2_VECTOR,ipl3)T2InterruptHandler(void)
{
asm("ei");
uinti,t;
if(mT2GetIntFlag())
{
for(i=1;i<=10-hunger;i++);
LED=1;
for(i=1;i<=hunger;i++);
LED=0;
mT2ClearIntFlag();
}
}
三.系统总体设计:
图三整体流程图
1.宠物生命状态控制模块:
宠物的生命状态由4个参数,2个指数控制,hunger饥饿程度,bath洗澡值,sleep睡觉值,pat抚摸值,健康指数health,心情指数mood。
而两个指数,即健康指数和心情指数由上述4个参数所计算得来。
每隔固定时间,进入一次中断,在中断里改变标志位,在主程序中通过判断标志位来改变4个参数的值,从而改变两个指数的值。
hunger取值0-10,值越大表示宠物越饥饿;bath、sleep、pat取值0-10,随时间下降;health和mood取值0-100,值越大表示越健康,心情越好。
当宠物饥饿值hunger达到10,宠物饥饿而死;当宠物健康指数health达到0,宠物生病而死;当宠物心情指数mood达到30,宠物抑郁而逃。
至此本轮游戏结束。
通过按键操作,改变宠物的4个参数值,每按一次1-4键,相应的参数+1,按5键,bath和sleep设为10.
图四宠物生命状态流程图
2.警告灯模块:
为了提醒玩家及时给宠物喂食,设计了警告灯模块用来反映hunger的值变化,hunger取值为0-10,值越大表示宠物越饥饿,此时灯就越亮。
灯亮度控制模块采用PWM脉冲调制技术,流程图如下:
图五宠物饥饿警告灯流程图
三硬件连接:
图六PIC32MX795F512L引脚图
1.PIC32和显示屏连接:
鉴于硬件连接方便,我组采用了PIC的26~50和76~100号管脚。
先在面包板上组装电路,以便于调试,调试成功后使用焊接的方法将整个电路和外设焊接在电路板上。
PIC主板和显示屏管脚以及警示灯的具体连接如下:
图七单片机和显示屏管脚连接示意图
2.PIC32和矩阵键盘连接:
图八单片机和键盘管脚连接示意图
四.软硬件调试:
第一次接触单片机,在老师的入门指导下,上网查了一些资料并且看了一些单片机教程,决定了选择电子宠物这一课题,然后就边学边做地开始编程,连硬件了。
学习周期不长,所以做的过程中出现了各种各样的软硬件问题,一方面是我们组的三个同学一起商量,另一方面就是向老师求助,最后终于历经千辛万苦做完了这次小学期。
回想这四周来遇到的各种问题,很有必要做一下总结,也是为以后的学习积累经验,提供教训。
1.中断优先级问题:
由于我们做的电子宠物需要用时间来改变各项生命状态值,并且要避免与按键操作产生冲突,所以需要使用PIC的计时器和中断优先级。
我们参考了一本PIC32的教程上的中断计时器代码加到我们的代码里,可是一直出现问题,一开始根本无法进入计时器程序里,后来修改了一些代码之后,宠物死亡速度太快,并且经常出现奇怪的错误。
我们三个就查询其他的资料,结果不同资料上的代码也不同,也都没有详细的解释,经过思考和请教老师,发现我们的中断优先级代码有以下几个问题:
(1)少了计时器的初始值设定;
(2)重复开启优先级;(3)重新领养宠物时没有关闭上一次的计时器导致计时混乱。
(4)进入中断的时间太快导致无法进入主程序。
(5)中断函数里代码过长,并且含有延迟函数。
在老师的指导下,我们修改了中断优先级的开启代码,加入了关闭代码,并且在中断函数里加入了一个循环嵌套,加长了进入一次中断处理的时间。
在中断函数里用一个标记量,通过在中断里改变表计量的值,在主函数里判断是否需要修改宠物的生命状态值。
我们的程序里用到了两个不同级别的中断,一个是优先级为2的PWM控制灯亮度,一个是优先级为3的宠物生命状态值控制。
这样解决了上述的5个问题,实现了宠物的生命状态值功能,让宠物“活”了起来。
从处理中断优先级问题的过程中,我不仅学会了中断优先级的调用方法,还深刻地明白了一个道理,学习知识一定要透彻,不能一知半解,尤其是借用前人已有的知识时更要把知识的来龙去脉弄透彻了。
2.显示屏调试问题:
为了测试显示屏和硬件连接的好坏,我们写了一段很短的测试显示屏代码。
第一次测试显示屏时,显示屏显示出了正确的字符,可是过了一会显示屏什么都没有了,我们判定是硬件连接不紧的问题。
就把线又插进了一遍,插上电还没有反应。
之后我们用万能表测试每条线的通断,发现了有2根导线内部断了,还有的导线太松,我们换了新的导线,可是还没有结果。
我们又测了每一个管脚的高低电平,发现了PIC的底座有很多个口是完全松的,所以又换了一个底座,显示屏就完全正常了。
键盘没有任何接触不良的问题,所以没有什么调试。
我们总结了硬件调试的经验,连接导线之前一定要合理安排管脚的使用,尽量使连接导线时不要相互交叉太多,以免导线相互交叉影响接触。
连接导线时可以先把导线头弯一下,这样可以插得很紧。
还有插底座时注意底座是不是紧的,看一下里面是不是有的口已经很松了。
出现意想不到的错误时一定要冷静,一步步调试,充分利用万能表测试硬件各部分是否连通。
五实验心得体会
第一次接触单片机,第一次自己动手做软硬件结合的综合实验,在这四周里遇到的困难很多,但是收获的东西让这四周的付出变得很值得。
开始的第一周是第一阶段,主要任务是熟悉单片机的基础知识和选题。
在这一阶段的学习,确实在这个小学期里起到了奠基的作用。
首先看各种PIC的教程以及视频,然后是广泛查找选题资料。
开始我们想做一个语言识别的东西,通过和老师的交流发现语言识别的难度太大,并且专业知识远远不足。
兴趣是最好的老师,我们三个人都很怀念小时候玩的电子宠物游戏机,所以我们选择了这个我们感兴趣的项目——电子宠物。
决定题目之后,我们将大致的实验方案制作出来,写了一份开题报告。
第二阶段是确定管脚的使用,编写程序。
MPLAB我们是边学边用的,由于是基于C语言,所以难度相对较小一些。
编程的思想不仅要考虑到程序的是实现过程,也要顾忌到硬件的合理性。
为了使编程思想更明确,我们先写了一段伪代码,按照伪代码的流程分工编程。
软件的通过编译没遇到什么困难。
第三阶段是硬件的连接和软硬件结合的调试。
由于显示屏的接触不良浪费了很多时间。
我们充分使用了万用表、MPLAB的断点调试、管脚电平检测等调试方法,一一解决了各种硬件问题。
在不断的学习中,我学会了MPLAB的使用,学会了单片机的编程和硬件实现,学会了显示屏和键盘等外设的调试,最重要的是学会了软硬件结合的思想。
大学已经两年结束了,前两年一直在注重理
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 小学 单片机 设计 实验 报告