基于ARM9风扇控制系统方案.docx
《基于ARM9风扇控制系统方案.docx》由会员分享,可在线阅读,更多相关《基于ARM9风扇控制系统方案.docx(25页珍藏版)》请在冰豆网上搜索。
基于ARM9风扇控制系统方案
嵌入式课程设计实验报告
项目:
基于ARM9的风扇控制系统
一实验目的1
二实验环境1
三设计功能2
四实验原理分析3
4.1液晶屏显示3
4.2直流电机控制3
4.3键盘控制4
4.4蜂鸣器控制4
4.5LED控制5
五软件设计方案6
5.1计时模块6
5.2液晶显示模块7
5.3键盘模块8
5.4直流电机控制模块8
5.5LED模块9
5.6蜂鸣器模块10
六调试与结果11
6.1程序编译与安装11
6.2实验结果11
七个人工作自我评估17
7.1方立超个人工作报告17
7.2周超个人工作报告17
7.3程文博个人工作报告18
八程序附件20
一实验目的
此次嵌入式控制系统综合实验,我们小组以直流电机为主要控制对象,以TI公司推出的新一代OMAPL138高速处理器为控制器模拟了电风扇的基本功能,并在此基础之上扩展了时间显示、LED灯装饰、定时等功能。
通过本次综合设计,我们主要达到以下主要目的:
了解Linux系统中屏幕显示的接口,及访问方法;
1、熟悉Linux下FrameBuffer技术的概念和应用;
2、学习使用Omapl138在Linux+QT下访问键盘的方法,了解Linux+QT下键盘的使用原理及编程方法;
3、了解Linux系统中标准键盘的接口,及访问方法;
4、了解蜂鸣器的发声原理;学习Linux下非标准设备的访问控制方法;
5、熟悉嵌入式系统开发软硬件设计的基本过程;
6、大体实现期望的风扇控制系统的基本功能。
7、了解PWM控制直流电机的基本原理;
二实验环境
硬件:
PC兼容机一台、ICETEK—OMAPL138-A实验箱一只。
其中实验箱主要由4部分组成:
(1)实验箱部分:
一个独立的数字信号源,可提供四种波形、三路输出;信号的波形、频率、幅度可调;+5V(5A)、+12V(1A)、+9V(0.5A)多种直流电源输出;底板插座完成A/D信号输入和D/A输出;一个测试模块,包括18个测试点,可以测量PWM输出、AD输入和DA输出波形;一个双信号发生器,方便对许多实际情况中的两个信号进行分析。
(2)通用DSP开发系统部分:
一个USB2.0接口开发系统,支持C2000/VC33/C5000/C6000的开发应用。
(3)通用控制及显示模块:
一块128×64点阵图形显示LCD屏;四组发光二极管,每组三个红黄绿LED灯;一个可由DSPI/O脚控制的蜂鸣器进行音频输出;一个D/A输出音频插座,可直接接插耳机;9个键数字键盘(1~9);4个拨动开关(DIP),可实现复位和设置DSP应用板参数。
(4)DSP主处理板部分:
支持:
ICETEK-F2812-A板、ICETEK-VC5509-A板、ICETEK-VC5416-A板、ICETEK-VC33-AR板、ICETEK-C6713-A板、ICETEK-LF2407-A板等。
图2.1ICETEK-OMAPL138-A评估模块接口布局
软件:
PC兼容机安装windows7,并通过virtualbox虚拟机平台安装Ubuntu版本的Linux系统以及超级终端。
三设计功能
本次综合实验我们讲主要实现风扇的以下功能:
1.风扇的开机/关机;
2.风扇开关状态及挡位的显示;
3.时间的显示,并可以分别对时、分、秒进行设置;
4.定时时间和计时时间的设置;
5.蜂鸣器报时;
6.十二个led灯的流水闪烁。
四实验原理分析
本次设计实验以ICETEK-OMAPL138-A的双核处理器扩展评估板为核心,它通过扩展接口与实验箱的显示/控制模块连接,可以控制其各种外围设备,也可以接收外设发送的各种数据、信息。
CTR设备连接在EMIFA的片选4上,所以通过操作以片选4为基地址(0x64000000)的空间再加上设备控制寄存器的偏移就可以访问到实验箱上的CTR设备。
4.1液晶屏显示
液晶显示模块中有两片显示缓冲存储器,分别对应128*64液晶屏上的每一个像素点,向其中写入“1”“0”控制其显示和不显示。
首先利用命令控制字选择操作位置(页数、列数)后,再将需要显示的数据写入到液晶显示模块的缓存中,将数据发送到相应的数据控制地址即可。
4.2直流电机控制
本次实验中应用的直流电机采用的是定频调宽法。
PWM输入对应ICETEK-OMAPL138-A板上P4外扩插座第26引脚的UHPI_HCNTL1信号,DSP将此引脚配置成GPIO,并在此引脚上给出PWM信号用来控制直流电机的转速;图中的DIR输入对应ICETEK-OMAPL138-A板上P4外扩插座第29引脚的MMCSD1_D0信号,DSP将此引脚配置成GPIO,并在此引脚上给出高电平或低电平来控制直流电机的方向。
从DSP输出的PWM信号和转向信号先经过2个与门和1个非门再与各个开关管的栅极相连。
当电动机要求正转时,MMCSD1_D0给出高电平信号,该信号分成3路:
第1路接与门Y1的输入端,使与门Y1的输出由PWM决定,所以开关管V1栅极受PWM控制;第2路直接与开关管V4的栅极相连,使V4导通;第3路经非门F1连接到与门Y2的输入端,使与门Y2输出为0,这样使开关管V3截止;从非门F1输出的另一路与开关管V2的栅极相连,其低电平信号也使V2截止。
同样,当电动机要求反转时,MMCSD1_D0给出低电平信号,经过2个与门和1个非门组成的逻辑电路后,使开关管V3受PWM信号控制,V2导通,V1、V4全部截止。
图4.2电机控制电路图
在ICETEK-OMAPL138-A套件的Linux核里集成了ICETEK-CTRV6.2的驱动,驱动中给CTR上的直流电机配置了Linux2.6下驱动属性接口,通作属性文件可实现对电机的起动、占空比和转向的控制。
4.3键盘控制
在ICETEK-OMAPL138-A套件的Linux核里集成了ICETEK-CTRV6.2的驱动,驱动中将CTR上的keypad做为一个标准的keypad进行挂载,并将按键值映射成了标准的1到9的按键值,这样在Linux下对这个keypad的操作就可以用通用的Linux控制和读写函数来完成。
本实验也是基于QT下对1-9的按键响应的封装完成的。
图4.3键盘连接示意图
4.4蜂鸣器控制
在ICETEK-OMAPL138-A套件的Linux核里集成了ICETEK-CTRV6.2的驱动,驱动中将CTR上的蜂鸣器做为一个标准的拨声器进行注册挂载,这样在Linux下对这个蜂鸣器的操作就可以用通用的Linux控制和读写函数来完成。
图4.4蜂鸣器连接示意图
4.5LED控制
CTR上的发光二极管显示阵列的显示是由扩展端口控制,由扩展在EMIFA的地址空间接口的两个寄存器提供具体控制。
在ICETEK-OMAPL138-A套件的Linux核里集成了ICETEK-CTRV6.2的驱动,驱动中将CTR上的发光二极管做为一个标准的led进行挂载,这样在Linux下对这些led的操作就可以用通用的Linux控制和读写函数来完成。
五软件设计方案
本次综合设计主要涉及到计时模块、液晶显示模块、键盘模块、直流电机控制模块、LED模块和蜂鸣器模块。
在设计的过程中需要将各个模块分别设计,然后整合到一起再进行调试与运行。
主要分为三个方面:
1、时钟显示与调时的实现,2、风扇定时开关的实现,3、风扇档位控制的实现。
具体功能描述,显示当前的时间并对时间的小时分钟进行调整;并可以对风扇开关定时时间进行设置,当电机在定时时间以前是关闭状态时,到达设定时间电机以最低档转动,当电机在定时时间以前是开启状态,到达设定时间电机停止转动;并且在电机处于转动状态时可以对电机档位进行调节;同时有整点报时功能与led灯的随秒循环闪烁功能。
5.1计时模块
实验中各个模块的工作都是基于计时模块来运行,在计时模块过对定时器周期的设置,并以定时器周期为基础,控制其他各个模块的运行。
实验中设置定时器周期为1s,并利用定时器实现时间的秒数增加,利用时间的进位关系实现分钟和时钟数的增加。
分别定义了秒钟增加函数secadd()、分钟增加函数minadd()、时钟增加函数houradd()和整合函数addOneSecond()。
本实验程序利用QTimer设置了一个时间周期为1s的定时器,每1s产生一个timeout()信号,将这个信号连接到相应的槽中,调用drawgraph()函数,在程序中定义了addOneSecond()子函数,在drawgraph()中调用addOneSecond()子函数实现时间的增加。
另外定义了secadd()子函数实现秒钟加1,当设置的秒钟加到60s时调用minadd()子函数实现分钟数加1,同理通过houradd()实现小时数加1。
具体的子程序见附录中的程序。
图5.1计时流程图
5.2液晶显示模块
液晶显示模块显示主要显示开机画面、时间的时钟、分钟和秒钟、电机开关状态和电机档位的显示。
在液晶显示中主要通过调用液晶屏显示实验中中画线函数CTR_lcd,实现数字1-9的显示及电机的开关状态ON和OFF显示。
定义函数drawnumber(intnum,intposition)和drawmininum(intmininum,intmposition)通过输入数字参数来调用ctr_lcd.cpp中画线子函数LCDDrawLine(unsignedintx0,unsignedinty0,unsignedintx1,unsignedinty1,unsignedcharcolor),实现数字显示。
图5.2.1开机画面128*64.bmp
图5.2.2二进制文件生成过程
5.3键盘模块
键盘模块主要实现电机风扇的开关控制、档位控制和计时时间和定时时间的设置。
各按键功能定义如下表:
按键
功能
1
直流电机的启动/停止
2
挡位循环增加
3
时间清零
4
小时十位加1
5
小时个位加1
6
分钟十位加1
7
分钟个位加1
8
定时时钟个位加1
9
定时时钟十位加1
在具体程序过对函数keyPressEvent(QKeyEvent*e)中各个按键功能的定义实现各个参数的设置。
在上述按键功能中,当设置定时时间时需要使液晶屏转换到定时时间节目并显示设置的定时时间,此处利用sleep
(1)函数挂起1s,使前面调用的显示定时时间的程序能够在液晶屏上显示1s的时间,并通过addOneSecond()补偿挂起的1s时间,使时间能够准确计时。
5.4直流电机控制模块
直流电机模块主要是有两个功能,一个是对电机的运行与否进行控制,一个是对电机的转速档位进行控制,将设置的档位转化为实际的转速输入到电机中,并使电机运行。
在程序中定义了dcmotorspeed(intdangweis)函数,其输入参数为设置的档位dangweis,首先根据输入的档位计算出实际的转速,设置每档转速增加10,一档转速为10,在dcmotorspeed(intdangweis)函数通过对属性文件的操作可以实现电机转速的输入和点击启动的控制。
由于电机的开关状态只需要改变属性文件的参数即可,在实现中直接利用参数motor_switch(开关状态)控制即可。
图5.4挡位控制流程图
5.5LED模块
LED模块实现顺时针每一秒钟亮一个LED,当12个LED全亮后再顺时针依次熄灭,并不断循环。
由于在驱动中将CTR上的发光二极管作为一个标准的LED进行挂载,因此定义了一个loop_light函数实现上述功能,并在函数过对通用的Linux读写函数来控制每个灯的开关。
5.6蜂鸣器模块
蜂鸣器模块主要是在整点时候对通过的Linux控制和读写函数来完成,在具体程序设计中有,通过设置频率,输入频率到蜂鸣器,并使能蜂鸣器实现蜂鸣器报时。
六调试与结果
6.1程序编译与安装
连接好实验箱上的各部件,用实验箱配的交叉连串口线连实验箱开发板的J13到PC机的COM1,用实验箱配的网线连ICETEK-OMAPL138-KBA的J5到PC机的网口,拨动开发板的拨码开关U15的状态拨为1000,PC机起动超级终端,PC机起动虚拟机Ubuntu。
实验设备上电起动,拨动实验箱左上角的总开关,到“开”的状态,给实验箱上电启动。
超级终端登录,超级终端出现3,2,1,倒计数时按回车暂停自动起动,输入相应命令进行开发板相关参数的设置。
虚拟机起动控制台,通过cd命令进入工程所有目录,通过make命令进行程序的安装与调试,通过网络文件系统nfs,程序会被安装到/opt/nfs/home/root/ctr目录下。
在开发主机的Windows系统中启动超级终端【Davinci】;
接通ICETEK-OMAPL138-A板电源,按回车键暂停linux的起动;
输入setenvbootcmd'nandread.e0xc07000000x2000000x400000;bootm'
输入setenvbootargs'console=ttyS2,115200n8noinitrdrwip=192.168.1.3root=/dev/nfsnfsroot=192.168.1.103:
/opt/nfs,nolockmem=32M0xc0000000mem=64M0xc4000000',
输入boot,观察【Davinci】中的输出的起动信息。
输入root登录;
输入cd/进入根目录输入cd/进入根目录;
输入ls列出根目录文件,列出的即为/opt/nfs目录下的;
6.2实验结果
在超级终端输入cdctr进行可执行程序所在目录,然后输入./lcd运行。
图6.2.1一档运行界面
电机档位信息在LCD屏幕左下角显示。
按2键进行风扇档位切换,即转速的调整。
档位分为4档,电机初始为N1档,2键每按下一次档位升一。
从N1到N4循环往复。
图6.2.2二档显示
图6.2.3三档显示
图6.2.4四档显示
图6.2.5电机停止状态显示
按键4、5、6、7分别设置时钟小时的十位个位,以及时钟分钟的十位个位。
效果如下图6.2.6。
图6.2.6设置时间后显示
按键8设置风扇定时小时的个位和十位,9键设置风扇定时分钟的十位。
效果如下图6.2.7。
图6.2.7设置定时时间显示
按键3设计为风扇定时设置各位归零。
效果如下
图6.2.8定时时间复位显示
LED装饰灯效果如图所示
图6.2.9LED装饰灯效果图
七个人工作自我评估
7.1个人工作报告
本次嵌入式课程综合设计实验,我们主要做了一个直流电机的控制系统,并扩展了相关功能,用于模拟风扇的控制。
在此次设计过程中我主要承担了LCD开机画面、电机开关状态的显示;装饰风扇的LED灯以及键盘的功能设计,如调时、调挡位、开关直流电机,并主要撰写课程设计报告和答辩演示。
在设计的过程中自己遇到了很多困难。
比如在初次实验的时候对超级终端操作不够熟悉,超级终端启动操作进行步骤不对,致使虚拟机不能连接开发板,经过多次动手操作逐渐熟悉了整个流程;开机画面显示需要显示单色位图,但是由于LCD屏不能直接显示位图,需要对位图转换为二进制文件,自己通过上网学习最终得以解决:
先用字模提取软件进行图片设计,生成128*64.bmp的图片,再通过PCtoLCD2002将图片转换成.txt文件,最后通过Txt2Bin将.txt文件转化成.bin文件,通过程序直接调用即可。
最终通过查阅各种资料找到了各个问题的相应解决办法,问题也得以解决。
此外自己也发现了程序中程序语句不够完美的地方,并对其进行了优化。
总之,通过此次综合设计我学到了如何团结合作,提高了自己独立解决问题的能力,并对Qt编程有了更多了解。
有时候花上一整天去阅读理解程序的逻辑设计及功能的实现方法,学到了很多程序设计的技巧,提高了阅读代码的能力,也发现了其中的乐趣。
而且我认为更重要的是我知道了如何高效的搜索信息,找到自己需要的知识,并最终完成了此次实验。
7.2个人工作报告
本次嵌入式课程综合设计实验,我们组主要做了一个智能风扇系统,风扇叶片又直流电机表示。
LCD显示屏主要显示了电机运行的时间,并可以手动调节。
在此次设计中,我主要设计了LCD时间显示的逻辑功能设计,还有LCD数字显示的实现,比如0-9这九个数字是如何在LCD上显示的,而且在128*64的LCD显示屏上位置如何分布。
逻辑的设计就是分钟和小时的进位设置,以及如何设置每小时时会调动蜂鸣器发声一次,在23时59分时会进位变成00:
00.
在设计的过程中遇到了很多的问题。
最初的肯定就是对设备不熟悉,使电脑虚拟机和开发板不能正确的连接。
在经过不断地尝试后,慢慢熟悉的操作过程,并开始设计系统。
接下来面对的问题就是,LCD显示屏显示时间是如何显示的问题。
最初想到了图片的调用实现,画出图片后然后再使用jmshow函数来调用图片。
但是这总方法太过于繁琐,不适合本系统。
最终还是选择了通过调用直线画图的方法来画出所需要的数字,然后再确定各个位置来进行调用。
还有一个难点就是调用后放置的位置,这个我通过资料的查阅,进行基于不同位置的调用,可以顺利解决这个问题。
最后,我通过此次综合设计我学到了QT编程的使用和团队的合作,提高了自己独立解决问题的能力通过阅读理解程序的逻辑设计及功能的实现方法,学到了很多程序设计的技巧,提高了阅读代码的能力。
此次嵌入式课程设计提高了我们编程方面的能力,锻炼我们的专业能力。
7.3个人工作报告
在本次嵌入式系统软硬件设计实验中,我们组通过做了一个智能风扇项目了解了嵌入式系统ubuntu的使用方法以及基于OMAPL138的小项目开发。
我的个人工作主要是实现蜂鸣器整点报时,软件模块的程序流程图设计,程序的安装和执行。
在进行试验的过程中,我们遇到了很多困难。
首先我与小组其他两位成员讨论了嵌入式实验的设计,包括使用开发板上的哪些模块,各模块的可能实现的方法,如何使用qt,如何编写程序,在调试过程中又遇到了很多问题。
通过我们的团结讨论,基本上实现了设计的功能。
在最后的整合阶段,小组成员积极参与讨论并共同调试,最终完成了智能风扇的实验。
在设计中遇到的主要问题及解决方案:
1.由于之前没有接触过QT,C++程序设计能力也有待提高,所以在程序设计和编写过程中非常艰难。
通过查询QT的书和网络资源,逐渐了解了QT的作用。
请教了一些学长和同级的同学,提高了C++的程序设计能力。
2.在程序调试过程中也遇到了一些问题。
例如程序编译后安装错误,安装之后无法在开发板运行,超级终端上找不到该程序的安装目录。
后来在仔细阅读实验指导书以后发现了问题所在,经过多次试验,终于成功运行了程序。
通过本次试验,使我了解了嵌入式系统试验的开发设计流程。
首先要清楚要做的项目实现的功能,由功能分析需要的模块和各个模块之间的调用关系,设计流程图。
然后在嵌入式操作系统上编写,编译,安装,运行,调试程序。
最后完善设计,查找bug,解决问题。
加强程序语言的设计和编写能力,并且会修改错误程序。
即使实现了要求的功能,程序也可能有逻辑上的漏洞。
不仅仅要能够理解客户的需求,还有有强大的编程能力,这样才能把项目做得尽可能完美。
八程序附件
以下附件为源程序主要部分:
/*************************按键*************/
voidDialog:
:
keyPressEvent(QKeyEvent*e)
{switch(e->key())
{
caseQt:
:
Key_3:
n_minunits=0;
n_mintens=0;
n_hourunits=0;
n_hourtens=0;
lcd->clearBuffer();
drawnumber(n_hourtens,10);
drawnumber(n_hourunits,40);
drawnumber(10,64);
drawnumber(n_mintens,70);
drawnumber(n_minunits,100);
sleep
(1);
addOneSecond();
break;//定时初始化
caseQt:
:
Key_7:
if(minunits<9)
{
minunits++;
}
else
minunits=0;
break;//分钟个位加一
caseQt:
:
Key_6:
if(mintens<5)
{mintens++;}
else
mintens=0;
break;//分钟十位加一
caseQt:
:
Key_5:
if(hourtens<2)
{
if(hourunits<9)
{
hourunits++;
}
else
hourunits=0;
}
else
{
if(hourunits<3)
{
hourunits++;
}
else
hourunits=0;
}
break;//时针个位加1
caseQt:
:
Key_4:
if(hourunits<4)
{
if(hourtens<2)
{
hourtens++;
}
else
hourtens=0;
}
else
{
if(hourtens<1)
{
hourtens++;
}
else
hourtens=0;
}
break;//时针十位加1
caseQt:
:
Key_1:
motor_switch=!
motor_switch;
if(motor_switch)
{
system("echo1>/sys/devices/platform/davinci_ctr.2/dc_motor/enable");
dcmotorspeed(0);
}else{
system("echo0>/sys/devices/platform/davinci_ctr.2/dc_motor/enable");
dangwei=0;
}
break;
caseQt:
:
Key_2:
if(motor_switch)
{
if(dangwei<4)
{
dangwei++;
}
else
{
dangwei=0;
}
dcmotorspeed(dangwei);
}
break;
caseQt:
:
Key_9:
if(n_mintens<5)
{
n_mintens++;
}
else
n_mintens=0;
lcd->clearBuffer();
drawnumber(n_hourtens,10);
drawnumber(n_hourunits,40);
drawnumber(10,64)