找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4144|回复: 0
打印 上一主题 下一主题
收起左侧

MSP430G2553实现乒乓球游戏机实验报告

[复制链接]
跳转到指定楼层
楼主
ID:343004 发表于 2018-6-1 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实验报告

实验名称:采用MSP430G2553 实现乒乓球游戏机
姓    名:
学    号:
指导教师:     张*         
实验时间:



目录
一、实验目的
二、实验内容与步骤
2.1实验内容:
2.2实验步骤:
三、系统设计
3.1  总体设计
3.2硬件:
3.3软件:
四、软件单元电路设计
4.1  PWM波信号产生单元
4.2  串口发送模块
4.3  定时中断程序
4.4  按键中断模块
4.5  Flash模块
六、硬件单路整体外观与显示效果
显示效果
七、 个人感想
八、 参考文献 与 附录
8.1参考文献:
8.2附录:
8.3全部代码:

摘要
MSP430单片机通过两条I/O 信号输出两组脉宽调制波,经过低通滤波器提取脉宽调制的均值电压,输入到双通道示波器中。示波器工作在X/Y 模式。示波器屏幕上的光电代表乒乓球。乒乓球在X/Y 电压的控制下在屏幕上移动。

实验题目:采用MSP430G2553 实现乒乓球游戏机
一、实验目的
1、通过此次实验掌握采用MSP430G2553编程的具体步骤;
2、串口编程中要掌握的包括串口的设置、串口的读写操作等;
3、熟悉模电硬件电路的设计与焊接;
4、掌握如何调试电路和软件编程的结合。
二、实验内容与步骤2.1实验内容:
1.构造两组无源低通滤波器,使得msp430 可以用脉宽调制方式控制球的位置
2.用给定的运放制作一放大器,使光点运动范围在示波器的X 轴,Y 轴方向上可调
3.乒乓球可按抛物线自动在屏幕上左右弹射,球的落点为屏幕两侧边的中间
4.使用两个按钮分别作为左侧击球按钮和右侧击球钮。当乒乓球靠近屏幕左边时
按下左侧击球钮,可将球击回右侧。右侧击球钮亦然
5.建立成败机制。即球抵达边沿而未按下击球按钮,记为击球失败,用LED 灯光表示
6.建立记分机制,用串口在电脑上上显示双方得分
7.特殊功能,在不调整放大器的情况下,连按两下击球钮能击出高抛球,轨迹抛物线曲率变大

8.利用片内flash 加入比分断电自保存功能

2.2实验步骤:
  • 先确定方案和硬件电路设计图。
  • 开始软件编程和硬件电路的焊接。
  • 下载程序,进行调试,优化程序。
三、系统设计
3.1  总体设计
      总体设计框图

3.2硬件:            
杜邦线连接P1.3、P1.4口到两个按键,P2.1和P2.5分别是两个PWM波输出分别连接到两个低通滤波器,然后接放大器,最后输入到双通道显示示波器,XY挡。

硬件设计图
3.3软件:
由单片机产生PWM波,写程序控制不同时间,给它不同的占空比,程序编写Flash程序,按键中断程序,串口发送程序。

四、软件单元电路设计4.1  PWM波信号产生单元
由Grace定时器生成代码,用Timer1可以出两路PWM波,由MatLab生成抛物线码表,根据要求不同X位置付给Y不同码表,三角波由x随Y线性自增实现。
    MatLab里生成抛物线的函数为
t=0:pi/4:201;
y=254*sin(pi/200.3*t);;%二次函数表达式(你改成自己的抛物线就行了)
stem(t,y);%画图
    得到256个数,在CCS开头即可定义一个码表,即
