陈胜--实习报告

更新时间:2024-02-27 03:15:02 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实习报告

实习性质 实习单位 院 (系) 专业班级 姓 名 学 号 指导教师

认识与生产实习 西安建筑科技大学 信息与控制工程学院

2012年 09 月 05 日

目 录

1.激光枪自动射击装置(E题)【本科组】 .............................. 2

1.1任务 ........................................................ 2 1.2要求 ........................................................ 2

1.2.1基本要求 .............................................. 2

1.2.2发挥部分 .............................................. 3 1.3说明 ........................................................ 4 2.题目分析及设计方案论证与比较 ..................................... 5

2.1 系统总方案 ................................................. 5 2.2 单片机供电电源方案 ......................................... 5 3.系统设计 ......................................................... 6

3.1总体设计思路 ................................................ 6 3.2环数确定算法 ................................................ 7

3.2.1 方位确定算法 .......................................... 7 3.2.2 激光管的运动算法 ...................................... 8 3.3软件流程图 .................................................. 9 3.4系统模块设计 ............................................... 10

3.4.1 矩阵键盘 ............................................. 10 3.4.2 PWM波的生成 ......................................... 11 3.4.3 12864的显示 ......................................... 12

3.4.4串口通信 ............................................. 13 3.4.5 图像采集 ............................................. 16

4.实习总结 ........................................................ 17 附:系统部分程序 .................................................. 19

第 1 页

1.激光枪自动射击装置(E题)【本科组】

1.1任务

设计一个能够控制激光枪击发、自动报靶及自动瞄准等功能的电子系统。该系统由激光枪及瞄准机构、胸环靶、弹着点检测电路组成,其结构示意见图1。

1.2要求

1.2.1基本要求

(1) 用激光笔改装激光枪,激光枪可受电路控制发射激光束,激光束照射于胸环靶上弹着点的光斑直径<5mm;激光枪与胸环靶间距离为3m。

图1 激光枪自动射击装置示意图

(2) 激光枪固定在一机构上,可通过键盘控制激光枪的弹着点(用键盘设置激光束在靶纸上上下、左右移动一定距离)。

第 2 页

(3) 制作弹着点检测电路,通过摄像头识别激光枪投射在胸环靶上的弹着点光斑,并显示弹着点的环数与方位信息。其中环数包括:10、9、8、7、6、5、脱靶;方位信息是指弹着点与10环区域的相对位置,包括:中心、正上、正下、正左、正右、左上、左下、右上、右下。详见图2-b。

1.2.2发挥部分

(1) 在图形点阵显示器上显示胸环靶的相应图形,并闪烁显示弹着点。 (2) 自动控制激光枪,在15秒内将激光束光斑从胸环靶上的指定位置迅速瞄准并击中靶心(即10环区域)。

(3) 可根据任意设定的环数,控制激光枪瞄准击中胸环靶上相应位置。 (4) 其他

2-a 胸环靶尺寸 2-b胸环靶 环数及方位信息示意

图2 胸环靶示意图

第 3 页

1.3说明

1.

激光枪可以由市场上的激光笔改造,由电路控制击发;每次击发使

光斑维持3~5s时间,但此期间不得移动光斑。

2.

可采用步进电机、舵机或直流电机等机构对激光枪进行两维控制,

以实现瞄准。激光枪及相关机构可由支架支撑。

3.

胸环靶是在不反光的白纸画有一组相距5cm的同心圆(线宽不超过

1mm),最内圆环直径10cm,圆环内为10环区域,从最内环至最外环间分别为9、8、7、6、5环区域,最外环外为脱靶。胸环靶上不允许设置摄像头以外的传感器。

4.

当激光枪的弹着点落在胸环靶的环线上时,报靶时采取就高不就低

的原则。例如,弹着点在8环与9环之间的环线上时,则认为是9环。

5. 6.

在不影响靶纸上圆环线的前提下,允许在靶纸上做标记。 在完成发挥部分要求时,在正式击发前允许进行1-2次试射;但试

