资源描述
电子时钟系统设计
24
2020年4月19日
文档仅供参考,不当之处,请联系改正。
《嵌入式系统》课程设计说明书
电子时钟系统
院 部:
学生姓名:
指导教师: 职称
专 业:
班 级:
学 号:
湖南工学院嵌入式系统课程设计课题任务书
指导教师
学生姓名
课题名称
电子时钟系统设计
内容及任务
一、目标
在GEC210开发板上设计一个基于QT的电子时钟系统来显示当前的系统时间。
二、任务
根据控制要求,明确设计任务,拟定设计方案与进度计划,运用所学的理论知识,进行电子时钟系统原理设计、硬件系统设计、软件系统设计、创新设计,提高理论知识工程应用能力、系统调试能力、分析问题与解决问题的能力。主要内容包括:
1. 嵌入式交叉开发环境搭建。
2. Linux操作系统的移植。
3. 根据需求确定外围模块设计并完成相应驱动开发。
4. 应用程序原理及框架设计。
5. Linux下应用程序编写及移植。
6. 系统总体功能调试。
7. 编写设计说明书。
三、要求
1.本系统显示结果示例如下:
2.显示的时间为开发板当前的系统时间,显示的结果随着系统时间变化而变化。
主要参考资料
[1]马忠梅,ARM & Linux嵌入式系统教程(第3版)[M]。北京:北京航空航天大学出版社,
[2]曹忠明,程姚根。从实践中学嵌入式Linux操作系统[M]。北京:电子工业出版社,
[3]宋宝华,Linux设备驱动开发详解(第二版)[M]。北京:人民邮电出版社, 。
[4]韦东山,嵌入式Linux应用开发完全手册[M]。北京:人民邮电出版社,
[5] 陆文周,Qt5开发及实例[M]。北京:电子工业出版社,
[6] Stephen Prata,C Primer Plus[M]。北京:人民邮电出版社,
教研室
意见
教研室主任:(签字)
年 月 日
摘 要
嵌入式操作系统是一种支持嵌入式系统应用的操作系统软件,它是嵌入式系统 ( 包括硬、软件系统 ) 极为重要的组成部分,一般包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通信协议、图形界面、标准化浏览器等 Browser 。嵌入式操作系统具有通用操作系统的基本特点,如能够有效管理越来越复杂的系统资源;能够把硬件虚拟化,使得开发人员从繁忙的驱动程序移植和维护中解脱出来;能够提供库函数、驱动程序、工具集以及应用程序 。与通用操作系统相比较,嵌入式操作系统在系统实时高效性、硬件的相关依赖性、软件固态化以及应用的专用性等方面具有较为突出的特点。嵌入式技术已成为信息产业中发展最快、应用最广的计算机技术之一,并被广泛应用于网络通信、消费电子、医疗电子、工业控制和交通系统等领域。
本次设计采用QT程序开发框架开发的模拟时钟程序,使用Linux系统到嵌入式终端移植和交叉编译环境搭建,最终成功实现了在嵌入式终端的运行。
关键词:嵌入式系统;QT;模拟时钟;Linux系统
目 录
1绪论 1
1.1 设计背景 2
1.2 设计目的和意义 2
2 嵌入式Linux系统 2
2.1 嵌入式Linux概念 2
2.2 嵌入式Linux组成 2
3 Qt工具 3
3.1 Qt简介 3
3.2 Qt优点 3
4 模拟时钟的设计 4
4.1 代码的编写 4
4.2 代码的调试与运行 4
5 模拟时钟到开发板的下载 6
5.1 交叉编译环境的构建 7
5.2 模拟时钟到开发板的下载运行 7
结论 10
参考文献 11
致 谢 12
附录 13
1绪论
嵌入式Linux操作系统在广泛和深入的应用于各个领域,应用的技术也越来越复杂。而随着城市信息化和行业信息化的持续深入,嵌入式技术已成为信息产业中发展最快、应用最广的计算机技术之一,并被广泛应用于网络通信、消费电子、医疗电子、工业控制和交通系统等领域。嵌入式Linux开始采用较为复杂的图形用户界面。QT以其强大的功能,良好的可移植性成为一种被广泛使用的GUI系统。于是嵌入式操作系统及其相应图形用户界面的不断发展,嵌入式软件的开发显得越来越重要。本次设计模拟时钟能够以简洁的外观为用户提供时间信息成为了系统中的重要组成部分,在基于QT的嵌入式系统中模拟时钟具有深刻的实用价值。
1.1 设计背景
源代码开放的Linux搭建的嵌入式操作系统由于其强大的网络功能和低成本,近年来得到了越来越多的应用。其能够提供全功能的桌面计算,定制非常方便而且支持大多数嵌入式系统上使用的芯片。在嵌入式Linux操作系统上使用一个功能完备的轻量级、高性能、高可靠、可配置的GUI系统成为可行的解决方案。全过程自动化产品制造、大范围电子商务活动、高度协同科学实验以及现在化家庭起居,为嵌入式产品造就了崭新而巨大的商机。日趋增长的功能密度、灵活的网络链接、轻便的移动应用和多媒体的信息处理对嵌入式系统软件技术提出了新的挑战。
1.2 设计目的和意义
随着近年来计算机技术的迅速发展,当新硬件、新技术出现时,计算机的体系结构、指令系统和操作系统都可能发生相应的改变,这势必会导致一部风应用在新环境下无法正常运行。如果舍弃原有软件重新开发,将会耗费大量的人力和财力,而浪费了许多成熟的软件成果。而QT在源代码级上实现了跨平台特性,极大地支持了跨平台通用软件的开发。QT能够用同一个源程序在不同平台上编译链接,生成目标代码,并取得相同的运行效果,充分实现了程序的跨平台运行。这种基于源代码的跨平台特性不但解决了性能的问题,而且能够发挥各个平台的优势,充分利用每个平台自身的特点;而且即能够在新环境下实现原有软件的功能和特点,减少开发费用,还能够改进原有软件的不足,增加新的需求,从而提高软件的质量,延长软件生命期。模拟时钟需要编写代码来实现它的功能,然后对代码进行编译运行,检查是否达到了预期的效果。
2 嵌入式Linux系统
2.1 嵌入式Linux简介
嵌入式Linux是将标准Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。它以应用为中心,以计算机技术为基础,软件、硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等有严格要求的专用计算机系统。Linux从1991年问世到现在,短短的十几年时间已经发展成为功能强大、设计完善的操作系统之一,不但能够与各种传统的商业操作系统分庭抗争,在新兴的嵌入式操作系统领域内也获得了飞速发展。嵌入式系统的发展方向是与目标密切相关的嵌入性能、操控能力与控制的可靠性。嵌入式操作系统从它的产生到现在经历了几个阶段,全入市系统是以应用为中心的计算机技术为基础而且软硬件是可裁剪的适用于对功能、可靠性、成本、功耗等有严格要求的专用计算机系统嵌入式系统最典型的特点是与人们的日常生活紧密相关,任何一个普通人都可能拥有各种运用了嵌入式技术的电子产品。各种新型嵌入式设备在数量上已经远远超过了通用计算机。
2.2 嵌入式Linux的组成
一个最小的嵌入式系统基本组成为:一个用作引导的可用设施(工具);一个具备内存管理,进程管理和定时器服务的Linux微内核;一个初始进程;硬件的驱动程序;一个或几个应用进程以提供必要的应用功效。嵌入式Linux既继承了Internet上无限的开放源代码资源,又具有嵌入式操作系统的特性。
(1) 硬件层:硬件层包含嵌入式微处理器、存储器(SDRAM、ROM、Flash等)、通用设备接口和I/O接口(A/D、D/A、I/O等)。在意嵌入式处理器基础上添加电源电路、时钟电路和存储电路就构成了一个嵌入式核心控制模块。其中操作系统和应用程序多都能够固化在ROM中。
(2) 中间层:硬件层与软件层之间为中间层,也称为硬件抽象层(Hardware Abstract Layer,HAL)或者板级支持包(Board Support Package,BSP),它半系统上层软件与底层硬件分离开来,使系统的底层驱动程序与硬件无关,上层软件开发人员无需关心底层硬件的具体情况,根据BSP层提供的接口即可进行开发。该层一般包含相关底层硬件的初始化、数据的输入/输出操作和硬件设备的配置功能。
(3) 系统软件层:系统软件层由实时多任务操作系统(Real-time Operation System,RTOS)、文件系统、图形用户接口(Graphic User Interface,GUI)、网络系统及通用组件模块组成。RTOS是嵌入式应用软件的基础和开发平台。
3 Qt工具
3.1 Qt简介
Qt是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架。它给应用程序开发者提供了一套功能齐全的进行艺术级的图形用户界面程序设计所需的功能。Qt很容易扩展,而且 允许真正地组件编程。基本上Qt和X Window上的GTK,Openwin,Motif等图形界面库和 Windows 平台上的ATL,CL,OWL,VMFC是非常类似的。QtCreator 主要是为了帮助新 Qt 用户更快速入门并运行项目,还可提高有经验的 Qt 开发人员的工作效率。Qt Creator 包括项目生成向导、高级的 C++ 代码编辑器、浏览文件及类的工具、集成了 Qt Designer、Qt Assistant、Qt Linguist、图形化的 GDB 调试前端,集成 qmake 构建工具等。
3.2 Qt优点
Qt的良好封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。Qt提供了一种称为signal/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单。Qt有丰富的API包括多达250个以上的C++类,还是提供基于模板的collections,serialization,file,I/Odevice,directory management,date/time类,还包括正则表示式的处理功能。支持2D/3D图形渲染、OpenGL、大量的文档开发、XML支持和实现本地界面与Web内容的无缝集成。
4 模拟时钟的设计
设计要求指针式的表盘为原型,而且圆周上有分布均匀的12个刻度,钟面上有长度不同的指针,即时针、分针、秒针,间隔一秒更新一次时间。显示的时间为开发板当前的系统时间,显示的结果随着系统时间变化而变化。
4.1 代码的编写
模拟时钟每一个模块的功能是在cpp文件中实现的,h文件是类、槽、函数、变量的定义,main主函数用来调用现实,头文件和主函数的代码如下:
myclock.h文件
#ifndef MYCLOCK_H
#define MYCLOCK_H
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QTime>
#include <QTimer>
#include <qmath.h>
namespace Ui {
class myclock;
}
class myclock : public QWidget
{Q_OBJECT
public:
explicit myclock(QWidget *parent = 0);
~myclock();
protected:
void paintEvent(QPaintEvent*);
private:
Ui::myclock *ui;
QTimer *timer;
int i;
};
#endif // MYCLOCK_H
main主函数:
main.cpp
#include "myclock.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
myclock w;
w.show();
return a.exec();
}
模拟时钟的走时为调用系统时间,用定时器每一秒更新一次draw函数,在表盘上显示为秒针跳动一格,由于始终与系统时间保持一致,因此完全能够作为直接的时间显示工具。实现的代码如下:
myclock::myclock(QWidget *parent) :
QWidget(parent),
ui(new Ui::myclock)
{
ui->setupUi(this);
this->resize(350,350);
timer = new QTimer(this);//定时器
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(1000);
}
myclock::~myclock()
{
delete ui;
}
时钟的指针绘制也是根据定义的坐标用画笔画出需要的指针形状,其中绘制指针的实现代码如下:
QPen hourpen;//时针的画笔
hourpen.setWidth(4);//设置画笔宽度
//hourpen.setColor(Qt::blue);//设置画笔颜色
mypainter.setPen(hourpen);
mypainter.save();//
mypainter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
mypainter.drawConvexPolygon(hourHand, 3);
//mypainter.drawLine(0,0,0,-80);
mypainter.restore();
QPen minutepen;//分针的画笔
minutepen.setWidth(3);
minutepen.setColor(Qt::yellow);//设置画笔颜色
mypainter.setPen(minutepen);
mypainter.save();
mypainter.rotate(6.0 * (time.minute() + time.second() / 60.0));
mypainter.drawConvexPolygon(minuteHand, 3);
//mypainter.drawLine(0,0,0,-100);
mypainter.restore();
QPen secondpen;//秒针的画笔
secondpen.setWidth(1);
secondpen.setColor(Qt::blue);//设置画笔颜色
4.2 代码的调试和运行
经过以上步骤代码编写已经完成,在Windows系统下的QT运行。经过调试发现没有发现错误和警告,就会出现如下的到模拟时钟的界面,如图1所示。
图1 模拟时钟界面
5 模拟时钟到开发板的移植
5.1 交叉编译环境的构建
在开发板上移植Linux系统之前,必须确保已经安装了USB驱动,并把开发版设置为NOR Flash启动。系统更新和安装完毕后设置为Nand Flash启动。然后对Nand Flash进行分区,安装bootloader,移植内核文件,移植文件系统。做完这些就能够进行交叉编译环境构建。在Linux平台下,要为开发板编译内核,图形界面Qtopia,bootloader,还有其它一些英勇程序,均需要交叉编译工具链。
(1)安装gcc编译工具用于arm平台程序的编译工具,arm-linux-gcc,arm-linux-g++等,
把程序源码包复制到用户目录下面解压
(2) 设置环境变量,
(3) 保存设置
最后在终端输入以下命令:arm-linux-gcc -v等待出现信息成功安装。
4.2 模拟时钟到开发板的下载与运行
交叉编译好的程序到开发板的下载用到串口,用串口线连接好开发板和电脑,串口使用COM3。接通电源,启动开发板,登录系统,在SecureCRT中点击连接。
图2 串口连接设置
进入后弹出一个对话框,在对话框中输入一下几条命令:
(1)pwd
(2)ls
(3)cd aaa
(4)ls
(5)source qtconf.sh
(6)./myclock
输入以上命令后能够在SecureCRT中看到如下信息:
图3 输入命令结果
输入以上几条命令后,开发板上也就出现了本次设计的模拟时钟界面。开发板上结果如图4所示。
图4 开发板显示结果
由图4能够看出,开发板上的时钟与系统时间一致,而且随系统时间的变化而变化,说明设计成功。
在下载运行时会遇到这些问题:调用驱动时要保证实际驱动名字与应用程序名字相同;经过串口显示的数据是乱码,原因是波特率设置的不正确,导致双方数据交互出现错误;开发板的系统上电后,不能重新启动,究其原因是内核、根目录系统或者bootloader没有正确的烧写,重新烧写后正常启动;程序下载到开发板上不能正确运行,提示缺少某个动态库,将缺少的库文件从Qt的安装包拷贝到lib目录下完成后可正常启动。
结 论
本次课程设计实现了一种基于Qt的模拟时钟的开发过程,实现了预期的功
能。编写好的模拟时钟代码在Linux系统、Windows系统下都能编译并运行成功,还讲交叉编译好的程序下载到开发板上运行,冲锋体现了Qt的跨平台特性。为了Windows系统下编写编译的Qt程序能够在嵌入式Linux环境里运行,需要在搭建交叉编译环境时,要配置环境变量,设计编译参数,任何一个依赖库的确实或编译参数的疏忽都可能导致交叉编译不成功。交叉编译好的Qt程序到开发板移植时,嵌入式Linux中要有Qt程序运行的环境,移植时往往缺少很多库文件导致不能运行,需要不断测试并在交叉编译环境中找到相应的库文件下载到开发板。
由于个人能力以及时间的限制,此次设计最终能实现了一些基本功能,可是还有很大的扩展性,比如时间设置等功能。希望在今后的学习中能够学到更多完善自己。
参考文献
[1]马忠梅,ARM & Linux嵌入式系统教程(第3版)[M]。北京:北京航空航天大学出版社,
[2]曹忠明,程姚根。从实践中学嵌入式Linux操作系统[M]。北京:电子工业出版社,
[3]宋宝华,Linux设备驱动开发详解(第二版)[M]。北京:人民邮电出版社, 。
[4]韦东山,嵌入式Linux应用开发完全手册[M]。北京:人民邮电出版社,
[5] 陆文周,Qt5开发及实例[M]。北京:电子工业出版社,
[6] Stephen Prata,C Primer Plus[M]。北京:人民邮电出版社,
致 谢
首先我要感谢我的老师在课程设计上给予我的指导,提供给我的支持和帮助,这是我能顺利完成这次报告的主要原因,更重要的是老师帮我解决了许多技术上的难题,让我能把系统做得更加完善。在此期间,我不但学到了许多新的知识,而且也开阔了视野,提高了自己的设计能力。其次,我要感谢帮助过我的同学,她们也为我解决了不少我不太明白的设计商的难题。最后再一次感谢所有在设计中曾经帮助过我的良师益友和同学这段时间以来,在老师的耐心指导下,我终于完成了本次的课程设计。
附录
程序清单
工程程序:
myclock.pro
#-------------------------------------------------
#
# Project created by QtCreator -11-21T04:30:07
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = myclock
TEMPLATE = app
SOURCES += main.cpp\
myclock.cpp
HEADERS += myclock.h
FORMS += myclock.ui
头文件程序:
myclock.h
#ifndef MYCLOCK_H
#define MYCLOCK_H
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QTime>
#include <QTimer>
#include <qmath.h>
namespace Ui {
class myclock;
}
class myclock : public QWidget
{Q_OBJECT
public:
explicit myclock(QWidget *parent = 0);
~myclock();
protected:
void paintEvent(QPaintEvent*);
private:
Ui::myclock *ui;
QTimer *timer;
int i;
};
#endif // MYCLOCK_H
源文件程序:
main.cpp
#include "myclock.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
myclock w;
w.show();
return a.exec();
}
myclock.cpp
#include "myclock.h"
#include "ui_myclock.h"
myclock::myclock(QWidget *parent) :
QWidget(parent),
ui(new Ui::myclock)
{
ui->setupUi(this);
this->resize(350,350);
timer = new QTimer(this);//定时器
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(1000);
}
myclock::~myclock()
{
delete ui;
}
void myclock::paintEvent(QPaintEvent *)
{
QTime time = QTime::currentTime();//获取系统时间
QPainter mypainter(this);//定义画家
mypainter.setRenderHint(QPainter::Antialiasing);//平滑设置
static const QPoint hourHand[3] = {
QPoint(4, 4),
QPoint(-4, 4),
QPoint(0, -80)
};//时针
static const QPoint minuteHand[3] = {
QPoint(4, 4),
QPoint(-4, 4),
QPoint(0, -100)
};//分针
static const QPoint secondHand[4] = {
QPoint(5, 5),
QPoint(0, 30),
QPoint(-5, 5),
QPoint(0,-120)
};//秒针
//mypainter.translate(this->width()/100,this->height()/100);//坐标平移
QPen pen;//定义圆画笔
pen.setWidth(5);//设置画笔宽度
pen.setColor(Qt::blue);//设置画笔颜色
mypainter.translate(170,170);//将(0,0)坐标平移到(170,170)的位置
mypainter.setPen(pen);
mypainter.drawEllipse(-150,-150,300,300);//画圆
QPen rul;//刻度的画笔
mypainter.setPen(rul);
mypainter.save();//保存原有状态
for (int i = 0; i < 60; ++i)
{
if(i%5 == 0)
{
mypainter.drawLine(150, 0, 135, 0);
}
mypainter.drawLine(150, 0, 145, 0);
mypainter.rotate(6.0);
}
mypainter.restore();//恢复坐标
QPen hourpen;//时针的画笔
hourpen.setWidth(4);//设置画笔宽度
//hourpen.setColor(Qt::blue);//设置画笔颜色
mypainter.setPen(hourpen);
mypainter.save();//
mypainter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
mypainter.drawConvexPolygon(hourHand, 3);
//mypainter.drawLine(0,0,0,-80);
mypainter.restore();
QPen minutepen;//分针的画笔
minutepen.setWidth(3);
minutepen.setColor(Qt::yellow);//设置画笔颜色
mypainter.setPen(minutepen);
mypainter.save();
mypainter.rotate(6.0 * (time.minute() + time.second() / 60.0));
mypainter.drawConvexPolygon(minuteHand, 3);
//mypainter.drawLine(0,0,0,-100);
mypainter.restore();
QPen secondpen;//秒针的画笔
secondpen.setWidth(1);
secondpen.setColor(Qt::blue);//设置画笔颜色
mypainter.setPen(secondpen);
mypainter.save();
mypainter.rotate( 6.0 * time.second());
mypainter.drawConvexPolygon(secondHand, 4);
//mypainter.drawLine(0,0,0,-120);
mypainter.restore();
//画数字
mypainter.save();//保存原有状态
for(int i = 1; i < 13; i++)
{
QString num = QString::number(i);
//mypainter.rotate(30.0);//旋转30度
//mypainter.drawText(0,-120,num);
mypainter.save();
mypainter.rotate(i*30.0);
mypainter.translate(0,-125);
mypainter.rotate(-i*30.0);
mypainter.drawText(-4,0,num);
mypainter.restore();
}
mypainter.restore();//恢复坐标
}
展开阅读全文