Const float y[256]={0,3.1288269,6.257179,9.384581,12.510560,15.634640,18.756348,21.875209,24.9907517633125,28.1025016646739,31.209987,34.312736,37.410279,40.502145,43.587865,46.666971,49.738995,52.803472,55.859936,58.907924,61.94697,64.976622,67.996411,71.0058819526576,74.004578,76.992044,79.967827,82.931476,85.882540,88.820572,91.745126,94.655758,97.552027,100.433493,103.299719,106.150269,108.984712,111.802617,114.603556,117.387106,120.15284,122.90034,125.62920,128.338991,131.029308,133.699741,136.349886523822,138.979341373364,141.587706913092,144.174587338650,146.739590105921,149.282325990597,151.802409147240,154.299457167832,156.773091139803,159.222935703532,161.648619109298,164.049773273701,166.426033835507,168.777040210944,171.102435648417,173.401867282641,175.674986188189,177.921447432436,180.140910127905,182.333037483992,184.497496858071,186.633959805973,188.742102131824,190.821603937241,192.872149669873,194.893428171287,196.885132724180,198.846961098927,200.778615599439,202.679803108336,204.550235131431,206.389627841501,208.197702121359,209.974183606210,211.718802725280,213.431294742727,215.111399797810,216.758862944320,218.373434189270,219.954868530829,221.502925995499,223.017371674528,224.497975759559,225.944513577501,227.356765624622,228.734517599854,230.077560437320,231.385690338050,232.658708800910,233.896422652726,235.098644077590,236.265190645368,237.395885339377,238.490556583247,239.549038266961,240.571169772056,241.556795995998,242.505767375717,243.417939910307,244.293175182869,245.131340381521,245.932308319553,246.695957454719,247.422171907687,248.110841479623,248.761861668909,249.375133687003,249.950564473430,250.488066709901,250.987558833567,251.448965049393,251.872215341657,252.257245484581,252.603997052071,252.912417426586,253.182459807121,253.414083216310,253.607252506641,253.761938365796,253.878117321089,253.955771743039,253.994889848037,253.995465700137,253.957499211956,253.880996144690,253.765968107235,253.612432554430,253.420412784405,253.189937935048,252.921042979582,252.613768721258,252.268161787165,251.884274621152,251.462165475874,251.001898403946,250.503543248230,249.967175631234,249.392876943636,248.780734331935,248.130840685224,247.443294621099,246.718200470693,245.955668262840,245.155813707386,244.318758177625,243.444628691884,242.533557894247,241.585684034429,240.601150946798,239.580108028544,238.522710217014,237.429117966199,236.299497222389,235.134019398984,233.932861350494,232.696205345691,231.424239039959,230.117155446816,228.775152908624,227.398435066492,225.987210829376,224.541694342377,223.062104954248,221.548667184106,220.001610687362,218.421170220877,216.807585607335,215.161101698851,213.481968339819,211.770440328998,210.026777380847,208.251244086115,206.444109871692,204.605648959725,202.736140326006,200.835867657637,198.905119309987,196.944188262929,194.953372076390,192.932972845190,190.883297153206,188.804656026851,186.697364887869,184.561743505483,182.398115947864,180.206810532957,177.988159778663,175.742500352378,173.470173019910,171.171522593766,168.846897880830,166.496651629432,164.121140475824,161.720724890061,159.295769121299,156.846641142526,154.373712594723,151.877358730469,149.357958356999,146.815893778722,144.251550739210,141.665318362662,139.057589094854,136.428758643596,133.779225918677,131.109392971336,128.419664933254,125.710449955077,122.982159144481,120.235206503788,117.470008867146,114.686985837276,111.886559721796,109.069155469145,106.235200604094,103.385125162874,100.519361627920,97.6383448622435,94.7425120434471,91.8323025973826,88.9081581314717,85.9705223676945,83.0198410752579,80.0565620029519,77.0811348112064,74.0940110038585,71.0956438596384,68.0864883633880,65.0670011370189,62.0376403702228,58.9988657509443,55.9511383956251,52.8949207792330,49.8306766650837,46.7588710344675,43.6799700160909,40.5944408153444,37.5027516434067,34.4053716461967,31.3027708331826,28.1954200060616,25.0837906873179,21.9683550486719,18.8495858394310,15.7279563147526,12.6039401638308,9.47801143801569,6.35064447888023,3.22231384624036,0};//256个数
产生三角波的部分:
  1. if(w_ctl1==0)

  2. {

  3. TA1CCR1++;

  4. }

  5. if(w_ctl1==1)

  6. {

  7.     TA1CCR1--;

  8. }

  9. 其中w_ctl1为一个标志位,当其为0时代表球往右移,当其为1时代表球往左移。

  10. 产生抛物线的部分:

  11. int h=1;//曲率,双击时h=2

  12. TA1CCR2=h*y[j];//上升

  13. j=j+1;

  14. if(j==256) j=0;

  15. __delay_cycles(250000);

  16. 产生两路PWM波的函数为

  17. void Set_PWM(void)//无需中断输出两路PWM

  18. {

  19.               //使用系统初始化时的默认时钟1MHz,定时器A1专门用于产生PWM 波形。

  20.               TA1CTL = TASSEL_2 + MC_1 + ID_0;//使用系统次主机SMCLK、增计数模式、无分频

  21. //              TA1CCR0 = 256;//在16MHz的主频率下,16*10^6/TA1CCR0

  22.               TA1CCR0 = 800;//在16MHz的主频率下,16*10^6/TA1CCR0

  23.               TA1CCR1 = 0;

  24.               TA1CCR2 = 0;

  25.               TA1CCTL1 = OUTMOD_7;

  26.               TA1CCTL2 = OUTMOD_7;

  27.               P2SEL |= BIT1 + BIT5;//做第二功能使用(PWM输出)

  28.               P2DIR |= BIT1 + BIT5;//输出

  29. }