射次数越少越好。

7. 不限制摄像头及弹着点检测电路的安装位置,但应方便搬运与快速

安装。

8. 测试时自带胸环靶纸,测试评审现场可提供粘贴胸环靶的支架。

第 4 页

2.题目分析及设计方案论证与比较

2.1 系统总方案

1) 方案1:采用单处理单元即只使用MSP430F149,控制激光管的运动,通过采

集摄像头信息,完成显示功能,但是此方案对主控芯片的处理速度要求高。 2) 方案2:采用双处理单元利用MSP430F149 控制激光管的打靶,完成打靶位

置的图像显示,利用XXX 处理摄像头的信息,并获取激光光斑的位置信息,此方案容易实现但是不利于自动控制。

3) 方案3:采用双控制单元利用MSP430F149 控制激光管的打靶,完成打靶位置

的图像显示,并与MC9S12XS128 副控制芯片进行通信通过从处理器传来的光斑位置信息,从而完成精确的位置追踪。综上思考决定使用第3方案。

2.2 单片机供电电源方案

1) 方案一:选用线性稳压芯片(LM7805)实现降压。由于单片机的供电压一 定,则在线性稳压芯片两端的压降也一定,且压降较大,随着电流的增加,

芯片消耗的功率迅速增大,致使整个系统速率大大降低,故不采用该方案。

2) 方案二:选用TI 公司5430,查手册可得输入是5~36V 输出电压可调,由于

其转换效率高,所以选用该方案。

第 5 页

3.系统设计

3.1总体设计思路

根据题目要求, 经过我们认真分析,在整体设计时将MSP430F149作为主控芯片,MC9S12XS128作为从控制器,整个系统通过拨码开关控制系统的手动和自动功能,当为高时实现手动方式控制激光笔找寻靶位,当为低时实现自动搜索靶位。

在主控芯片上经过串口通信,接收从控制器发送过来的位置数据,通过12864显示击中靶的位置并闪烁。通过控制二自由度的舵机云台,实现激光的移动。编程设定激光笔的点亮时间,通过矩阵键盘的扫描,来进行相应的操作。

从控制芯片负责处理图像数据,定位中心点,确定击中靶的位置,转换坐标然后同构串口通信传送给主控制器。从控制器还得负责手动控制下的方位显示,环数显示。

图3 系统总体设计图

第 6 页

3.2环数确定算法

设计所使用环的半径60cm,黑线边框变长为70cm,以半径为60cm 的边框 左上角为(0,0)点看,此时的坐标为(x,y),而相对于中心点的坐标是

X1=x-30; Y1=y-30; X2=X1/5; Y2=Y2/5;

环数的换算:

D=sqrt(X2^2+Y2^2); 结果分析

① 0

3.2.1 方位确定算法

将一个圆面分成8 个部分,因此每个部分为360°/8=45°,下文省略单位度。

激光击打位置的垂直距离

第 7 页

Y=X2*tan(θ);

激光笔与水平面所成角度

θ=[22.5,22.5+45,22.5+45*2,22.5+45*3,22.5+45*4,22.5+45*5,22.5+45*6 , 22.5+45*7,-22.5]; 分析:

a. 当X2<=1,Y2<=1 时, 方位是中心

b. X2*tan[22.5+45*i]

[i]=[“正右”,“右上”,“正上”,“左上”,“正左”,“左下”,“正下”,“右下”,“中心”];

3.2.2 激光管的运动算法

通过按键上下左右的移动,每按一下,从当前位置走一步边界条件: 在[60,60]点阵中移动。当摄像头读不到光点时,由128 向430 发送[-1,-1];当摄像头读到光点时,128 向430 发送光点的坐标[x,y]其中0

当x≤0 时,不能左移 当x≥60 时,不能右移 当y≤0 时,不能上移 当y≥60 时,不能下移

