单片机课程设计智能仪器文档格式.docx
《单片机课程设计智能仪器文档格式.docx》由会员分享,可在线阅读,更多相关《单片机课程设计智能仪器文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
三、元器件列表,
图表1
四、实验原理
本实验选用了一只六联共阴极数码管显示器,按照动态显示原理接线,其中段码通过锁存器74LS245驱动后接于P0口,位码则有反相器74LS04驱动后接于。
A/D转换器采用逐次逼近方式的芯片ADC0809,其并行数据输出端直接连接于P2口,4个控制端CLOCK,START,EOC,和OE分别接于,采用查询法等待转换结束,转换时钟利用定时器中断产生。
四个面板按键通过8位串行输入并行输出移位寄存器74LS164与单片机接口,其移位时终端与单片机的TXD引脚相连,串行数据端(1和2脚)与单片机的RXD引脚相连,串口输出功能采用汇编语言与C51语言混合编程实现。
软件系统采用一个有多个功能模块构成的程序,模块之间相互依赖,他们之间的关系如图,程序有主要的两个功能模块组成——控制模块和菜单模块。
这两个模块能够同时运行。
这里,“同时”的意思是指用户进行菜单操作的时候,程序还能采集数据并进行控制。
图表2
软件系统结构组成
“控制”和“菜单”这两个主要的模块都是建立在其他小模块的基础上的,比如控制模块建立在A/D转换和LED显示的基础上,菜单建立在按键检测和LED显示的基础上,而按键检测又建立在串口输出的基础上。
下表列出了各个模块的主要函数。
图表3
各个模块的主要函数和功能
五、程序源代码
//
voidad_init();
voidcontrol_thread();
voidmenu_thread();
voidmain()
{
ad_init();
while
(1)
{
menu_thread();
control_thread();
}
}
#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();
voidprint(charname,unsignedintvalue);
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)
{
}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]);
#include<
>
sbitP32=P3^2;
sbitP33=P3^3;
sbitP34=P3^4;
sbitP35=P3^5;
sbitP37=P3^7;
unsignedcharad(){
P33=0;
P33=1;
while(!
P34);
P35=1;
returnP2;
voidad_init(){
TMOD=0x02;
TH0=0;
TL0=0;
ET0=1;
TR0=1;
EA=1;
void_ad_clock(void)interrupt1{
P32=~P32;
#include<
sbitP16=P1^6;
sbitP17=P1^7;
unsignedcharad();
externunsignedcharparam_value[2];
externcharmenu_status;
voidcontrol_thread(){
//第1步:
A/D转换
unsignedcharvalue=ad();
//第2步:
根据采样值控制LED灯
if(value>
param_value[1]){
P16=0;
P17=1;
}elseif(value<
=param_value[1]&
&
value>
=param_value[0]){
P17=0;
}else{
P16=1;
//第3步:
如果菜单是关闭的,显示采集到的数值
if(menu_status==1){
print('
'
value);
#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;
//按键序号
voidserial(charbyte);
char_check_key(unsignedchar_key_idx){//检查按键状态
serial(~(0x01<
<
_key_idx));
//将待查按键键码转换成扫描码后输出
if(_p36==0){//根据P36状态决定返回值
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{//否则,将检查阶段标志设置为压下
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;
//按键检查阶段标志改为压下
returnresult;
charcodemap1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7