_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;
P33=0;
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();
voidprint(charname,unsignedintvalue);
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]){
P16=0;
P17=0;
}else{
P16=1;
P17=0;
}
//第3步:
如果菜单是关闭的,显示采集到的数值
if(menu_status==1){
print('',value);
}
}
//
#include<>
#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;
}else{
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;//按键检查阶段标志改为压下
if(++_key_idx==4){//判断是否4个按键已经轮流扫描一遍
_key_idx=0;//是,则将待扫描按键号设为0
}
}
}
returnresult;
}
//
#include<>
charcodemap1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
charcodemap2[]={0x00,0x76,0x38};
char_convert(charc){
if(c=='')
returnmap2[0];
elseif(c=='H')
returnmap2[1];
elseif(c=='L')
returnmap2[2];
elseif(c>='0'&&c<='9')
returnmap1[c-'0'];
return0;
}
void_delay(){
inti=0,j=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
}
}
}
voidprint(charname,unsignedintvalue){
charbuf[6];
chari=5;
for(i=5;i>1;i--){
buf[i]='0'+value%10;
value/=10;
if(value==0){
break;
}
}
i--;
for(;i>=1;i--){
buf[i]='';
}
buf[0]=name;
for(i=0;i<6;i++){
P1&=0xC0;
P1|=(1<
P0=_convert(buf[i]);
delay();
}
}
//
PUBLIC_SERIAL
DESEGMENTCODE
RSEGDE
_SERIAL:
MOVSCON,#0
MOVSBUF,R7
JNBTI,$
CLRTI
RET
END
六、实验结果
图表4
程序通过编译,并且没有错误
系统运行效果如图所示,参数设置状态效果如图所示。
实际运行情况表明,测控与参数设置着两个环节的确是“同时”进行的。
具体表现为,若参数L设置为100,某一时刻的采样值为60,那么在参数设置过程中,处于后台运行的控制程序还会使报警器D1在此时点亮。
若将参数L修改为30,只要确认保存参数后,不等关闭菜单显示,D1就会熄灭了。
采用并行结构编程是一种非常有用的设计思想,其要点在于可是多个程序“同时”拥有运行权限,对外表现出实时多任务的效果。
这类程序的关键在于每个程序都不能这多的占用机时,因此必须设法将长时运行改为短时运行。
本实验采用的运行标记设置的做法就是一个具体的体现。
图表5
测控状态运行效果
图表6
参数设置状态运行效果
七、总结
通过本次试验,我发现了自己对学习单片机和做实验中存在两个主要缺点:
一是依赖性很大,刚开始编程序时喜欢套用书上的语句,希望从书上找到源代码,但是当我从别处找来源代码时,却很难读懂别人写的代码,也就是对语句的理解不够。
于是当我在调试程序控制protues仿真软件时出现了很多的问题,而我也不知道该怎么样修改,因为眼前的程序都是自己写的和别人写的拼凑起来的,没有很清楚的理解哪些代码控制哪些功能,没法知道哪里错了。
但是经过我不断的改错,看c语言书,最后终于调试出来了,通过实验我发现编程是一件很严肃的事情,容不得半点错误。
二是基础知识的薄弱,在用C语言编程时,才发现自己C语言真的太差劲了,虽然这门课程我在大一下学期早就学过,但是就目前所掌握的C语言知识,对于单片机编程远远不够。
C语言也是我们以后学各种语言的基础,必须要花大量的时间温习强化。
在通过本次课程中,我遇到很多问题,但是与此同时,我们也学到了很多,对我以后的学习会产生影响:
不管做什么事,计划是很重要的;做事要多动脑,选出最好的方法;要注意细节。
细节决定成败;最后,也是最重要的一点,通过这次课题,我们学到了很多有关单片机方面的知识,也对单片机有了更深入的了解。
使我们受益匪浅。
在电子技术应用领域中,单片机的应用愈来愈多地应用到各行各业。
要开发单片机的应用,不但要掌握单片机硬件和软件方面的知识,而且还要深入了解各应用系统的专业知识,融会贯通和有机结合,才能设计出优良的应用系统。
培养自己接受新知识的自学能力,掌握芯片发展动态。
培养自己的创新精神,在原有的基础上进行改进,使之功能不断完善。
当然,最重要到还是态度,无论做什么事情,足够认真,足够坚强,足够毅力,足够决心,足够勇气,就一定能办到。