当读到x<0,y<0 时,说明光点在靶外,继续搜索,直到x>0,y>0 为止。

第 8 页

3.3软件流程图

图4 系统软件流程图

第 9 页

3.4系统模块设计

3.4.1 矩阵键盘 矩阵键盘电路图:

矩阵键盘的思路是选择一列,再逐行扫描,看有没有键按下,按下了就读取键值,没有就扫描下一列直到扫描完所有键,都扫描完没有键按下的话,跳出循环,不进行操作!我们根据读取到的键值跳转到相应的子程序里面。

如上表前面八个前用于手动调节双舵机的转动,后面是击中靶子预定环数的选择和确定键。

第 10 页

3.4.2 PWM波的生成

/*时钟源的选择,选择高频8M晶振*/ BCSCTL1&=~XT2OFF; do{

IFG1&=~OFIFG; for(i=0xff;i>0;i--); }

while((IFG1&OFIFG)!=0); BCSCTL2 |=SELM1+SELS; //***设置Timer_B***//

TBCTL =TBSSEL_2 + TBCLR; // 选择SMCLK 为时钟定时器清除 TBCTL |= MC_1+CNTL_0+TBCLGRP_0; //选择up,16 位模式 TBCCTL0 = CCIE; //将CCR0 设为比较模式,中断允许 TBCCR0 =14380; //PWM 的频率为50hz

TBCCTL1=OUTMOD_7+CLLD_1; //将CCRx 设为比较模式,中断禁止 TBCCR1=1100;//下面舵机的正中位置

TBCCTL2=OUTMOD_7+CLLD_1; //将CCRx 设为比较模式,中断禁止 TBCCR2=1400;//上面舵机的正中位置 分析:

F149可以通过捕捉/比较功能来产生PWM波,并且仅在P4口才能产生,通过设定CCR0来设置PWM的频率,CCRx(1~7)来确定占空比,占空比是CCRx/CCR0。由于舵机的精度与靶和激光笔的3米距离,多以我们要选用较高频率的PWM波,保证

第 11 页

单片机能够使舵机达到其最高精度,保证准确性。

3.4.3 12864的显示

12864的显示要求我们能够显示区方位、环数以及闪烁表示击中靶的位置,我们使用的是带字库的12864,可以直接显示。

12864液晶显示器是应用较多的一种点阵式液晶显示模块,它由行驱动器、列驱动器及128×64全点阵液晶显示器组成。可以完成图形显示也可以显示8×4个(16×16点阵)汉字。模块内自带-10V负压,用于LCD的驱动;显示内容为128(列)×64(行)个点;与CPU接口采用了8位数据总线并行输入输出和8条控制线。 逻辑工作电压(VDD):4.5~5.5V 电源地(GND):0V 工作温度(Ta):0~60℃(常

温) / -20~75℃(宽温) ,模块控制芯片提供两套控制命令,基本指令和扩充

指令。详见相关资料。

下表是管脚的功能表;

12864显示中文、数字只需写好控制字后,再直接输入数据就可以了。但是显示图像时,我们需要先用字模提取软件提取图像,再将我们的字模显示。

第 12 页

我先用CAD画好靶子后,用生成一个图像文件,在字模提取软件里面不断调整,得到最终的图像字模。通过串口通信来得到点的位置,改变字模,通过相应的算法,达到闪烁的效果。

3.4.4串口通信

MSP单片机的USART模块可以配置成SPI(同步通信)模式或UART(异步通信)模式,我们用到的是UART方式。UART数据传输格式如下:

