物理与电子工程学院
《嵌入式系统与应用》
设计性实验报告
题目 基于ARM7的多通道仪表数据采集实验
系 别 物理与电子工程学院
年 级 电子科学与技术
班 级 学 号
学生姓名
指导教师
实验时间
目录
引言.................................................................................................................................................. 2
课题要求........................................................................................................................................... 2
1.本课题的目的........................................................................................................................... 2
2.运行环境.................................................................................................................................. 3
正文.................................................................................................................................................. 4
一.课题分析............................................................................................................................. 4
二.系统设计............................................................................................................................. 4
2.1新建工程........................................................................................................................ 4
2.2打开main.c 文件,编辑Main_Task 任务中的代码........................................................... 4
2.3编写OnKey()函数,响应键盘消息.................................................................................. 4
2.4编写绘图显示任务Display_Task....................................................................................... 5
2.5编写4 路AD 采集任务ADx_Task.................................................................................. 6
2.7生成发行版本的.bin 文件,通过USB 下载到嵌入式开发平台中,运行并检查输出结...... 6
果。.................................................................................................................................... 6
三.技术实现问题......................................................................................................................... 6
3.1数码管显示及闪烁显示的代码......................................................................................... 6
3.2在LCD屏条形图中超出部分闪烁原理............................................................................. 7
3.3条形图顶端显示具体电压值的代码如下:....................................................................... 8
3.4实现条形图闪烁显示及文本框显示相应数值.................................................................... 8
3.5按键实现单通道图形显示................................................................................................ 9
四. 总结与体会......................................................................................................................... 12
设计性实验报告成绩: 指导教师签名:.................................................... 13
引言
随着工业自动化与信息化的不断发展,数据采集已经成为了计算机与外部物理世界连接的桥梁。数据采集系统广泛地应用于工业生产中设备工作状况的监测、控制领域中的闭环控制系统及仿真领域的半实物仿真系统。
传统的数据采集装置通常由单片机及采集卡组成, 其采集通道数较少、单任务的软件结构及实时性差等不足之处已无法满足人们的需求。ARM ( Advanced RISC Machines) 是基于RSIC 架构的数据宽为32 位可嵌入操作系统的微处理器。由于其体积小、价格低、可靠性高、低功耗等特点在工业自动化、国防、运输等领域得到了广泛的应用。
本次设计是基于ARM的多通道实时数据采集系统;该系统由下位机系统及上位机软件组成,下位机硬件主要基于ARM工控开发平台、数据采集板及模拟量输出板,采用μC/OSⅡ实时多任务操作系统,实现多通道数据的采集、数据存储及模拟量的输出,并将采集数据实时传送至上位计算机;上位机软件接收数据进行监控,图形化显示数据变化曲线,并控制下位机的模拟量输出功能;通过实验验证,下位机系统能够实现多通道数据的采集、存储及模拟量的输出,μC/OSⅡ操作系统完成多任务的实时调度,上位机软件成功进行模拟量数据的采集监控及数据变化的图形显示,整个系统具有良好的实时性。
课题要求
1.本课题的目的
摘要:采用多任务编程方法,每个任务监视一路AD 转换, 每一路AD 的转换结果在液晶屏上用一个条形图的长短来表示,直观地显示每路模拟输入电压的大小。可以通过文本框给每路AD 设置警戒值,某路输入超出警戒线之后条形图中超出的部分会以闪动的方式显示。
在此基础上,利用实验箱中的数码管显示每一路的电压采样值,并能在超出警戒值的情况下闪烁显示。或在LCD屏上对应条形图的顶部显示具体的电压值。
2.运行环境
硬件:ARM嵌入式开发平台、用于ARM7TDMI的JTAG仿真器、PC机Pentium100以上。
软件:PC机操作系统Win98、Win2000或WinXP、ARM SDT2.51或ADS1集成开发环境、仿真器驱动程序、超级终端通讯程序。
正文
一.课题分析
数据采集系统置于被监控的设备处,通过传感器对设备的电压或者电流信号进行采样、保持,并送入A/D转换器变成数字信号,然后将该信号送到FIFO中。当FIFO中存放的数据到了一定数目时,由ARM7从FIFO中读出,然后通过ARM7的以太网接口送给上位机。多路采集通道经过模拟开关后再进入A/D转换器。CPLD是整个系统的控制核心,它控制采集通道的切换、A/D转换器的启/停、转换后的数据在FIFO中的存放地址发生器、产生中断请求以通知ARM7读取存放在FIFO中的数据等。
二.系统设计
2.1新建工程
将“Exp23 多通道仪表数据采集实验”中的文件加入工程。
2.2打开main.c 文件,编辑Main_Task 任务中的代码
用init_ADdevice()函数初始化处理器的AD 转换硬件,启动消息循环。
2.3编写OnKey()函数,响应键盘消息
流程图如图5-4 所示。提示:
1) 这里设置了两个文本框,用来输入通道编号和该通道的警戒值,在键盘消息响应函数里针对两个文本框分别作出处理,只处理回车键和取消键,其他键由控件本身处理。程序里用变量EditNumber 指示当前要编辑的文本框控件;用变量input 指示该文本框控件是否处于输入编辑状态。以此决定回车键应该执行的功能。
2)当文本框控件不是编辑状态时,回车将使其进入编辑状态,在程序里用SetWndCtrlFocus( )函数将焦点转移到该控件并用SetTextCtrlEdit() 函数设置为编辑状态;当文本框正处于编辑状态时,回车将使其退出编辑状态,并将要编辑的文本框切换到另一个文本框控件,取消键的处理和这种情况类似。
3) 如果当前要编辑的文本框是警戒值输入框,在编辑状态中回车确定后,所输入的通道编号以及警戒值就会保存在数组WarnningData 中,代码如下:
WarnningData[ Unicode2Int(pChannelTextCtrl->text)]=Unicode2Int(pValueTe xtCtrl->text);
图5-4 流程图
2.4编写绘图显示任务Display_Task
绘制文本框和条形图等,并实现文本框编辑过程中和超过警戒值后的动画显示。流程图如图5-5 所示。
提示:
1)程序中用TextOut()函数显示文本框的提示信息,用数组edit 记录两个文本框是否处于编辑状态,用变量IsEdit 指示提示信息是否显示。实际上,IsEdit这个变量在显示任务循环一次就改变一次状态,当IsEdit==1 时将提示信息擦掉,否则保持显示不变。这就是闪烁显示的原理,表示AD 转换结果的条形图超出警戒值的部分的闪烁也是这样实现的,随着任务的循环隔次的改变状态。
2)和变量IsEdit 的作用类似,warnning[x]是条形图闪烁的指示变量。当某路AD 转换的结果result_ADx 大于对应通道的警戒值Warnni ngData[x]时,根据warnning[x] 的值决定条形图的长度是和result_ADx 对应还是和W arnningData[x]对应,这样看起来条形图的长度是变化的,效果就是超过警戒线的那部分在闪烁。
3)这里条形图实际上是一个实心矩形,用FillRect()函数填充。
图5-5 Display_Task 流程图
2.5编写4 路AD 采集任务ADx_Task
提示:
1)使用GetADresult()函数即可得到某路AD 输出的二进制代码。由于处理器的8
路10 位AD 转换单元的最大输入电压是2.50V,所以实际电压值就是
result_ADx=GetADresult(x)*2.50/1024;
2.6用ARM SDT 2.5 或ADS1.2 编译、下载并调试上述程序,检查运行结果。
2.7生成发行版本的.bin 文件,通过USB 下载到嵌入式开发平台中,运行并检查输出结
果。
三.技术实现问题
3.1数码管显示及闪烁显示的代码
// 0通道显示
ZLG7289_ENABLE();//使zlg7289占有同步串口
Delay(5);//延时
WriteSDIO(ZLG7289_CMD_DATA1|6);//数码管以方式1译码,第一个数码管亮
WriteSDIO(((int)(result_AD0))%10);//显示个位
Delay(1);//延时
if((int)((result_AD0))>9)
{//键值大于9显示十位
WriteSDIO(ZLG7289_CMD_DATA1|7);//发送十位数据
WriteSDIO(((int)(result_AD0))/10);
Delay(1);
WriteSDIO(ZLG7289_CMD_HIDE);//使一、二、三这三位数码管显示
WriteSDIO( 0xff);
}
else
{//键值小于10不显示十位
WriteSDIO(ZLG7289_CMD_HIDE);//使个位数码管显示
WriteSDIO(0x7f);
}
a=0xff;
if(result_AD0>WarnningData[0])
a=0x3f;
Delay(1);
WriteSDIO(ZLG7289_CMD_FLASH);//闪烁
WriteSDIO(a);
通道1、2、3和通道0一样只需将通道0中的输入值和警戒值改成对应通道的值就可以实现,当然要选择不同数码管来显示,具体哪个数码管可由自己选择。
3.2在LCD屏条形图中超出部分闪烁原理
利用FillRect()函数画出条形图,如果采样值小于警戒值则正常画图,如果超过警戒值,则先画采样值所对应的条形图,后画出警戒值所对应的条形图,两者无限循环这样现实的现象就是超出部分闪烁。
闪烁显示的代码如下:
if(result_AD0<=WarnningData[0])
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
}
else
{
if(warnning[0]==1)
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210, GRAPH_MODE_NORMAL,COLOR_BLACK);
warnning[0]=0;
}
else
{
warnning[0]=1;
FillRect(pdc, 110, (int)(210-WarnningData[0]*20/3.3), 130,210, GRAPH_MODE_NORMAL,COLOR_BLACK);
}
}
这是通道0的代码,通道1、2、3的代码同上,只要改变相应的输入值和警戒值即可。
3.3条形图顶端显示具体电压值的代码如下:
Int2Unicode((int)(result_AD0),result_AD0_16);
TextOut(pdc,114,(int)(198-result_AD0*20/3.3),result_AD0_16,TRUE, FONTSIZE_SMALL);
相应的也只需改变对应通道的输入值和警戒值即可实现其他通道电压值显示。
3.4实现条形图闪烁显示及文本框显示相应数值
完整代码如下:
//0通道
if(result_AD0<=WarnningData[0])
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
}
else
{
if(warnning[0]==1)
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210, GRAPH_MODE_NORMAL,COLOR_BLACK);
warnning[0]=0;
}
else
{
warnning[0]=1;
FillRect(pdc, 110, (int)(210-WarnningData[0]*20/3.3), 130, 210, GRAPH_MODE_NORMAL,COLOR_BLACK);
}
}
Int2Unicode((int)(result_AD0),result_AD0_16);
TextOut(pdc, 114, (int)(198-result_AD0*20/3.3), result_AD0_16, TRUE, FONTSIZE_SMALL);
其他通道的显示和0通道类似,只需修改相应坐标及相应数值即可。
3.5按键实现单通道图形显示
在U8 onKey(int nkey, int fnkey)函数中添加一个变量f
static int f;
switch(nkey)
{
case 0:
f=0;
break;
case 1:
f=1;
break;
case 2:
f=2;
break;
case 3:
f=3;
break;
case 7:
f=4;
break;
}
在void Display_Task(void * Id) 中添加相应功能,代码如下:
If(f==0)//0通道条形图及文本显示
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD0),result_AD0_16);
TextOut(pdc, 114, (int)(198-result_AD0*20/3.3), result_AD0_16, TRUE, FONTSIZE_SMALL);
}
If(f==1)//1通道条形图及文本显示
{
FillRect(pdc, 110, (int)(210-result_AD1*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD1),result_AD1_16);
TextOut(pdc, 114, (int)(198-result_AD1*20/3.3), result_AD1_16, TRUE, FONTSIZE_SMALL);
}
If(f==2)//2通道条形图及文本显示
{
FillRect(pdc, 110, (int)(210-result_AD2*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD2),result_AD2_16);
TextOut(pdc, 114, (int)(198-result_AD2*20/3.3), result_AD2_16, TRUE, FONTSIZE_SMALL);
}
If(f==3)//3通道条形图及文本显示
{
FillRect(pdc, 110, (int)(210-result_AD3*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD3),result_AD3_16);
TextOut(pdc,114,(int)(198-result_AD3*20/3.3),result_AD3_16,TRUE, FONTSIZE_SMALL);
}
If(f==4)//所有通道条形图及文本显示
{
FillRect(pdc, 110, (int)(210-result_AD0*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD0),result_AD0_16);
TextOut(pdc,114,(int)(198-result_AD0*20/3.3),result_AD0_16,TRUE, FONTSIZE_SMALL);
FillRect(pdc, 110, (int)(210-result_AD1*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD0),result_AD1_16);
TextOut(pdc,114,(int)(198-result_AD1*20/3.3),result_AD1_16,TRUE, FONTSIZE_SMALL);
FillRect(pdc, 110, (int)(210-result_AD2*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD0),result_AD0_16);
TextOut(pdc,114,(int)(198-result_AD2*20/3.3),result_AD2_16,TRUE, FONTSIZE_SMALL);
FillRect(pdc, 110, (int)(210-result_AD3*20/3.3), 130, 210,GRAPH_MODE_NORMAL, COLOR_BLACK);
Int2Unicode((int)(result_AD3),result_AD3_16);
TextOut(pdc,114,(int)(198-result_AD3*20/3.3),result_AD3_16,TRUE, FONTSIZE_SMALL);
}
四.总结与体会
因为我前面几个实验做的都是ARM7的实验,所以在选计性实验的时候,选择的是基于ARM7的多通道仪表数据采集实验,虽然有了前面几个实验的基础,不过我仍然没有十足的把握能够在短时间内完成上述功能。因为一个人想把一个设计性的实验完全做完是不太容易的,所以我们必须要将前面所掌握的知识融会贯通,并灵活运用,这样才能把这次实验做完。
首先按照的实验要求,将以前的实验拿出来巩固,将有关函数的用法弄清楚,不懂的请教他人,然后和做这个实验的同学讨论,最终有了一个比较的明确的方向,因为以前做过LED显示及键盘实验,所以可以加上这些功能,可是真正做的时候并不是那么简单的,总是遇到这样或那样的问题,当然遇到问题就要解决了,这就要靠自己发现错误并改正,当然一个人的力量是有限的,借助同学的帮助,终于把程序中的错误都改正过来了。
这次实验使我学到了很多,纸上得来终觉浅,只有理论知识是不行的,我们要把理论知识和实践结合起来,绝知此事要躬行。这样才能发挥理论知识的用途。做实验的时候不能太急躁,要慢慢来,凡事都不能一气呵成的,都是要经历一定的过程才能到达理想的彼岸,途中总会遇到一些问题,遇到问题我们不能退缩,要勇敢面对,这样我们才能从中有所收获。
此次实验的不足之处是本想加入触摸屏功能,但对于相关函数的使用不是太懂,最终选择放弃了。希望在以后的实验或实践中能够实现更多功能。