实验八 智能仪器文档格式.docx
《实验八 智能仪器文档格式.docx》由会员分享,可在线阅读,更多相关《实验八 智能仪器文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
该系统具体功能为,仪器上电后自动进入测控状态,显示器显示实时采样值,同时D1和D2实时切换报警状态。
若0#键按下,进入参数设置状态(测控转入后台运行),显示器显示工作参数L及其当前值;
若2#或3#键按下,可对当前参数值进行加10或减10计算并更新显示;
若按压1#键可以确认修改结果(下次再进入参数设置状态时可以以此结果作为新的当前值,否则修改后的参数值不被保存),并转入下一个参数H的设置过程(同理不再赘述)。
再次按压0#键或1#键均可退出参数设置状态,返回测控状态。
软件编程原理:
软件系统采用一个由多功能模块构成的程序,模块之间相互依赖,它们之间关系如图2所示。
控制
(control.c)
菜单
(menu.c)
按键检测
(keyboard.c)
A/D转换
(ad.c)
LED显示
(led.c)
串口输出
(serial.asm)
图2软件系统结构组成
程序由两个主要的功能模块组成一一控制模块和菜单模块,两个模块能够同时运行(指用户在进行菜单操作时,程序需还能实时采集数据并进行控制)而“控制”和“菜单”这两个主要模块都是建立在其他小模块的基础上的,比如控制模块建立在A/D转换和LED显示的基础上,菜单建立在按键检测和LED现实的基础上的,而按键检测又建立在串口输出的基础上。
表1列出了各个模块的主要函数。
表1各个模块的主要函数和功能
模块
主要函数和功能
控制模块
voidcontrol_thread(void);
菜单模块
voidmenu_thread(void);
A/D转换模块
charad(void);
//进行A/D转换,结果通过返回值输出
voidprint(charname,unsignedintvalue);
//输出名称和数值
voidserial(charbyte);
//将字节byte串口输出
unsignedcharget_key(void);
//检测并返回按下的键值
实验内容:
(1)熟悉单片机应用系统的设计要领;
(2)按图1中元器件及参数在ISIS中完成电路原理图的绘制;
(3)在uVision3中,按图2及表1建立7个程序文件;
(4)在ISIS中运行,实现一路电压信号输入和两路报警开关量输出控制功能。
软件编程:
该项目由7个程序文件组成,其中6个为C语言文件,一个为汇编语言文件(串口输出功能采用汇编语言与C51语言混合编程),程序如下:
(1)main.c文件
voidad_init();
voidcontrol_thread();
voidmenu_thread();
voidmain(){
ad_init();
while
(1){
menu_thread();
control_thread();
}}
(2)control.c文件
#include<
reg51.h>
sbitP16=P1^6;
sbitP17=P1^7;
unsignedcharad();
externunsignedcharparam_value[2];
externcharmenu_status;
voidcontrol_thread()
{
unsignedcharvalue=ad();
//A/D转换
if(value>
param_value[1]){//根据采样值控制LED灯
P16=0;
P17=1;
}
elseif(value<
=param_value[1]&
&
value>
=param_value[0]){
P17=0;
else{
P16=1;
if(menu_status==1){//如果菜单是关闭的,显示采集到的数值
print('
'
value);
(3)menu.c文件
#defineMENU_ON0
#defineMENU_OFF1
#defineMENU_NUM2
#defineMENU_MAX999
#defineMENU_MIN0
unsignedcharparam_value[]={100,150};
unsignedcharmenu_status=MENU_OFF;
char_menu_name[]={'
L'
'
H'
};
//参数名的符号
unsignedchar_menu_value[]={0,0};
//供显示用的参数数组
unsignedchar_menu_idx=0;
//参数序号
charget_key();
voidmenu_thread(void){
chari=0;
charkey=get_key();
if(menu_status==MENU_OFF){//当前菜单为关闭状态时
if(key==0){//若0#键已被按下
menu_status=MENU_ON;
//置当前菜单为打开状态
_menu_idx=0;
//设置参数序号0
for(i=0;
i<
MENU_NUM;
i++)
_menu_value[i]=param_value[i];
//将所有参数当前值取出,送入供显示的参数数组中
}}
else{//如果当前菜单为打开状态,则进行以下操作:
if(key==0){//若按键0#按下,则不保存键值,仅切换到下一个参数
if(++_menu_idx==MENU_NUM)//判断所有参数是否都循环到了
menu_status=MENU_OFF;
//若已循环完成,设置菜单关闭状态
elseif(key==1)//若按键1#按下,则保存键值,并切换到下一个参数
{param_value[_menu_idx]=_menu_value[_menu_idx];
if(++_menu_idx==MENU_NUM)
menu_status=MENU_OFF;
elseif(key==2){//若按键2#按下,则参数值加10
_menu_value[_menu_idx]+=10;
if(_menu_value[_menu_idx]>
MENU_MAX)
_menu_value[_menu_idx]=MENU_MAX;
elseif(key==3){//若按键3#按下,则参数值减10
_menu_value[_menu_idx]-=10;
if(_menu_value[_menu_idx]<
MENU_MIN)
_menu_value[_menu_idx]=MENU_MIN;
if(menu_status==MENU_ON)//若菜单状态为开时,显示参数值
print(_menu_name[_menu_idx],_menu_value[_menu_idx]);
}
(4)keyboard.c文件
#defineCHECK_KEY_DOWN0//处在检测按键压下阶段标志
#defineCHECK_KEY_UP1//处在检测按键抬起阶段标志
#defineKEY_UP0//按键抬起标志
#defineKEY_DOWN1//按键压下标志
sbit_p33=P3^3;
sbit_p34=P3^4;
sbit_p35=P3^5;
sbit_p36=P3^6;
char_key_status=CHECK_KEY_DOWN;
//按键检测状态(初值为检测压下阶段)
char_key_idx=0;
//按键序号
char_check_key(unsignedchar_key_idx){//检查按键状态
serial(~(0x01<
<
_key_idx));
//将待查按键键码转换成扫描码后输出
if(_p36==0){//根据P3.6状态决定返回值
returnKEY_DOWN;
returnKEY_UP;
charget_key(void){
charresult=-1;
//无键按下时键值为-1
if(_key_status==CHECK_KEY_DOWN)//如果当前处于检查压下阶段,进行以下操作
{if(_check_key(_key_idx)==KEY_DOWN)//判断当前扫描键的状态,若为压下_key_status=CHECK_KEY_UP;
标志,则将检查阶段标志设置为抬起
else{
_key_status=CHECK_KEY_DOWN;
//否则,将检查阶段标志设置为压下
if(++_key_idx==4){//判断4个按键是否已经轮流扫描一遍
_key_idx=0;
//是则将待扫描按键号设置为0
}}}
elseif(_key_status==CHECK_KEY_UP)
{//如果当前处于检查抬起阶段,进行以下操作
if(_check_key(_key_idx)==KEY_UP)
{//判断当前扫描键的状态,若为抬起标志则键值输出
result=_key_idx;
_key_status=CHECK_KEY_DOWN;
//案件检查阶段标志改为压下
if(++_key_idx==4)//判断4个按键是否已经轮流扫描一遍
{_key_idx=0;
//是,则将带扫描按键号设为0
returnresult;
(5)led.c文件
#include<
charcodemap1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//'
0'
~'
9'
charcodemap2[]={0x00,0x76,0x38};
//'
char_convert(charc){//将待显示字符转换为显示字符
if(c=='
)returnmap2[0];
elseif(c=='
)returnmap2[1];
)returnmap2[2];
elseif(c>
='
c<
)returnmap1[c-'
];
return0;
void_delay(){//软件延时函数
inti=0,j=0;
for(i=0;
10;
i++)
for(j=0;
j<
j++);
voidprint(charname,unsignedintvalue)//数码管显示函数(字符、数值)
{
charbuf[6];
chari=5;
for(i=5;
i>
1;
i--)
{buf[i]='
+value%10;
value/=10;
if(value==0)break;
i--;
for(;
=1;
i--)buf[i]='
;
buf[0]=name;
6;
i++){
P1&
=0xC0;
P1|=(1<
i);
P0=_convert(buf[i]);
delay();
(6)ad.c文件
sbitP32=P3^2;
sbitP33=P3^3;
sbitP34=P3^4;
sbitP35=P3^5;
unsignedcharad(){//A/D转换函数
P33=0;
P33=1;
while(!
P34);
//查询法等待转换结束
P35=1;
//OE置位
returnP2;
//输出转换结果
}
voidad_init(){//A/D转换的初始化
TMOD=0x02;
//定时器0方式2
TH0=0;
TL0=0;
ET0=1;
TR0=1;
EA=1;
void_ad_clock(void)interrupt1{//中断服务函数
P32=~P32;
(7)serial.asm文件
PUBLIC_SERIAL;
混合编程文件的标准前缀
DESEGMENTCODE
RSEGDE
_SERIAL:
MOVSCON,#0;
串口方式0
MOVSBUF,R7;
输出数据送入缓冲区
JNBTI,$;
等待移位结束
CLRTI;
清理标志位
RET
END
仿真效果:
实验小结:
经过这次上机,我了解了单片机应用系统的研制过程包括总体设计、硬件设计、软件设计及仿真调试等几个阶段,通过基于单片机系统的智能仪器的设计,进一步学习领会单片机的工作原理及单片机应用系统的开发方法和技巧。
总之,这次上机使我受益匪浅。