起始位,数据位由高到低7/8位,地址位 0/1位,奇偶校验位 奇偶或无,停止位1/2位。数据位位数、地址位、奇偶校验位、停止位均可由单片机内部寄存器控制;MSPF149单片机有两个USART模块,有两套独立的寄存器组;以下寄存器命中出现x代表0或是1,0代表对应0模块的寄存器,1代表对应1模块的寄存器;其中,与串口模式设置相关的控制位都位于UxCTL寄存器,与接收相关的控制位都位于UxRCTL寄存器,与发送相关的控制位都位于UxTCTL寄存器;波特率设置用UxBR0、UxBR1、UxMCTL三个寄存器;接收与发送有独立的缓存UxRXBUF、UxTXBUF,并具有独立的移位寄存器和独立的中断;中断允许控制位位于IE1/2寄存器,中断标志位位于IFG1/2寄存器。 波特率设置:430的波特率设置用三个寄存器实现, UxBR0:波特率发生器分频系数低8位。 UxBR1:波特率发生器分频系数高8位。 UxMCTL:波特率发生

第 13 页

器分频系数的小数部分实现。 设置波特率时,首先要选择合适的时钟源:USART模块可以设置的时钟源有UCLK引脚、ACLK、SMCLK;对于较低的波特率(9600以下),可选ACLK作为时钟源,这样,在LPM3(低功耗3)模式下,串口仍能正常发送接收数据;另外,由于串口接收过程有一个三取二判决逻辑,这至少需要三个时钟周期,因此分频系数必须大于3;波特率高于9600时,将不能使用ACLK作为时钟源,要调为频率较高的SMCLK作为时钟源;另外还可以外部输入UCLK时钟。分频系数计算公式如下:

小数分频是MSP430单片机的串口特色之一,UxMCTL寄存器的作用就是控制小数的分频,控制方法如下:对应位是1,则分频系数加一,0则分频系数减一;小数分频器会自动依次取出每一位来调整分频系数。其计算方法:可以先计算小数部分1的个数,然后把1均匀的放入UxMCTL的8位中,这样计算比较简单,分频系数的小数部分乘以8即得到1的位数,查表得到对应的UxMCTL值;另外一种通过计算每一位的错误率,交互计算,直到得到最小错误率的UxMCTL值,这种方法比较复杂,但得到的小数分频误差更小,这种方法也是TI给的计算方法,详细参考UserGuide。

串口通信程序: void init_com( void ) {

P3SEL |= 0x30; //0x30=0011_0000,即选择P3.6和P3.7做

UART通信端口

ME1 |= UTXE0 + URXE0; //使能UART0的发送TXD和接受RXD //设置波特率9600bps,寄存器数据为32768/9600=3.41

第 14 页

UTCTL0 |= SSEL0; //UCLK = ACLK,选择时钟来源32K UBR00 = 0x03; //波特率寄存器低字节 UBR10 = 0x00; //波特率寄存器高字节

UMCTL0 = 0x34; /*波特率小数寄存器,首先把小数部分0.41x8=3.2,取整后为3,这个3的意思就是在UxMCTL中的8位里要有3个1,3个1要相对分散点,低4位最好选择偶数*/

UCTL0 |= CHAR; // 数据格式为8位数据 UCTL1 &= ~SWRST; //使能USART

IE1 |= URXIE1; //让串口接收到数据后能产生中断 _EINT(); //开总中断,整个系统中断使能 }

#pragma vector=UART1RX_VECTOR __interrupt void usart1_rx (void) {ck++; if(ck==1) {

x=RXBUF0; } else{

y=RXBUF0; ck=0;} }

我自己通过串口调试助手调试得到我的程序、串口硬件没错。

第 15 页

3.4.5 图像采集

图像采集是通过MC9S12XS128超频到80MHz,迅速得到图像,通过分析图像,确定靶子的中心位置,通过分析图像中的亮斑得到激光的击中位置。分析计算把亮斑的位置换算成我们的标准坐标,再利用串口通信传送到149,让149闪烁显示图像。

第 16 页

4.实习总结

本系统通过主控芯片MSP430F149为中心,共由5个模块构成,分别是12864 液晶显示模块,双舵机云台射击模块,模式选择模块,蜂鸣器模块以及数据采集模块构成。

数据采集是通过128 定时中断,读取数据,读取出靶的四周黑线,从而定位靶和得到圆心位置。然后提取光斑,得到光斑位置坐标,通过串口通信把光斑坐标传给主控芯片MSP430F149。

