上海求育QY-JXSY38开放型单片机微机开发系统实验箱是集51,96,8088三大系列CPU于一体的三合一实验系统,内置51/96单片机仿真器和8088实验系统.可单独作为8086微机原理和接口实验使用,也可分别叠插51或96CPU卡,构成51/96单片机实验开发系统,通过选配EDA扩展卡,实现EDA和单片机两合一,可分别控制实验电路。系统配置2000/xp等操作平台的单片机仿真调试软件,支持汇编、C51语言编译、调试;单片机在线下载软件等。电话021-69918115
详细信息:https://www.mmaan.com/cpjs/1553.html
实验项目
(一)51单片机实验
软件实验
(1)清零程序;
(2)拆字程序;
(3)拼字程序;
(4)数据区传送子程序;
(5)数据排序实验;
(6)查找相同数据个数;
(7)无符号双字节快速乘法子程序;
(8)多分支程序;
(9)脉冲计数实验;
(10)电脑时钟实验。
硬件实验
(1)P1口亮灯实验;
(2)P1口转弯灯实验;
(3)P3.3口输入,P1口输出实验;
(4)工业顺序控制实验;
(5)8255A、B、C口输出方波实验;
(6)8255PA口控制PB口;
(7)8255控制交通灯;
(8)简单I/O扩展实验;
(9)A/D0809转换实验;
(10)D/A0832转换实验;
(11)8279键盘显示实验;
(12)通用打印机实验;(打印机选配☆)
(13)微型打印机打印字符、曲线、汉字实验;(打印机选配☆)
(14)I2C储存卡读写实验;
(15)继电器控制实验;
(16)步进电机控制;
(17)8253方波实验;
(18)小直流电机调速实验;
(19)16*16LED点阵显示实验;
(20)128*64LCD液晶显示实验;
(21)8250可编程异步通讯接口实验(自发自收);
(22)8251可编程通讯接口实验(与PC机);
(23)单片机RS232/485串行发送实验(双机通讯);
(24)单片机RS232/485串行接收实验(双机通讯);
(25)DS18B20单总线温度测量实验
(26)压力实验;
(27)PWM实验
(28)射极跟随器
(29)看门狗实验
(30)串并转换实验(74LS164)
(31)并串转换实验(74LS165)
(32)查询式键盘实验(选配)
(33)红外线遥控收发实验
(34)LM331V/F、F/V实验
(35)138译码实验
(36)串行EEPROM93C46读写实验
(37)I2CAT24C02读写实验
(38)TLC549串行A/D转换实验
(39)TLC561510位D/A串行转换实验
(40)PCF8563I²C日历时钟实验
(41)日历时钟DS12887控制实验(选配)
(42)语音芯片ISD1730控制实验(录音)
(43)语音芯片ISD1730控制实验(放音)
(44)CAN总线通讯接口实验(选配)
(45)以太网TCP/IP协议接口实验(选配)
(46)USB2.0通讯接口实验(选配)
(47)非接触式IC卡模块实验(选配)
(48)电子音乐实验
(二)96单片机实验
软件实验
(1)清零程序
(2)拆字程序
(3)拼字程序
(4)数字区传送子程序
(5)数据排序实验
(6)查找相同个数
(7)无符号双字节快速乘法子程序
(8)多分支程序
硬件实验
(1)P1口亮灯实验
(2)P1口转弯灯实验
(3)P2.6口输入,P1口输出
(4)工业顺序控制
(5)8255A、B、C口输出方波
(6)8255PA口控制PB口
(7)8255控制交通灯
(8)简单I/O扩展
(9)A/D转换实验
(10)D/A转换实验
(11)8279键盘显示实验
(12)通用打印机☆
(13)继电器控制
(14)8253方波
(15)步进电机控制
(三)8086微机实验
软件实验:
(1)二进制多位加法实验
(2)二进制转换为BCD码实验
(3)BCD码转换为二进制码
(4)十进制数的BCD码相减运算
(5)内存清零实验
(6)数码显示实验
(7)求最大数和最小数
(8)数据块传送实验
(9)分支程序设计。
硬件实验:
(1)A/D转换实验
(2)D/A转换实验(一)
(3)D/A转换实验(二)
(4)8255A并行口实验(一)
(5)8255A并行口实验(二)
(6)定时器/计数器实验
(7)8259单级中断控制器实验
(8)串行口发送实验(双机通讯)
(9)串行口接收实验(双机通讯)
(10)小直流电机调速实验;
(11)步进电机控制
(12)继电器控制
(13)存贮器读写实验
(14)电子琴实验
(15)简单I/O口扩展实验
(16)8251可编程通讯接口和PC机通讯
(17)16*16LED点阵显示实验
(18)128*64LCD液晶显示实验
(19)8237DMA传送实验
(20)8250可编程异步通讯接口实验
(21)8279键盘显示实验
(22)温度测量实验
(23)压力测量实验
扩展卡实验(选配)
(1)POD5扩展卡:
40芯锁紧大孔引出,扩展主板以外接口芯片用。
(2)POD1032扩展卡:
主持Lattice公司:ISP1032E芯片实验开发。
(3)POD1C3扩展卡:
主持Atera公司:EP1C3T144芯片实验开发。
(4)POD1C6扩展卡:
主持Atera公司:EP1C6T144芯片实验开发。
(5)模拟组态控制实验:(USB接口)
(6)单片机课程设计实验平台(51选配)
乒乓球游戏设计
抢答器设计
音乐盒的制作
温度巡回检测系统
计算器实验
电子密码锁
超声波测距
汽车倒车雷达
生产线货物自动计数设备
数显频率计实验
EDA实验报告
一.实训目的
1.熟悉EDA实验基本操作
2.利用VHDL语言编写EDA程序,运行调试程序,观察现象
3.采用单片机技术实现惯导信号的数据采集
4.采用PC应用程序处理单片机传来的数据并显示波形
二.实训任务和要求
1.用VHDL语言独自编写“七人表决器程序”,并在实验箱进行测试
2.用STM32单片机采集MPU6050数据,实现惯导数据的采集
3.用C#编写PC端应用程序,实现惯导数据的波形显示
三.实训过程与内容
1.EDA实验的程序实现
1.1 实验原理
用七个开关作为表决器的7个输入变量,输入变量为逻辑“1”时表示表决者“赞同”; 输入变量为逻辑“0”时表示表决者“不赞同”;输出逻辑“1”时,表示表决“通过”; 输出逻辑“0”时,表示表决“不通过”;当表决器的七个输入变量中有4个及以上为“1”时,则表决器输出为“1”,否则为“0”。表决器输入采用试验箱K1~K16,输出采用试验箱L15、L16指示;同意红灯亮,否则黄灯亮。
1.2 实验过程
学习EDA编程第一步就是要学会用,VHDL语言的开发环境,本次实验我们使用的是Quartus编译器。首先是建立一个quartus工程,启动Quartus软件后默认的界面主要由标题栏,菜单栏你,工具栏,资源管理窗口,编译状态显示窗口,信息显示窗口和工程工作区等部分组成。执行菜单命令File->New Project Wizard创建工程向导。第二步,设置工程文件夹及工程名,在弹出来的对话框中输入工程将存储的路径,然后填写工程名,最后一行填写顶层文件名。点击next,然后选择器件。在Device family ->family下选择要使用的FPGA芯片系列,并在devices下选择具体芯片型号,点击next。然后在编辑区编辑VHDL程序即可。
1.3 实验程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------------------------
entity decision is
port(
k1,K2,K3,K4,K5,K6,K7 : in std_logic; --输入:7个人
ledag : out std_logic_vector(7 downto 0); --数码管显示
m_Result : out std_logic --表决结果
);
end decision;
--------------------------------------------------------------------
architecture behave of decision is
signal K_Num : std_logic_vector(2 downto 0);
signal K1_Num,K2_Num: std_logic_vector(2 downto 0);
signal K3_Num,K4_Num: std_logic_vector(2 downto 0);
signal K5_Num,K6_Num: std_logic_vector(2 downto 0);
signal K7_Num : std_logic_vector(2 downto 0);
begin
process(K1,K2,K3,K4,K5,K6,K7) --计算表决同意人数
begin
K1_Num<='0'&'0'&K1;
K2_Num<='0'&'0'&K2;
K3_Num<='0'&'0'&K3;
K4_Num<='0'&'0'&K4;
K5_Num<='0'&'0'&K5;
K6_Num<='0'&'0'&K6;
K7_Num<='0'&'0'&K7;
end process;
process(K1_Num,K2_Num,K3_Num,K4_Num,K5_Num,K6_Num,K7_Num)
begin
K_Num<=K1_Num+K2_Num+K3_Num+K4_Num+K5_Num+K6_Num+K7_Num;
end process;
process(K_Num) --根据人数输出结果
begin
if(K_Num>3) then
m_Result<='1';
else
m_Result<='0';
end if;
end process;
process(K_Num) --根据人数数码管显示表决通过人数
begin
case K_Num is
when "000"=>ledag<="11000000";
when "001"=>ledag<="11111001";
when "010"=>ledag<="10100100";
when "011"=>ledag<="10110000";
when "100"=>ledag<="10011001";
when "101"=>ledag<="10010010";
when "110"=>ledag<="10000010";
when "111"=>ledag<="11111000";
when others=>ledag<="11111111";
end case;
end process;
end behave;
1.4 实验程序分析
在程序开始需要添加库文件,本次程序总共使用到了三个库文件,一个是包含了基本逻辑门实体,一个是包含了数学运算,一个包含了整形数。然后在实体中定义端口,标明输入输出端口。整个程序主要部分是在Architecture中,在这个部分中定义了5个信号,在结构中有三个进程,一个进程负责当有人按下同意按键时,相应的指示灯亮。第二个进程表示统计所有按下同意按键的人数。第三个进程将同意的人数通过数码管显示出来。
1.5 引脚绑定
在Quatus软件中使用Assignments->Remove Assignment标签,移出管脚分配内容,以确保此次操作。然后使用记事本或类似软件新建一个tcl文件,按如下格式编写管脚分配内容。
1.6 运行程序查看实验结果
编译程序成功后,接下来就是测试程序是否按照自己的意图运行。点击运行按钮,然后按下K1开关,可以看到L1灯亮了表示K1已经按下,数码管显示数字1,然后表决灯灭。接着按下K1,K3,K4,K6,K7按键,看到L1,L3,L4,L6,L7指示灯都是亮的,数码管显示数字5,表决灯亮,表示有4个以上的人表示通过。实验成功!
2.采用单片机技术实现惯导数据的采集
2.1 STM32单片机的介绍
STM32系列单片机基于专为高要求性能,低成本,低功耗的嵌入式应用专门设计的ARM Cortex-M3内核。最高工作频率为72MHZ,单周期乘法和硬件除法。片上集成32-512KB的Flash存储器,有三种低功耗模式:休眠,停止,待机模式。拥有USART,SPI,I2C等常用外设接口。操作简单方便等特点。
2.2 惯导定位系统简介
随着社会现代化建设的不断发展,大型建筑日益增多,人们80%以上的时间处于室内环境,室内位置服务的需求正在不断增加。在特殊人群监护,大型场馆管理,个人位置服务等领域都需要使用准确的室内位置信息,特别是在紧急情况时,如在消防救援,应急疏散等特殊应用场景下,室内定位信息显得尤为重要。惯导定位的原理是:在知道物体初始位置的情况下,通过惯导器件(加速度计和陀螺仪)确定物体相对空间的位置变化,然后通过磁力计得到物体相对初始位置的方向变化,然后结合位置和方向两个物理量,可以计算出物体的最终位置,实现室内定位。
2.3 惯导传感器MPU6050介绍
MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,相较于多组件方案,免除了陀螺仪与加速度时轴间差的问题,减少了安装空间。
MPU6050内部整合了3轴陀螺仪和3轴加速度传感器,并且含有一个第二IIC接口,可用于连接外部磁力传感器,并利用自带的数字运动传感器(DMP:Digital Motion Processor)硬件加速引擎,通过主IIC接口,向应用端输出完整的9轴融合演算数据。有了DMP,我们可以使用InvenSense公司提供的运动处理资料库,非常方便的实现姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度。
2.4 MPU6050的特点
1.以数字形式输出6轴或9轴的旋转矩阵,四元数,欧拉角格式的融合演算数据。
2.移除加速度与陀螺仪轴间敏感度,降低设定给与的影响与感测器的漂移。
3.自带1024字节的FIFO,有助于降低系统功耗。
2.5 MPU6050的单片机的连接
MPU6050通过IIC来和单片机通信,SCL和SDA是连接MCU的IIC接口,MCU通过这个IIC接口来控制MPU6050,另外还有一个IIC接口:AUX_CL和AUX_DA,这个接口可用来连接外部从设备,比如磁传感器,这样就可以组成一个九轴传感器。VLOGIC是IO口电压,该引脚最低可以到1.8V,我们一般直接接VDD即可。AD0是从IIC接口的地址控制引脚,该引脚控制IIC地址的最低位。如果接GND,则MPU6050的IIC地址是:0X68,如果接VDD,则是0X69,注意:这里的地址是不包含数据传输的最低位!
2.6 STM32单片机控制流程图
STM32单片机主要是通过IIC通信,从MPU6050传感器中读出DMP中输出的四元数q0,q1,q2,q3。然后通过公式:
Pitch = asin(-2*q1*q3+2*q0*q2)*57.3;(俯仰角)
Roll=atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;(滚动角)
Yaw=atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;(航偏角)
得到三个姿态角,然后通过串口通信,将三个姿态角加上原始数据(加速度传感器读到的数据和陀螺仪传感器得到的数据)发送到PC端的应用程序。
名词解释:
俯仰角:物体坐标系X轴与水平面的夹角。当物体坐标系的X轴在惯性坐标系XOY平面上方时,俯仰角为正,否则为负。
滚动角:物体坐标系zb轴与通过机体xb轴的铅垂面间的夹角,机体向右滚为正,反之为负。
航偏角:机体坐标xb轴在水平上投影与地面坐标系xg轴之间的夹角,由xg轴逆时针转至机体xb的投影线时,航偏角为正,反之为负。
2.7 主函数程序
int main(void)
{
u8 report=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //初始化中断优先级
USART1_Init(9600); //初始化串口
Delay_Init(); //初始化延时函数
MPU_Init(); //初始化MPU6050
while(mpu_dmp_init()); //初始化DMP
TIM4_Init(99, 71); //初始化定时器TIM4
while(1)
{
if(Flag_50ms == 1){
Flag_50ms = 0;
mpu_dmp_get_data(&pitch,&roll,&yaw); //获得姿态角
//将数据传输到PC端应用程序
usart1_report_imu(accel[0],accel[1],accel[2],gyro[0],gyro[1],gyro[2],roll,pitch,yaw);
}
}
}
2.8 KEIL5的使用方法
1.首先是在Project->New uVison Project中创建新的文件工程
2.在target文件夹下创建3个子文件夹,分别命名CMSIS,FWLIB,USER
3.在CMSIS中存放内核支持文件和设备支持文件
4.在FWLIB文件中存放外部设备驱动文件
5.在USER文件中存放自己的文件,如主函数等
6.写程序,保存,编译,下载,运行
3.PC应用程序处理单片机传来的数据并显示波形
3.1 C#语言简介及使用方法
C#是一种简单的,现代的,类型安全的,由C和C++衍生出来的面向对象的编程语言。它牢牢根植于C和C++语言之上,并可立即被C和C++的使用者所熟悉。
简单是C#语言的第一个特点。C#的简单易学是其想对你于复杂的C++的一个明显优势,该语言在设计时的首要目标就是简单,以提高开发者的效率。在C#中,没有C++中流行的指针。默认的,在受保护的代码中不允许执行诸如直接存取内存等不安全的操作。在C#语言中,由于装箱和拆箱的机制,使用者可以不必记住基于不同处理器架构的隐含类型以及各种整型的变化范围。这中系统允许使用者将各种类型作为一个对象查看,以确定它是一个原始类型还是一个真正的类。
C#的现代性很大程度上是由.NET框架体现出来的。
C#是面向对象编程语言。所有的东西都被封装在类中,包括实例成员或静态成员。这样就使C#代码更加易读,且有助于减少潜在的命名冲突。类中的方法默认是非虚拟的,不能被派生类重写。这主要是为了消除由不经意间重写方法而导致另外一些源码出错的问题。用户要重写方法,就必须明确的使用虚拟标志。这种做法也缩减了虚拟方法表的大小。
C#不仅支持传统面向对象语言的private,protected和Public三种存取权限,而且还新增了第四种:internal。
C#还有一个重要特点是类型安全。在使用C++指针的时候,你可以自由地对它进行强制类型转换,将其变为任何类型,只要内存支持这种操作,它就能工作。这在C#中是不允许的,因为这并不符合企业级编程语言的类型安全要求。C#实施了最严格的类型安全,以保护自己及垃圾收集器。首先,编码者不能使用没有初始化的变量。对于对象的成员变量,由编译器清零。而局部变量则由编码者清零。当你使用一个没有初始化的变量时,编译器会提示你该怎么做。其次,C#取消了不安全的类型转换。你不能把一个整型强制转换成一个引用类型。再次,C#也包括了边界检查的功能,例如,我们不能访问任何超出了数组边界的元素。另外,在C#中,被传递的引用参数也是安全的。
C#在.NET框架下,与ADO.NET和ASP.NET一起构成了一个优秀的数据库及网络应用开发组合,这也是现如今C#应用最广泛的方面。
3.2 面向对象的概念及类的特性
面型对象方法是一种把面向对象的思想应用于软件开发过程中,指导开发活动的系统学习方法,简称OO方法,它是建立在“对象”概念基础上的方法学。对象是由数据和允许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相似性质的一组对象。而继承是对具有层次关系的类的属性和操作进行共享的一种方式。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制来认识,理解,刻画客观世界并设计和构建相应的软件系统。
在程序执行期间,具有不同的状态且其他特性都相似的对象会被分组到对象的类中,这是关键字class的由来。
类有三大特性:封装,继承和多态。封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装将数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能看到对象的外在特性,而对象的内特性对用户是隐蔽的。封装的目的在于把对象的设计者和对象的使用者分开,使用者不必知晓行为实现的细节,只需使用设计者提供的消息来访问对象。类描述了具有共同特性和行为的对象集合。继承使得代码变得优雅,并且具有更好的扩充性。所谓的多态是指通过继承而具有相关特性的不同的类,它们的对象能够对同一个方法的调用做出不同的响应。
3.3 C#绘图机制
Windows窗体中提供的图形分为下面三大类:1.二维矢量图形2.图像处理3.版式。本次程序设计使用的是二维矢量图形。二维矢量图形是绘图的基本元素(例如,直线,曲线和图形)。它们由坐标系统上的一些点和另外一些描述参数指定。例如:直线可通过它的两个端点来指定;而矩形可通过确定其左上角的点并给出其宽度和高度的一对数字来指定;简单路径可以通过由直线直接的点的数组来指定;贝塞尔样条曲线是由4个控制点指定的复杂曲线。GDI+提供了存储基元自身信息的类和结构,存储基元绘制方式信息的类以及实际进行绘制的类。例如:Rectangle结构存储矩形的位置和尺寸;Pen类存储有关线条颜色,线条粗细和线型的信息;而Graphics类具有用于绘制直线,矩形,路径和其他图形的方法。还有几种Brush类,他们存储了有关如何使用颜色或图案来填充封闭图形和路径的信息。
一般来说,绘图至少分为下面两个步骤。
第一步,获得Graphics对象,要在应用程序中绘图,要先获得Graphics对象,然后才可以使用GDI+绘制线条和形状,兑现文本或显示与操作图像。这个对象可以通过下面这几种方式获取。
在窗体或空间的Paint时间中接收对图形对象的引用,作为PaintEventArgs的一部分。在为控件创建绘制代码时,通常会使用此方法来获取对图形对象的引用。
调用某控件或窗体的CreateGraphics方法以获取对Graphics方法以获取对Graphics对象的引用,该对象表示该控件或窗体的绘图图画。如果在已存在的窗体或控件上绘图,最好使用此方法。
由从Image继承的任何对象创建Graphics对象。此方法在更改已存在的图像时十分有用。
第二步,绘制和操作形状与图像
Graphics对象在创建后,可用于绘制线条和形状,呈现文本或显示与操作图像。与Graphics对象一起使用的主要对象有一下4种。
Pen类--用于绘制线条,勾勒形状轮廓或呈现其他几何表示形式。
Brush类--用于填充图形区域,如实心形状,图像或文本。
Font类--提供在呈现文本时要使用什么形状的有关说明
Color类--表示要显示的不同颜色
Graphics类是GDI+的核心功能,它是实际绘制直线,曲线,图形,图像和文本的类。Graphics的FillRectangle方法可以接收指向LinearGradientBrush对象的指针,该对象与Graphics对象配合工作以使用一种渐变色填充矩形。Font和StringFormat对象影响Graphics对象绘制文本的方式。Matrix对象存储并操作Graphics对象的世界变换,该对象用于旋转,缩放和翻转图像。GDI+提供了用于组织图形数据的几种结构。而且某些类的主要作用是结构化数据类型。例如,BitmapData类是Bitmap类的帮助器;PathData类是GraphicsPath类的帮助器。
3.4 Visual Studio 2008开发环境的使用
Visual Studio 2005提供了解决方案和项目,帮助我们有效管理开发工作所需的项。简单地说,解决方案是用来组织管理项目的,而项目是用来组织管理了文件,引用,数据连接等项目资源。
选择“文件”->“新建”->“项目”命令,在弹出 的对话框的左侧选择:“其他项目类型”->“Visual Studio 解决方案”,选择“空白解决方案”,输入解决方案的名称,选择一个存放的位置。单击“确定”按钮。这样,一个空白的解决方案就建立了,接着我们将向其中加入项目。
向一个解决方案添加新项目,在解决方案资源管理器中,点击“解决方案”在弹出的菜单中选择“添加”->“新建项目”,一个对话框弹出来了。在对话框的左边选择“Visual C#”->“Windows”右边选择“控制台应用程序”,输入名称:项目1,单击“确定”按钮。一个项目被创建并加入到解决方案中。这样就建立成功了一个工程,可以用来编辑C#程序了。
3.5 PC应用程序分析
3.5.1 PC串口接收数据程序
串口接收源代码函数
private void SerialPort_DataReceived(object sender,SerialDataReceivedEventArgs e)
{
int bufferlen = serialPort.BytesToRead; //重串口中得到的数据字节数
byte[] bytes = new byte[bufferlen];
serialPort.Read(bytes, 0, bufferlen); //接收一个包的数据
if(bufferlen > 0)
{
if (bytes[0] == (byte)0x88) //分析包头
{
if (bytes[1] == (byte)0xAF) //分析包命令
{
if(bytes[2] == 18) //分析包数据长度
{
for (int i = 0; i < 9;i++ ) //将包数据解析到appearbuff数组中
{
appearbuff[i] = (short)((bytes[3 + i * 2] << 8) | bytes[4 + i * 2]);
}
//计算步态分析数据
step = CaculateStep(appearbuff[0],appearbuff[1],appearbuff[2],Constants.GRESOLUTION);
//计算步态分析数据最大值
stepmax = StepPeakAnalyze(appearbuff[0],appearbuff[1],appearbuff[2],Constants.GRESOLUTION);
AppearOriData(); //显示MPU6050数据 及 用列表显示原始数据
if (issavexmlfile) //要保存数据
{
//把数据添加到xml文件中
AddElementInXML(appearbuff,name,Constants.appearbuffnum,path,xmlcount,step);
xmlcount++; //记录xml文件中元素的个数
}
if(StoreSampleNum(step)) //判断是否采样完毕
{
//将采样的数据保存到panel1的disFStep数组中
Array.Copy(samplebuffer,panel1.disFStepBuff,samplenum); textBox3.AppendText("samplecount = "+samplenum+"\r\n");
Thread fftthread = new Thread(new ThreadStart(FFTModle));
fftthread.Start(); //采样完成后 立刻开启线程 对采样数据进行快速傅里叶变换
}
//缓存区接收数据
StoreNum(disPicBuff1,disPicBuff2,disPicBuff3,appearbuff,Constants.pointnum,step);
}
}
}
}
}
代码分析:函数SerialPort_DataReceived是在串口接收到数据后就会被调用。在这个函数首先是调用串口对象的Read函数,将串口接收到的数据存放在bytes数组中。然后对传来的数据进行解析,首先是分析包头,然后分析包指令,再分析包长度,分析完后,就可以取出MPU6050分析完的数据,然后将加速度传感器,陀螺仪传感器的数据和姿态角数据存放在appearbuff数组中,然后再通过公式进行步态数据分析,并将计算后的数据保存在step变量中,通过AppearOriData函数显示加速度,角速度,姿态角,步态分析数据。显示数据后,是对是否要保存数据到文件的判断,如果要将数据保存到文件中,则会调用AddElementInXML函数将加速度,加速度,姿态角,步态分析数据保存到XML文件中。如果不保存或保存完后,都会执行StoreSampleNum函数判断是否要采样步态分析数据,这个函数返回一个bool值,如果不需要采样则返回false,如果需要采样,则会将采样的数据保存到samplebuff数组中,然后采集完后返回true,采集完后就会开启运算FFT线程,对采样数据进行快速傅里叶变换。程序开启线程后就继续往下执行,调用StoreNum函数将要显示的数据存放到disPicBuff1,disPicBuff2,disPicBuff3三个数组中。
定时器程序:函数restarttime用来定时刷新panel上的波形。代码如下:
public void restarttime(object obj)
{
//只要有任何一个显示图形按钮按下 就进入
if (isDispAccPic || isDispTuoPic || isDispZiPic || isDisStepPic || isDisFFTPic)
{
Array.Copy(disPicBuff1,panel1.disPicBuff1,storecount); //重缓存区中取出数 复制到 panel1的绘图数组中
Array.Copy(disPicBuff2,panel1.disPicBuff2,storecount);
Array.Copy(disPicBuff3,panel1.disPicBuff3,storecount);
if(isDisFFTPic) //是否要进行fft变换图显示
{
isDisFFTPic = false;
button12.Enabled = true;
textBox3.AppendText("已经按下显示fft变换图形按钮\r\n");
if (fftisok) //fft变换是否结束
{
textBox3.AppendText("fft变换已经结束");
fftisok = false; //清除标志位
panel1.isDisFFTStepPic = true; //显示fft变换后的图 以及 其对应的时域图
//将fft变换后的数据存到panel1中的disFFTBuff中
Array.Copy(storefftarr, panel1.disFFTBuff, samplenum);
}
else
MessageBox.Show("fft变换还没有结束");
}
if(panel1.isAccPaint || panel1.isTuoPaint || panel1.isZitPaint || panel1.isStePaint || panel1.isDisFFTStepPic)
panel1.ReStartPaint(); //重新绘图
}
}
进入函数后首先判断显示图像标志位是否按下,如果按下,则从缓冲区中取出850个点的数据,然后判断是否要进行fft变换,如果fft变换标志位为true则将fft变换后的数据复制到panel1对象中的disFFTBuff数组中,接着判断绘图标志位是否为true,如果为true,则调用panel1的ReStartPaint函数进行重新绘图。然后就可以在panel1上看到加速度或角速度或姿态角或步态分析的波形了。
3.5.2 PC应用程序界面图
界面最上面一行是菜单,用来设置波特率和串口端口号的。然后中间黑色的部分是用来绘图的,显示不同数据的波形。最下面一行,从左边开始,是可以勾选的。如果方框被勾选,就会显示这一栏的数据,中间有个“单片机传来的原始数据”这个是显示MPU6050采集的原始数据,后面的单位表示用原始数据乘以单位,就是实际数据的大小。再往右的一栏中设置了8个按钮,这些按钮是显示数据和绘图用的。按下按钮就会对相应的标志位进行设置。右下角有两个按钮是用来开关串口的。最右侧的一栏分两个部分,一部分是用来保存数据到文件用的。通过输入文件名,然后按下开始保存数据按钮,然后就可以将数据保存到XML文件中了。下面的
数据分析是用来显示步态分析数据的,在“设置采样数目”一栏中如果输入要采样的数,然后按下“开始采样傅里叶变换数据”按钮,程序就会运行fft变换线程,对采样数据进行傅里叶变换。PC应用程序界面如图3.5.1
四.实训总结与心得体会
在实训之前,一直都是学习的理论知识,上学期就学过EDA技术,但是还没有实际用VHDL语言编写一个程序看看现象。在实训过程中体会到了理论和实际应用的差距,在实验过程中遇到了许多问题,并不是像想想中的那么简单。刚开始按着实验教程一步一步的简历工程,然后输入自己写的程序,编译后发现出现了好多错误。有的是文件名和实体名不一致,有的是忘记了加上分号,有的是实体或结构体不完整。排除语法错误后,绑定了引脚,下载程序看现象时
发现和自己预计的结果不一样。于是又检查程序,因为原来都是用的C语言写的程序,所以习惯了当给一个变量赋值时,变量中的数会立刻改变。然后在VHDL语言中,就把信号量当做变量使用了,但是在VHDL语言中,信号只有在出进程后数值才会改变,所以导致在进程中赋值的信号不能立刻改变,从而影响了实验现象。后来换成变量后,实验成功了。体会到了实践出真理的道理。实训第二部分是设计PC应用程序显示惯导数据波形。首先是通过STM32单片机采集MPU6050传感器传来的数据,刚开始在使用STM32单片机的时候连怎样建立工程都不知道。因为STM32单片机使用的是ARM内核,所以不能像51单片机那样建立简单的工程。STM32需要有内核支持文件,还要有库文件,在有了这些基本的支持之后,才能编写程序,在调用库函数包的时候才不会编译出错。在熟悉MPU6050的通信方式后,查阅资料怎样对MPU6050进行寄存器设置,在设置寄存器之后,就直接可以通过IIC通信协议收到MPU6050的数据了。然后STM32单片机再通过串口将数据传输到PC应用程序上。PC应用程序调用系统类SerialPort,生成一个串口对象,然后通过调用串口的read函数,读取STM32单片机发来的数据。再对数据包进行解析之后,将数据存到程序定义的数组中,当做缓存区使用。程序中设置定时器200ms进入一次定时器函数,然后从缓存区中取出数据,送到panel1对象中,调用ReStartPaint函数刷新panel,调用RestartPaint函数后将进入到MyPanel类中的OnPaint函数中,通过e.Graphics方法产生一个画笔,可以在MyPanel上绘图。画笔再调用DrawLine方法,将两个数据的点连接起来。形成一个波形。经过这次实训,将自己的理论与实际结合在一起,体会到了理论和实践的差别。在刚开始写PC应用程序时,是在Form类的OnPaint中绘图,然后当要绘制的点数越来越多的时候,串口接收的数据会变慢。后来发现是因为,绘图和接受数据是在一个对象,一个线程中进行的,当绘图点数变多时,绘图时间会变长,所以就会延迟接收数据的时间,使得数据接收变慢。后来改进的方法是在MyPanel类的OnPaint方法中绘图,Form类中只接收数据,然后绘图时从Form缓存区中取出数据显示就行。然后大大提高了绘图的效率。从这件事中自己也明白了在做实际项目的时候,要考虑到多种情况,不能只按自己的想法编程,要合理的分析问题,参考类似问题的解决办法。这样会节省出很多编程时间,提高编程效率。最后感谢老师辛勤的付出,耐心指导我们实训。针对每个人不同的问题耐心的回答。这次实训增加了自己对自己专业课的认识!希望还有更多的机会实训。