单片机控制系统课程设计03V电压测量表.docx
《单片机控制系统课程设计03V电压测量表.docx》由会员分享,可在线阅读,更多相关《单片机控制系统课程设计03V电压测量表.docx(14页珍藏版)》请在冰点文库上搜索。
单片机控制系统课程设计03V电压测量表
目录
第1章概述1
1.1本设计研究的背景及意义1
1.2本课题研究的主要内容1
1.3各部分元件介绍1
第2章硬件设计3
2.1设计的方案3
2.2基本原理3
第三章软件设计5
3.1程序的主程序流程图5
3.2实验步骤5
第4章调试结果及分析7
心得与体会8
参考文献9
附录10
第1章概述
1.1本设计研究的背景及意义
在广泛的自动控制领域中,需要有类似微型计算机功能的支持,但常常又不能把微型计算机安装在设备里面。
因此,微型控制器的一个重要分支(单片机)应运而生。
SPCE061A单片机的CPU内核是一个通用核结构,除此之外的其他功能模块均为可选结构,借助这种通用结构附加可选结构的积木式的构成,便可形成各种不同系统派生产品,以适应不同的应用场合。
本次课题所选用的就为LCD显示模组模块。
LCD就是指数码相机的液晶显示屏(LCD,全称为LiquidCrystalDisplay),LCD的特点包括低压微功耗,平板型结构,被动显示型,显示信息量大,易于彩色化,无电磁辐射,长寿命等。
1.2本课题研究的主要内容
本次设计要求完成基于单片机的电压测量系统的设计。
系统包括数据采集A/D转换模块,单片机控制模块和驱动显示模块。
主程序利用C语言编写,中断服务程序利用汇编语言编写,实现一个模拟电压表的功能,要求电压表能够测量电压值,在液晶显示器上显示并播报测量电压值。
在开机运行后,显示一个图片MM.bmp,显示并播放当前电位所在位置的电压;变化R22电位器,显示并播报R22电位器变化后的电压,即只要R22电位器改变,系统就能自动测量出R22电位器的电压,并把测量的到的电压值播报并显示出来。
1.3各部分元件介绍
SPCE061A提供了位控制结构的I/O端口,每一位都可以被单独定义用于输入或输出数据。
通常,对某一位的设定包括以下3个基本项:
数据向量Data、属性向量Attribution和方向控制向量Direction。
3个端口内每个对应的位组合在一起,形成一个控制字,用来定义相应I/O口位的输入输出状态和方式。
SPCE061A有32个可编程I/O端口,分为两组:
IOA0~15口和IOB0~15口,其中每一个端口都可以被单独设置为输入或者输出口。
SPLC501液晶显示模组采用的驱动控制芯片为凌阳科技的SPLC501A芯片,SPLC501A为液晶显示控制驱动器,SPLC501A单芯片液晶驱动,可以直接与其他微控制器接口总线相连。
微控制器可以将显示数据通过8位数据总线或者串行接口写到SPLC501A的显存中。
SACM_S480语音播放也有自动和手动两种方式,无论利用自动方式还是手动方式进行播放,都要通过语音播放初始化,即初始化为自动方式或者手动方式,取数据,填充语音队列,译码播放的过程。
在自动方式里,取语音数据,填充语音队列,对语音资源进行解码,以及输出队列的过程只需通过SACM_S480_ServiceLoop()一条语音就可以实现。
第2章硬件设计
2.1设计的方案
硬件连接图如图2-1。
IOA8~IOA15连接SPLC501液晶显示模块的D0~D7,IOB4连接AO,IOB5连接RWP,IOB6连接EP,RE连接/RES,IOB9连接/CS,VR、C86和PS跳线都与V3短接,把SPLC501液晶显示模组的时序选择为6800时序,即把JP6中所有左右两排的引针用跳线短接;两路音频输出J8和J13中靠左边的两个引针用跳线短接;IOA0连接R22电位器,即用排线把J26的第0号引针和J17(双0~3V的直流电平输入电路其中之一)中任一引针连接起来。
本实验中,通过SPCE061A内部ADC采集数据,如图2-1。
实验箱上V3为3.3V,当滑动头变化时,IOA0口输入的电压就随着变化;当已经通过[P_ADC_MUX_Ctrl]启动转换,通过[P_ADC_MUX_Ctrl]设置从LINE_IN1输入时,因为LINE_IN1也就是IOA0,所以IOA0口输入的电压变化时,就会送入A/D转换器变化的值,A/D转换器采集转换;通过读取[P_ADC_MUX_Data]转换得到数据,并把这些数据计算成电压值,计算出电压值的个位、小数点后第一位、小数点后第二位、小数点后第三位、小数点后第四位。
图2-1硬件连接图
2.2基本原理
本课题用到的实验箱硬件模块为:
SPCE061A核心及周边电路模块(包含32个I/O口),LCD显示模组模块,双0~3.3V直流电平输入电路模块,两路音频输出电路模块。
图2-20~3.3V直流电平输入电路
图2-3硬件原理图
第3章软件设计
3.1程序的主程序流程图
主程序流程图如图3-1,初始化LCD后,显示开机图片MM;进入电压测量循环:
启动转换,采集20个转换数据并取平均值,主要是为了减少误差;计算电压值;如果和上次电压值之差小于±0.1V,则电压没有变化,返回继续采集数据;如果和上次电压值之差大于±0.1V,表示有电压变化,计算电压各位(包括个位到小数点后四位)的数;清屏,显示图片MM;播报并显示电压值。
图3-1程序流程图
3.2实验步骤
1.新建一个工程ex10_VoltageMeasureFrom0To3,新建一个C语言程序main.c。
(根据编程需要,读者可自行新建其他文件)。
2.拷贝支持sacmv26e.lib的汇编语言文件hardware.asm和头文件hardware.h、hardware.inc以及头文件SPCE061A.h和SPCE061A.inc到ex10_VoltageMeasureFrom0To3工程文件夹。
3.拷贝语音播放库sacmv26e.lib和头文件s480.h、s480.inc到ex10_VoltageMeasureFrom0To3工程文件夹。
4.拷贝语音资源到当前工程的文件夹中,并将语音资源加载到工程中;语音资源可在IDE的安装路径\SPCE061A\example\IntExa\ex10_VoltageMeasureFrom0To3\voice文件夹中找到。
5.拷贝SPLC501液晶显示DataOSforLCD.asm、SPLC501Driver_IO.asm、SPLC501Driver_IO.inc、SPLC501User.c和SPLC501User.h五个LCD驱动程序到ex10_VoltageMeasureFrom0To3工程文件夹。
6.在IDE集成开发环境的Project?
?
Setting?
?
link中链接sacmv26e.lib库到工程中。
7.添加hardware.asm、DataOSforLCD.asm、SPLC501Driver_IO.asm和SPLC501User.c到工程文件的“SourceFiles”,添加s480.h、s480.inc、hardware.h、hardware.inc、SPLC501Driver_IO.inc、SPLC501User.h六个头文件到“HeadFiles”。
8.按照程序流程图编写程序。
9.RebuildAll。
10.按照硬件连接图连接硬件。
注意把J17的任一引脚和J26中的第0号引脚连接,把JP3和JP7的所有跳线全部拔掉,以免对I/O口的数据造成影响。
11.下载程序,运行。
12.调节R22电位器(双0~3.3V直流电平输入电路模块中下面一个电位器),观察LCD显示数据和实验箱播报的数据,分析是不是和实验要求相统一。
第4章调试结果及分析
实现一个模拟电压表的功能,要求电压表能够测量电压值,在液晶显示器上显示并播报测量电压值.开机(运行)后,显示一个图片,显示并播放当前电位器所在位置的电压;变化R22电位器,显示并播报R22电位器变化后的电压;即只要R22电位器改变,系统就能自动测量出R22电位器的电压,并把测量得到的电压值播报并显示出来。
图4-1实验结果
心得与体会
通过这次课程设计使我更进一步掌握了SPCE061A内部ADC的使用方法,同时熟悉了凌阳单片机试验箱LCD显示模块的使用方法,熟悉了SACM-S480格式的语音播放方式。
通过对单片机资料的查阅和应用,更进一步增加了对单片机知识的理解和运用能力。
本文列出了系统具体的硬件原理图,硬件连接方案,软件流程图和具体汇编语言程序设计与调试等方面。
在这次课程设计的过程中学会了凌阳十六位单片机的基本使用,感受到了熟练掌握它对于自动化专业的同学的重要性。
总体来说这次的科研实践很成功,达到了预想的目的,学到了知识,提高了能力,完成了任务。
在此感谢指导老师的悉心教导,改正了很多不曾发现的问题,为即将的毕业设计打下了基础。
参考文献
[1]杜刚.16位单片机原理及应用学习与实验指导[M].北京:
中国电力出版社,2008.12.
[2]罗亚飞.凌阳16位单片机应用基础[M].北京:
北京航空航天大学出版社,2003.12.
[3]李晓白.凌阳16位单片机C语言开发[M].北京:
北京航空航天大学出版社,2006.7.
[4]李朝青.单片机原理及接口技术(修订版)[M].北京:
北京航空航天大学出版社,1998.5.
附录总程序
//=====================================================================================================
//工程名称:
0~3V电压测量表
//功能描述:
//0~3V电压测量表
//采集电压经LCD显示出来,并语音提示电压值
//涉及的库:
CMacro1016.lib
//SacmV26e.lib
//组成文件:
main.c/SPLC501User.c
//ISR.asm/hardware.asm/SPLC501Driver_IO.asm/DataOSforLCD.asm
//480.h/480.inc/hardware.h/hardware.inc
//SPLC501Driver_IO.inc/SPLC501User.h/SPCE061A.h/SPCE061A.inc
//硬件连接:
选择IOA0口为AD输入
//LCD数据IOA8-IOA15,AOP:
IOB4,R/W:
IOB5,EP:
IOB6,片选由IOB9提供
//注意:
拔掉usb的数据线
//维护记录:
2005-10-17
//====================================================================================================
//========================================================================
//文件名称:
main.c
//功能描述:
采集电压经LCD显示出来,并语音提示电压值
//维护记录:
2005-10-17v1.0
//========================================================================
#include"VolMeasure.h"//定义了一个结构体
#include"MM.h"
#include"SPLC501User.h"
#include"SPCE061A.h"
unsignedintAD_Read(void);
voidPlayS480(intResult);
//========================================================================
//语法格式:
intmain(void)
//实现功能:
主程序
//参数:
无
//返回值:
int无意义
//========================================================================
intmain(void)
{
inti=0,j=0,k=0,m;
floatfVolVal;
intuiVolFlag=0,uiVolFlagOne=0;
longintuiVolFlagHow=0;
unsignedintuiData;
longintliDataVol;
structST_VolValudeVolValude;//0-3。
3V电压表服务结构
VolValude.VolTureValudeB=7;//初始化电压采集值
LCD501_Init(0x00);//初始化LCD
LCD501_SetPaintMode(4);//设置LCD显示图象模式为取反叠加模式
LCD501_ClrScreen(0);//清屏
LCD501_Bitmap(0,0,(unsignedint*)encoding_00);//显示开机图片
fVolVal=0.0;
while
(1)//主循环
{
*P_DAC_Ctrl=0;
*P_ADC_Ctrl=C_ADCE+C_MIC_DIS+C_AGCN+C_DAC_OUT3mA+C_VEXTREF_DIS+C_V2VREFB_DIS;
uiData=*P_ADC_LINEIN_Data;
while((*P_ADC_MUX_Ctrl&0x8000)!
=0x8000);
*P_ADC_MUX_Ctrl=C_ADC_CH1;
//播放语音后会改变P_ADC_Ctrl的设置
uiData=AD_Read();//丢掉第一个数
j=0;
for(i=0;i<20;i++)//采20个数据到VolValude.VolValudeA[j]
{
*P_Watchdog_Clear=C_WDTCLR;
uiData=AD_Read();
VolValude.VolValudeA[j]=uiData;
j++;
}
uiVolFlagOne=0xff;
uiVolFlag=0;
j=0;
uiData=0;
liDataVol=0;
for(i=0;i<20;i++)
{
liDataVol=liDataVol+VolValude.VolValudeA[j];
j++;
}
uiData=liDataVol/20;//取20个数据的平均值,以减少误差
VolValude.VolTureValudeA=(float)uiData*3.3/0xffc0;
//得到电压值
fVolVal=VolValude.VolTureValudeB-VolValude.VolTureValudeA;
if(fVolVal<0.1&&fVolVal>(-0.1))//和前一次数据比较,有变化更新显示和语音提示
{
if(k==0)
{
k++;
}
elsek++;
}
else
{
k=0;//取得要在LCD上显示的数据,存入VolValude.LCD[j]
VolValude.VolTureValudeB=VolValude.VolTureValudeA;
uiVolFlagHow=VolValude.VolTureValudeA*10000;
VolValude.LCD[0]=uiVolFlagHow/10000%10;
VolValude.LCD[1]=uiVolFlagHow/1000%10;
VolValude.LCD[2]=uiVolFlagHow/100%10;
VolValude.LCD[3]=uiVolFlagHow/10%10;
VolValude.LCD[4]=uiVolFlagHow%10;
//LCD数据更新
m=LCD501_GetPaintMode();//获取当前图象叠加模式
LCD501_SetPaintMode
(2);//设置为清除模式
LCD501_Rectangle(68,40,127,56,PAINT_SOLID);//清除数据显示区
LCD501_SetPaintMode(m);//图象叠加模式恢复
//////////////////////////////////////////////////显示AD转换数值以及语音播报结果
LCD501_PutChar(68,40,('0'+VolValude.LCD[0]));
LCD501_PutChar(76,40,'.');
PlayS480(VolValude.LCD[0]);
PlayS480(10);
LCD501_PutChar(78,40,('0'+VolValude.LCD[1]));
PlayS480(VolValude.LCD[1]);
LCD501_PutChar(88,40,('0'+VolValude.LCD[2]));
PlayS480(VolValude.LCD[2]);
LCD501_PutChar(98,40,('0'+VolValude.LCD[3]));
PlayS480(VolValude.LCD[3]);
LCD501_PutChar(108,40,('0'+VolValude.LCD[4]));
PlayS480(VolValude.LCD[4]);
LCD501_PutChar(116,40,'V');
}
}
}
//=============================================================
//语法格式:
voidAD();
//实现功能:
数据采集
//参数:
无
//返回值:
bData-采得的数据
//=============================================================
unsignedintAD_Read(void)
{
unsignedintbData;
while(!
(*P_ADC_MUX_Ctrl&0x8000));//等待采样完成
bData=*P_ADC_LINEIN_Data;
bData=bData&0xffc0;
returnbData;
}
//=============================================================
//语法格式:
voidPlayS480(intResult);
//实现功能:
语音播放
//参数:
intResult-要播放的段
//返回值:
无
//=============================================================
voidPlayS480(intResult)
{
SACM_S480_Initial
(1);//播放初始化,来自于SacmV26e.lib
SACM_S480_InitQueue();
SACM_S480_Play(Result,3,3);
while((SACM_S480_Status()&0x0001)!
=0)//填充队列播放,来自于SacmV26e.lib
{
SACM_S480_ServiceLoop();
*P_Watchdog_Clear=C_WDTCLR;
}
SACM_S480_Stop();//停止播放,来自于SacmV26e.lib
__asm("FIQOFF");
}