12864模块通过MSP430F149的I/O口给其写控制字,通过AUTOCAD和绘图软件,获得靶的图像,再将图像导入字模提取软件,得到字模,从而在12864上面显示靶子。MSP430F149 提取从芯片传过来的点的坐标,定位点在12864 中的位置,判定相对应的位置是否为1。为1就减去相应的位为一其他位为0的一个字节数据,修改数据后显示图像,再将减去的数据再加回来,从而闪烁。反之亦然。 双舵机云台射击模块,通过云台固定激光枪,由云台构成二自由度的机构。 舵机的控制是通过TIMERB 的比较模式,产生频率为50Hz的PWM波。舵机根据PWM 波的占空比转动相应的角度。实现上下左右的射击方向控制。

经过了三天的奋战,我们把各个模块都做好了,但是在把程序最后到一起时,问题出现了,程序老是跑飞,不稳定,内存不足;从控制器无法正常采集分析数据,串口通信也没有调试成功。

我总结了一下我们失败的原因,有三点:

一、我自身的编程能力不行,在做模块时没有一边做模块一边组合在一起调试,导致最后程序老师跑飞,这也给我我一个很好的教训。

第 17 页

二、我们也失败在两个单片机的通信,我们的设计是基于两机通信的,但我们没有注意这个看似简单的部分。没有两机的通信,我们的系统就无法正常的运行。

三、我们的前期工作没有做到位,之前的硬件一直停滞不前,没有给我练手的机会。硬件模块在比赛前也只做了一个电源模块出来,可以说硬件部分导致了这一次的失败。

这段时间的实习,让我很是充实,即使结果不是很好,但现在的我已经看淡了这些,我在这次实习中收获很大,我认识到了我自身的不足。通过这段时间的练习,我的编程能力有了极大的提高,可以说以前的我只会纸上谈兵,现在的我也能够熟练地运用MSP430系列的单片机,更重要的是从老师和学姐那里学到了好多的经验,拓宽了眼界,还学到了一招学习各种应用技术的秘诀--逛论坛!

第 18 页

附:系统部分程序

#include \#include #include \

#define uchar unsigned char #define uint unsigned int

#define dataportjp P2 //矩阵键盘数据口 #define dataportxs P1 //12864数据口 #define RS P37 //命令/数据选择 #define RW P36 //读写口 #define E P33 //锁存控制 #define RES P30 //复位 #define PSB P32 //串并选择 #define MS P47 #define JG P46 uint queding;

uchar scode=0x00;//扫描码 uchar rcode=0x00;//读回码

uchar keyValue; //定义扫描结果参数 int dianliang;//定时器B设定 激光管点亮时间 uchar ck=0;//串口计数 uchar x=13; uchar y=23;//坐标 uint x1; uint y1;

uchar dwd[]={0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02};//定位点变换 uchar shejiba[]= //图片代码 {

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

第 19 页

0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x80,0x03,0xfc,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0x00,0x3e,0x03,0xe0,0x06,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x00,0xc0,0x00,0x18,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x06,0x00,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x80,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xc0,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x20,0x20,0x03,0xfe,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x40,0x40,0x1c,0x01,0xc0,0x10,0x10,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x80,0x80,0x60,0x00,0x30,0x08,0x08,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x81,0x01,0x80,0x00,0x08,0x04,0x08,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x06,0x02,0x04,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x06,0x06,0x00,0x00,0x03,0x02,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x04,0x08,0x00,0xf0,0x01,0x81,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x08,0x18,0x0f,0x0f,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x08,0x10,0x10,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x10,0x20,0x20,0x00,0x20,0x20,0x41,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x10,0x20,0x40,0x00,0x10,0x20,0x41,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x40,0x80,0x00,0x08,0x10,0x41,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x41,0x00,0xf0,0x08,0x10,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x81,0x01,0x0c,0x04,0x10,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x00,0x82,0x02,0x02,0x00,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x82,0x04,0x01,0x02,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x20,0x82,0x08,0x00,0x02,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x20,0x82,0x08,0x00,0x82,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x21,0x02,0x08,0x00,0x82,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x21,0x02,0x08,0x00,0x82,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x20,0x82,0x08,0x00,0x82,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10,0x20,0x82,0x08,0x00,0x02,0x08,0x20,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x82,0x04,0x01,0x02,0x08,0x20,0x40,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x00,0x82,0x02,0x02,0x00,0x08,0x20,0x40,0x00,0x00,0x00,0x00,