复制代码



4.2  串口发送模块
串口发送同样由Grace生成,直接调用Send_char()函数
根据判断不同标志位,判断何时发送比分,若球到达两端,没有击球,则停在边缘,判断停在边缘则计数。计数值改变时发送比分。
  1.            if(TA1CCR1==256)
  2.                                 {   w_ctl1=1;
  3.                                               P1OUT|=BIT6;
  4.                                               P1OUT&=~BIT0;
  5.                                               __delay_cycles(2000000);
  6.                                               P1OUT&=~BIT6;
  7.                                               ascore=ascore+1;
  8.                                               flash();
  9.                                               score[0]=ascore/10+'0';
  10.                                               score[1]=ascore%10+'0';
  11.                                               Send_Str(score);
  12.                                 }
  13.                                 if(TA1CCR1==0)
  14.                                 {  w_ctl1=0;
  15.                                    P1OUT|=BIT0;
  16.                                    P1OUT&=~BIT6;
  17.                                    __delay_cycles(2000000);
  18.                                    P1OUT&=~BIT0;
  19.                                    bscore=bscore+1;
  20.                                    flash();
  21.                                    score[3]=bscore/10+'0';
  22.                                    score[4]=bscore%10+'0';
  23.                                    Send_Str(score);
  24.                                 }                 
  25.        score[0]=a/10+0x30;
  26.                   score[1]=a%10+0x30;
  27.                   score[3]=b/10+0x30;
  28.                   score[4]=b%10+0x30;
  29.        Send_Str(score);
  30.     }
复制代码
4.3  高抛的实现

主函数while(1)里

  1. if(a==1)

  2.                                 {a=0;h=1;}

  3.                                 if(b==1)

  4.                                 {b=0;h=1;}

  5.                                   if(a==2)// p1.3双击

  6.                                              {a=0;h=2;}

  7.                                 if(b==2)//p1.4双击

  8.                                 {b=0;h=2;}

  9.             TA1CCR2=h*y[j];//上升

  10.             j=j+1;

  11.                                 if(j==256) j=0;

  12.                                 __delay_cycles(250000);