第 20 页

0x00,0x00,0x00,0x08,0x20,0x81,0x01,0x0c,0x04,0x10,0x20,0x40,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x41,0x00,0xf0,0x08,0x10,0x20,0x40,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x08,0x20,0x40,0x80,0x00,0x08,0x10,0x40,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x10,0x20,0x40,0x00,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x10,0x20,0x20,0x00,0x20,0x20,0x40,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x08,0x10,0x10,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x08,0x18,0x0f,0x0f,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x04,0x08,0x00,0xf0,0x01,0x81,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x02,0x06,0x06,0x00,0x00,0x03,0x02,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x06,0x02,0x04,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x81,0x01,0x80,0x00,0x08,0x04,0x08,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x80,0x80,0x60,0x00,0x30,0x08,0x08,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x40,0x40,0x1c,0x01,0xc0,0x10,0x10,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x20,0x20,0x03,0xfe,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xc0,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x80,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x06,0x00,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x00,0xc0,0x00,0x18,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0x00,0x3e,0x03,0xe0,0x06,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x80,0x01,0xf8,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

void delay(int time) {

uint i,j;

for(i = 0;i < time; i++) {

for(j = 0;j < 80; j++);

第 21 页

} }

uchar keyScan() {

scode=0x00;//扫描码 rcode=0x00;//读回码 P20=0;P21=0;P22=0;P23=0;

if((P2IN&0xf0)!=0xf0) //判断高4位是否为全1(高4位全1代表没按键按下) {

delay(8000); //延时去抖动,一般为5ms~10ms(由于机械触点的弹性作用,按键在闭合时不会马上稳定地接通,

//而在闭合瞬间伴随有一连串的抖动,键抖动会引起一次按键被误读多次)

if((P2IN&0xf0)!=0xf0) //还能检测到有键盘按下去,按行扫描 {

scode=0xfe; //置扫描码

while(scode!=0xef) //如果没有扫描完,继续扫描 {

P2=scode; //送扫描码 if((P2IN&0xf0)!=0xf0) //检测到了 {

rcode=P2IN; //保存P2口的状态 rcode=rcode & 0xf0; //生成返回码高4位 scode=scode & 0x0f; //生成返回码低4位

return(scode + rcode);//返回键盘编码, 程序跳出键盘扫描函数(程序执行到return语句的时候就返回,他后面的语句都不会执行)。 } else {

scode=(scode<<1)|0x01;//移位,产生下一行扫描码,顺序:0xfe—》0xfd—》0xfb—》0xf7—》0xef

//当扫描码为0xef时,判断条件scode!=0xe为假 ,跳出while 循环

} }

第 22 页

} }

return(0); //没有检测到返回0 }

//**************************************************************************************************

//舵机按键扫描结果处理函数

//**************************************************************************************************

void keyHandle(void) {

switch(keyValue) {

case 0xee: //S1 上 {

TBCCR1+=200; break;} case 0xde: //S2 下 {

TBCCR1-=200; break;}

case 0xBE: // 微上

{

TBCCR1+=500; break; }

case 0x7e: //微下

{

TBCCR1-=1;

break; }

case 0xed: //左右 {

TBCCR2+=500;

第 23 页

break;} case 0xdd: {

TBCCR2-=8; break;}

case 0xbd:

{

TBCCR2+=1;

break; }

case 0x7d:

{

TBCCR2-=1;

break; }

case 0xeb: //确认键 {

queding=1; break; }

case 0xdb: //10环 { break; }

case 0xbb: //9环 { break;}

case 0x7b: //8环 { break;} case 0xe7://7环 { break;} case 0xd7://6环 {

第 24 页

break;} case 0xb7://5环 { break;} } }

#pragma vector=TIMERA0_VECTOR __interrupt void Timer_A0(void){ P46=1; dianliang++; if(dianliang>800) {P46=0;

TACCTL0&=~CCIE;};//取反 }

void checkbusy(void) {

RS=0; //命令/数据选择,为0时选择命令 RW=1; //读/写选择,为1时选择读 E=1; //使能 delay(10);

P1DIR7=0; //设置查忙位为输入

while((P1IN&0x80)==1); //查忙标志位,等待标志位为0,即表示写入完毕 P1DIR7=1; //设置查忙位为输出 E=0; //关闭读写 }

//************************************************************************************************** //向LCD写一命令

//**************************************************************************************************

void wcode(uchar cmdcode) {

checkbusy(); //查忙

第 25 页

RS=0; //命令/数据选择,为0时选择命令 RW=0; //读/写选择,为0时选择写 E=1; //使能 P1=cmdcode; //送入命令 delay(10); //等待写入 E=0; //关闭读写 }

//************************************************************************************************** //向LCD写一数据

//**************************************************************************************************

void wdata(uchar dispdata) {

checkbusy(); //查忙

RS=1; //命令/数据选择,为1时选择数据 RW=0; //读/写选择,为0时选择写 E=1; //使能 P1=dispdata; //送入数据 delay(10); //等待写入 E=0; //关闭读写 }

//************************************************************************************************** //LCD 初始化

//**************************************************************************************************

void InitLCD(void) {

PSB=1; //设置为8BIT并口工作模式 RES=0; //复位 delay(10); //延时 RES=1; //关复位 wcode(0x30); //选择基本指令集

第 26 页

wcode(0x0c); //开显示(无游标、不反白)

wcode(0x01); //清除显示,并且设定地址指针为00H

wcode(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位 }

//************************************************************************************************** //显示图片

//**************************************************************************************************

void picshow(uchar *bmp) {

uchar i,j,k,up_down;

up_down=0x80; //先写上半屏 wcode(0x34); //设置图形模式 wcode(0x36); //设置图形模式

for(k=0;k<2;k++) //分上下半屏先后写入,所以循环2次,i为0时写上半屏,i为1时写下半屏 {

for(i=0;i<32;i++) //上下半屏各32行,共64行 {

wcode(0x80 + i); //设置垂直地址 wcode(up_down); //设置水平地址

for(j=0;j<16;j++) //写16个字节,16*8=128竖 {

wdata(*bmp); //写入一字节 bmp++; //加1 } }

up_down=0x88; //准备写下半屏 } }

void init_com( void ) {

P3SEL |= 0x30; //0x30=0011_0000,即选择P3.6和P3.7做UART通信端口 ME1 |= UTXE0 + URXE0; //使能UART0的发送TXD和接受RXD

第 27 页

//设置波特率9600bps,寄存器数据为32768/9600=3.41

UTCTL0 |= SSEL0; //UCLK = ACLK,选择时钟来源32K UBR00 = 0x03; //波特率寄存器低字节 UBR10 = 0x00; //波特率寄存器高字节

UMCTL0 = 0x34; /*波特率小数寄存器,首先把小数部分0.41x8=3.2,取整后为3,这个3的意思就

是在UxMCTL中的8位里要有3个1,3个1要相对分散点,低4位最好选择偶数*/

UCTL0 |= CHAR; // 数据格式为8位数据 UCTL1 &= ~SWRST; //使能USART

IE1 |= URXIE1; //让串口接收到数据后能产生中断 _EINT(); //开总中断,整个系统中断使能 }

#pragma vector=UART1RX_VECTOR __interrupt void usart1_rx (void) {ck++; if(ck==1) {

x=RXBUF0; } else{

y=RXBUF0; ck=0;} }

void main(void) { uint i;

WDTCTL = WDTPW +WDTHOLD; // 禁止看门狗定时器

BCSCTL1&=~XT2OFF; do{

IFG1&=~OFIFG; for(i=0xff;i>0;i--); }

第 28 页

while((IFG1&OFIFG)!=0); BCSCTL2 |=SELM1+SELS; //***初始化端口***//

P1DIR=0XFF; //12864数据初始化 P1=0XFF; P3DIR=0xdf;

//设置P3.5为输入

P3=0xFf; //设置P3初始化为高电平 P3SEL=0X30;//串口通信初始化 P2DIR=0X0f;//P2d低四位输出

P2IES |= 0xff;//set P2 1-->0 to set the flag P2IE |= 0xff;//enable P2 interrupt P2IFG = 0x00;//IO中断设定

P4DIR |= 0x06; // P4.1 P4.2 为输出 P4SEL |= 0x06; //TBPWM输出

InitLCD(); //初始化液晶 init_com( ) ; //初始化串口 //定时器A设置

//CCTL0 = CCIE; //设置捕获/比较控制寄存器中CCIE位为1,CCR0捕获/比较功能中断为允许。

//TACCR0 = 40000; //实现40000x(1/800000)=0.05S秒的定时,捕获/比较控制寄存器CCR0初值为40000

// TACTL = TASSEL_2+ MC_1; //时钟源选择为MCLK,频率为800000hz. //***设置Timer_B***//

TBCTL =TBSSEL_2 + TBCLR; // 选择SMCLK 为时钟定时器清除 TBCTL |= MC_1+CNTL_0+TBCLGRP_0; //选择up,16 位模式 TBCCTL0 = CCIE; //将CCR0 设为比较模式,中断允许 TBCCR0 =14380; //PWM 的频率为50hz

TBCCTL1=OUTMOD_7+CLLD_1; //将CCRx 设为比较模式,中断禁止 TBCCR1=1100;//下面舵机的正中位置

TBCCTL2=OUTMOD_7+CLLD_1; //将CCRx 设为比较模式,中断禁止 TBCCR2=1400;//上面舵机的正中位置 while(!queding) {

keyValue=0;

第 29 页

keyScan(); keyHandle(); }

TXBUF1=0X01; TACCTL0=CCIE; P46=1;

x1 = (128 + 25 + x + 128 * y) / 8 ; y1 = (128 + 25 + x + 128 * y) % 8; if(y1==0) x1-=1; while(1) {

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 if(shejiba[x1]&dwd[y1]==dwd[y1]) {

shejiba[x1]=shejiba[x1]-dwd[y1];

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 shejiba[x1]=shejiba[x1]+dwd[y1];} else{

shejiba[x1]=shejiba[x]+dwd[y1];

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 shejiba[x1]=shejiba[x1]-dwd[y1];} } } /* else { _NOP(); }*/

第 30 页

keyScan(); keyHandle(); }

TXBUF1=0X01; TACCTL0=CCIE; P46=1;

x1 = (128 + 25 + x + 128 * y) / 8 ; y1 = (128 + 25 + x + 128 * y) % 8; if(y1==0) x1-=1; while(1) {

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 if(shejiba[x1]&dwd[y1]==dwd[y1]) {

shejiba[x1]=shejiba[x1]-dwd[y1];

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 shejiba[x1]=shejiba[x1]+dwd[y1];} else{

shejiba[x1]=shejiba[x]+dwd[y1];

picshow(shejiba); //显示图片 delay(3000); //保持显示一段时间 shejiba[x1]=shejiba[x1]-dwd[y1];} } } /* else { _NOP(); }*/

第 30 页

本文来源:https://www.bwwdw.com/article/tmla.html

Top