复制代码
  1. 4.4  按键中断模块

  2. 用按键中断,用P1.3   P1.4口开启按键中断,进入中断时判断是哪个I/O 口,然后置不同的标志位,以便定时中断查询,进入不同的状态。在中断里再定义一个按键Push_Key1,若在一定时间内按下两次按键,则判断为高抛,h的值变为2。
  3. unsigned int Push_Key1 = 0;
  4. unsigned int Push_Key = 0;
  5. #pragma vector=PORT1_VECTOR
  6. __interrupt void PORT1_ISR(void)
  7. {
  8. P1_IODect();//检测通过,则会调用事件处理函数
  9. P1IFG=0;              //退出中断前必须手动清除IO口中断标志
  10. }
  11. void P1_IODect()
  12. {
  13. //              unsigned int Push_key = 0;
  14. Push_Key = P1IFG&(~P1DIR); //排除输出IO的干扰后,锁定唯一被触发的中断标志位
  15. __delay_cycles(10000); //延时一段时间,避开机械抖动区域(延时消抖)
  16. if((P1IN&Push_Key) == 0) //判断按键状态是否与延时前一致,若该次按键确实有效,继续往下执行
  17. {
  18. //----判断具体哪个IO被按下,调用该IO的事件处理函数----
  19. switch(Push_Key)
  20. {
  21. case BIT3: P13_Onclick();break; //调用中断事件处理函数
  22. case BIT4: P14_Onclick();break;
  23. default: break; //任何情况下均加上default
  24. }
  25. }
  26. }
  27. VoidP13_Onclick()
  28. {
  29. a=1;
  30. __delay_cycles(3200000);
  31. Push_Key1=P1IFG&(~P1DIR);
  32. __delay_cycles(10000);
  33. if((P1IN&Push_Key1)==0)
  34. {
  35. if(Push_Key==Push_Key1)
  36. a=2;
  37. }
  38. if(w_ctl1==0)//球往右移且过界
  39. {
  40. If
  41. ((j<255)&(j>127))
  42. {
  43. w_ctl1=1;//往左打
  44. j=256-j;
  45. }
  46. }
  47. }
  48. voidP14_Onclick()
  49. {
  50. b=1;
  51. __delay_cycles(3200000);
  52. Push_Key1=P1IFG&(~P1DIR);
  53. __delay_cycles(10000);
  54. if((P1IN&Push_Key1)==0)
  55. {
  56. if(Push_Key==Push_Key1)
  57. b=2;
  58. }
  59. if(w_ctl1==1)//球往左移且过界
  60. {
  61. if((j<255)&(j>127))
  62. {w_ctl1=0;//往右打
  63. j=256-j;
  64. }

  65. }

  66. }

  67. 4.5 Flash模块
  68. 定义一个函数,包括了Flash的擦写任务。

  69. /***************写flash***************/
  70. void flash()
  71. {
  72.               FCTL1=FWKEY+ERASE;
  73.                             FCTL2=FWKEY+FSSEL1+2;
  74.                             FCTL3=FWKEY;
  75.                             *(Addr1)=0x00;
  76.                             *(Addr2)=0x00;
  77.                             FCTL1=FWKEY;
  78.                             FCTL3=FWKEY+LOCK;

  79.                             FCTL1=FWKEY+WRT;
  80.                             FCTL2=FWKEY+FSSEL1+2;
  81.                   FCTL3=FWKEY;
  82.                   *(Addr1)=ascore;
  83.                   *(Addr2)=bscore;
  84.                   FCTL1=FWKEY;
  85.                   FCTL3=FWKEY+LOCK;
  86. }
  87. 调用函数:
  88. if(TA1CCR1==256)
  89.                                 {   w_ctl1=1;
  90.                                               P1OUT|=BIT6;
  91.                                               P1OUT&=~BIT0;
  92.                                               __delay_cycles(2000000);
  93.                                               P1OUT&=~BIT6;
  94.                                               ascore=ascore+1;
  95.                                               flash();
  96.                                               score[0]=ascore/10+'0';
  97.                                               score[1]=ascore%10+'0';
  98.                                               Send_Str(score);
  99.                                 }
  100.                                 if(TA1CCR1==0)
  101.                                 {  w_ctl1=0;
  102.                                    P1OUT|=BIT0;
  103.                                    P1OUT&=~BIT6;
  104.                                    __delay_cycles(2000000);
  105.                                    P1OUT&=~BIT0;
  106.                                    bscore=bscore+1;
  107.                                    flash();
  108.                                    score[3]=bscore/10+'0';
  109.                                    score[4]=bscore%10+'0';
  110.                                    Send_Str(score);
  111.                                 }
  112. Main函数里:
  113. ascore = *Addr1;//要想掉电保存,flash不仅要写,还要读
  114. bscore = *Addr2;
  115. score[0]=ascore/10+'0';
  116. score[1]=ascore%10+'0';
  117. score[3]=bscore/10+'0';
  118. score[4]=bscore%10+'0';
  119. Send_Str(score);
  120. 初始化里:
  121. #define Addr1 ((volatile unsigned short*)0x1000)
  122. #define Addr2 ((volatile unsigned short*)0x1008)
  123. unsigned int ascore=0,bscore=0,t=0;
复制代码


五、硬件单路整体外观与显示效果

6.2显示效果
、 个人感想
通过此次实验使我们对MSP430单片机控有了更加深刻的认识,各个功能有了更深的了解,熟悉运用了CCS开发软件,整个过程有很多不是很清楚的地方,但是通过查资料的方式,问题都迎刃而解,模电电路方面也有了很多提高,在调试电路方面也学到了很多东西,复习了模电知识,还学到了很多相关的知识。但是我们也存在很多问题,比如:
1.高抛方面在设置时间内试了很多次,延时过长会影响灵敏性。
2.模电方面焊接电路有些盲目,没有想好布局,就很容易乱,所以总是拆电路,要吸取教训,下次要细心想好布局,计算好数值。
3.有时候不要固定思维,要转换一下思考方式,好多东西都能迎刃而解。


1、原件清单
原件
个数
LM430放大器
一个(四个运放)
2.2μF电容
两个
20K电阻
四个
20K滑动变阻器
两个
按键
一个
探针
若干
电路板
一个
导线
若干
杜邦线
若干

完整的Word格式文档51黑下载地址:
msp430乒乓球游戏机.doc (505.4 KB, 下载次数: 10)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表