智能仪器实验999999.docx

上传人:b****6 文档编号:7451209 上传时间:2023-01-24 格式:DOCX 页数:26 大小:129.95KB
下载 相关 举报
智能仪器实验999999.docx_第1页
第1页 / 共26页
智能仪器实验999999.docx_第2页
第2页 / 共26页
智能仪器实验999999.docx_第3页
第3页 / 共26页
智能仪器实验999999.docx_第4页
第4页 / 共26页
智能仪器实验999999.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

智能仪器实验999999.docx

《智能仪器实验999999.docx》由会员分享,可在线阅读,更多相关《智能仪器实验999999.docx(26页珍藏版)》请在冰豆网上搜索。

智能仪器实验999999.docx

智能仪器实验999999

智能仪器课程设计

实验室所用实验箱已经作了重新设计,故下面的设计仅供参考,实际应用必须作相应的修改!

一.带温度计的电子钟设计

1.设计任务

用温度传感器和4个按键、4个数码管设计带温度计的电子时钟程序,要求:

(1)用单线数字温度传感器DS18B20按键检测当前环境温度,温度精度0.1。

(2)用定时器/计数器显示电子走时(时、分),用2个按键(k1、k2)调整修改时钟,用4位数码管显示时钟。

(3)用2个按键(k3、k4)控制显示:

按下k3选择电子时钟显示;按下k4选择温度测量显示。

2.电路设计

根据设计要求,温度检测选用DS18B20,显示采用4位串行静态数码显示,数码管是共阳极,电路如图16-1所示。

图16-1带温度计的电子时钟电路原理图

3.算法思路和程序流程图

DS18B20是11位数字温度传感器,最小分辨率为0.125℃,采用单总线方式访问,时钟和数据共用一根线,这种单总线方式对读写时序有非常严格的要求,一旦时序上有偏差就会得不到正确的结果。

DS18B20进行温度转换时需要500ms~800ms的转换时间,主程序负责温度测量,每秒调用一次温度测量子程序。

按键检测与处理放在10ms定时器0中断程序中,这样时钟显示、修改和温度测量就会互不影响。

硬件配置:

CPU选择AT89C51,晶振时钟为12MHz;SW1、SW2用于调整修改时钟;SW3、SW4选择时钟、温度显示切换;RXD、TXD用作串行静态显示。

程序流程如图16-2所示。

程序规划:

1、功能规划

本设计软件的功能函数模块包括:

定时器0中断函数、串行静态数码管显示函数、DS18B20操作函数、延时函数。

其中定时器0中断函数主要用于按键检测与处理,判读是显示时钟还是显示温度,判读是否要修改时钟等功能。

串行静态数码管显示函数主要用来显示温度和时钟信息,根据显示缓冲区的内容来查笔形码表后显示相对应的信息。

DS18B20操作函数主要包括DS18B20的复位、初始化、读取转换温度等操作。

由于DS18B20对读写时序有非常严格的要求,因此对DS18B20的时序延时操作采用汇编程序编写,以达到精确的时序控制要求。

2、层次规划

软件的层次规划也即是通常所说的软件架构,即软件设计的总体思想、功能模块的划分、各模块间的通讯方式定义等。

一般如果采用自顶向下的软件设计方法都要先确定软件的架构,分配好任务后再进行编程。

本软件的层次规划为:

主程序主要完成系统各项状态、信息等的初始化,包括串行口初始化、定时器初始化、DS18B20初始化等。

然后控制每秒采集1次温度,并将采集的数字量标度变换成温度值。

同时等待定时器0中断程序中通过按键的操作来判断是显示时钟还是温度、是否要修改时钟、是修改时还是修改分等。

图16-2带温度计的电子时钟程序流程图

4.参考程序(资源分配、加注释的程序清单)

(1)常数定义与资源分配

#include

#include

#defineucharunsignedchar

sbitKEY1=P1^7;//时钟修改选择键

sbitKEY2=P1^6;//时钟修改加1键

sbitKEY3=P1^5;//按下此键显示时钟

sbitKEY4=P1^4;//按下此键显示温度

sbitDQ=P1^3;//数字温度传感器DS18B20接口

ucharHour;//小时存放单元

ucharMin;//分钟存放单元

ucharSec;//秒钟存放单元

intTempValue;//存放温度值

ucharTempH;//温度高值存放单元

ucharTempL;//温度低值存放单元

ucharTimCnt05S;//0.5秒计数单元,用于修改时闪烁显示

ucharTimCnt1S;//1秒计数单元,用于秒加1

ucharModifyBuf[2];//小时,分钟修改缓冲区

ucharDispBuf[4];//显示缓冲区存放单元首址

ucharModifyStat;//时钟修改状态,1,修改时;2,修改分

bitTim1SFlag;//1秒时间到标志位

bitKey1Old;//按键SW1旧值,用于延时去抖

bitKey2Old;//按键SW2旧值,用于延时去抖

bitKey3Old;//按键SW3旧值,用于延时去抖

bitKey4Old;//按键SW3旧值,用于延时去抖

bitKeyOK;//按键响应标志,防止连击

bitModifyFlag;//时钟是否处于修改状态(1为修改状态)

bitFlashFlag;//时钟修改闪烁单元

bitDispClk_T;//是处于时钟显示还是温度显示状态(1为时钟显示,0为温度显示)

bitSign;//温度正负标志位,正为0,负为1

//***温度传感器DS18B20

#defineCONFIG0x5f//11位温度转换(此时传感器最小分辨率为0.125摄氏度)

#defineTHIGH30

#defineTLOW10

//***数码管显示笔形码表

ucharcodeDispTab[18]={

//0123456789ABCDEF-(16)17

0x09,0x7D,0x07,0x15,0x71,0x91,0x81,0x3D,0x01,0x11,0x21,0xC1,0x8B,0x45,0x83,0xA3,0xF7,0xFF};

//***自定义函数

voidDS18B20Init(void);//DS18B20初始化函数

voidRdTemp(void);//启动温度测量,读取转换的温度值(数字量)

voidDispClock(void);//时钟计数值分离成显示格式函数

voidDispTemp(void);//温度变换,温度值分离成显示格式函数

voidDisp(void);//送显示单元的数据到数码管显示函数

externvoiddelayus(uchar);//us延时函数

externvoiddelayms(uchar);//ms延时函数

(2)主程序

主要完成系统初始化,控制每秒采集1次温度,并将采集的数字量标度变换成温度值,实现带温度计的电子钟设计。

main()

{SCON=0x00;

TMOD=0x01;//定时器0工作于方式1,10ms定时方式

TH0=55536/256;

TL0=55536%256;

ET0=1;

EA=1;

DS18B20Init();

TR0=1;

KeyOK=0;

Tim1SFlag=0;

ModifyFlag=0;

Key1Old=1;

Key2Old=1;

Key3Old=1;

Key4Old=1;

DispClk_T=1;

while

(1)

{while(!

Tim1SFlag);

Tim1SFlag=0;

RdTemp();

if(DispClk_T)continue;

DispTemp();

}

}

(3)定时中断函数

使用T0作定时器,定时10ms,完成时钟走时、按键扫描、时钟校准、数值显示和控制显示状态指示等。

voidTimer0(void)interrupt1

{TL0=55536%256;//重置定时器初值

TH0=55536/256;

if((++TimCnt1S)==100)

{TimCnt1S=0;

Tim1SFlag=1;//1s定时时间到

if((++Sec)==60)

{Sec=0;

if((++Min)==60)

{Min=0;

if((++Hour)==24)Hour=0;

}

}

if((!

ModifyFlag)&&(DispClk_T))DispClock();//判断是否要调用时钟显示

}//在时钟修改中和温度测量显示中,不需调用时钟显示

else

{//时钟修改中,需闪烁显示修改单元

if(ModifyFlag)

{if((++TimCnt05S)==50)

{FlashFlag=~FlashFlag;

if(FlashFlag)//熄灭

{DispBuf[(ModifyStat-1)*2]=17;

DispBuf[(ModifyStat-1)*2+1]=17;

}

else//点亮

{DispBuf[(ModifyStat-1)*2]=ModifyBuf[ModifyStat-1]/10;

DispBuf[(ModifyStat-1)*2+1]=ModifyBuf[ModifyStat-1]%10;

}

Disp();//显示显示缓冲区中的内容

}

}

}

if(!

KEY1)//是否有SW1(时钟修改选择键按下)

{if(!

Key1Old)//10ms之前此键也是按下,中断延时去抖

{if(!

KeyOK)//此按键是否已经响应

{if((++ModifyStat)==3)//是否完成修改

{ModifyStat=0;

Hour=ModifyBuf[0];

Min=ModifyBuf[1];

ModifyFlag=0;

}

KeyOK=1;//设置按键已响应标志,防止连击

}

}

Key1Old=KEY1;//10ms之前此键未按,还需要延时去抖

}

elseif(!

KEY2)//是否有SW2(修改加1键按下)

{if(!

Key2Old)//10ms之前此键也是按下,中断延时去抖

{if(!

KeyOK)//此按键是否已经响应

{if(ModifyStat==1)//修改时

{if((++ModifyBuf[0])==24)

{ModifyBuf[0]=0;

}

}

elseif(ModifyStat==2)//修改分

{if((++ModifyBuf[1])==60)

{ModifyBuf[1]=0;

}

}

KeyOK=1;//设置按键已响应标志,防止连击

}

}

Key2Old=KEY2;//10ms之前此键未按,还需要延时去抖

}

elseif(!

KEY3)//是否有SW3(时钟显示选择键按下)

{if(!

Key3Old)//10ms之前此键也是按下,中断延时去抖

{if(!

KeyOK)//此按键是否已经响应

{DispClk_T=1;

//DispClock();

KeyOK=1;//设置按键已响应标志,防止连击

}

}

Key3Old=KEY3;//10ms之前此键未按,还需要延时去抖

}

elseif(!

KEY4)//是否有SW4(时钟显示选择键按下)

{if(!

Key4Old)//10ms之前此键也是按下,中断延时去抖

{if(!

KeyOK)//此按键是否已经响应

{DispClk_T=0;

//DispTemp();//应屏蔽,防止跟主程序的有冲突

KeyOK=1;//设置按键已响应标志,防止连击

}

}

Key4Old=KEY4;//10ms之前此键未按,还需要延时去抖

}

else

{Key1Old=1;

Key2Old=1;

Key3Old=1;

Key4Old=1;

}

}

(4)显示函数:

将显示缓冲区中的内容送数码管显示子程序

voidDisp(void)

{uchari,j;

for(i=0;i<4;i++)

{j=DispBuf[i];

j=DispTab[j];//查笔形码表

if(!

ModifyFlag&&!

DispClk_T)//确保当前不是处于时钟修改中且显示温度有效

{if(i==2)j=j&0xfe;//在倒数第二个数码管加上小数点

}

SBUF=j;

while(!

TI);

TI=0;

}

}

/*****时钟显示单元分离函数******/

voidDispClock(void)

{DispBuf[0]=Hour/10;

DispBuf[1]=Hour%10;

DispBuf[2]=Min/10;

DispBuf[3]=Min%10;

Disp();

}

/******温度变换和显示单元分离函数******

**11位温度转换分辨率为0.125,结果=Td×125/100,得到带1位小数的摄氏温度值*****/

voidDispTemp(void)

{TempValue=(TempValue*5)/4;//显示3位温度值,最高位作温度的正负,为负显示-

if(TempValue<0)//如果为负

{TempValue=0-TempValue;//取补码

Sign=1;

}

elseSign=0;

if(Sign)DispBuf[0]=16;//显示负号

elseDispBuf[0]=17;//为正,不显示

DispBuf[1]=(TempValue%1000)/100;

DispBuf[2]=(TempValue%100)/10;

DispBuf[3]=TempValue%10;

Disp();

}

(5)DS18B20操作函数

DS18B20是单总线访问的器件,使用改器件时,先应复位初始化,设置配置寄存器,应按照时序对器件进行读写,每次读写时先对其复位,然后读出当前转换的温度值。

/**************DS18B20初始化函数********************/

voidDS18B20Init(void)

{ow_reset();//复位

write_uchar(0xcc);//发SKIPROM命令

write_uchar(0x4e);//发写TH和TL

write_uchar(THIGH);//写高温报警点

write_uchar(TLOW);//写低温报警点

write_uchar(CONFIG);//写配置寄存器,11位

}

/************读取温度*****************/

voidRdTemp(void)

{uchari,j;

ow_reset();

write_uchar(0xcc);//SkipROM

write_uchar(0x44);//ReadScratchPad

for(i=0;i<8;i++)//延时800ms

{delayms(100);

}

ow_reset();

write_uchar(0xcc);//SkipROM

write_uchar(0xbe);//发读存储器命令

i=read_uchar();//读出温度的低字节

j=read_uchar();//读出温度的高字节

read_uchar();//读出TH

read_uchar();//读出TL

read_uchar();//读出CONFIG

TempValue=j*256+i;

}

/*******复位函数********************/

voidow_reset(void)//复位

{//bitpresence=1;

DQ=1;

do

{while(DQ)

{DQ=0;//pullDQlinelow

delayus(149);//低电平480-960us,取600us

delayus(149);

DQ=1;//电阻上拉15~60us,取50

delayus(29);//waitforpresence

}

delayus(119);//延时240us

}while(!

DQ);

delayus(249);//延时500us

}

/************从1-wire总线上读取一个字节****************/

ucharread_uchar(void)

{

uchari;

ucharvalue=0;

for(i=8;i>0;i--)

{value>>=1;

DQ=0;//pullDQlowtostarttimeslot

_nop_();

DQ=1;//thenreturnhigh

delayus(5);//延时12us

if(DQ)value|=0x80;

delayus(29);//延时60us

}

DQ=1;//thenreturnhigh

return(value);

}

/************向1-WIRE总线上写一个字节*****************/

voidwrite_uchar(ucharval)

{

uchari;

for(i=8;i>0;i--)//writesuchar,onebitatatime

{DQ=1;

_nop_();

DQ=0;//pullDQlowtostarttimeslot

delayus(7);//延时16us

DQ=val&0x01;

delayus(29);//延时60us

DQ=1;

val=val/2;

}

DQ=1;

}

(6)延时函数

使用汇编语言编写延时程序(DELAY.ASM),以混合编程的方式嵌入到C51程序中。

NAMEDELAY

?

PR?

_delayms?

DELAYSEGMENTCODE;申明代码段

?

PR?

_delayus?

DELAYSEGMENTCODE

PUBLIC_delayms,_delayus;输出函数名

RSEG?

PR?

_delayms?

DELAY;这个函数可被连接器放置在任何地方

_delayms:

;延时函数体

D1:

MOVR6,#10

D2:

MOVR5,#48

D3:

DJNZR5,D3

DJNZR6,D2;以上程序为延时1ms

DJNZR7,D1

RET

RSEG?

PR?

_delayus?

DELAY;必须为(2x+2)us

_delayus:

DJNZR7,$

RET

END

二.可控波形发生器

1.设计任务

用D/A转换器和键盘、显示设计可控波形发生器,要求:

(1)用单片机控制D/A转换器产生输出的波形,频率范围在0~1KHz。

(2)用按键选择输出方波、三角波、锯齿波或正弦波,输出波形频率能用步进可调,按键步进10Hz。

(3)通过键盘能预置波形输出频率,用数码显示当前输出波形的频率值。

2.电路设计

根据设计要求,采用D/A转换产生波形输出,由单片机控制波形的频率,扩展4位串行静态数码显示,数码管是共阳极;扩展4*4键盘选择输出波形,修改输出波形频率,实验电路如图16-1所示。

图16-3可控波形发生器电路原理图

3.算法思路和程序流程图

4*4键盘有16个键,其中0~9数字键用于预设输出波形频率,F键用于频率预置确认键,A键用于频率步进“+”键(步进为10Hz),B键用于频率步进“-”键,C键用于切换输出波形类型。

正弦波对应的50个波形点的数字量由TurboC2.0编程得出形成表格。

图16-4波形发生器主要程序流程图

波形发生器对打点的时间间隔要求比较严格,使用定时器T2控制定时打点。

因为波形输出频率的范围为10Hz~1KHz,相应的打点间隔时间为2000us~20us,考虑到20us的时间很短,应采用定时器的自动重装方式来实现定时打点。

由于T0、T1定时器只有8位定时重装方式,满足不了定时2000us的要求,故选用89C52系列单片机的定时器2来实现自动重装。

定时器0工作于10ms定时方式,用于按键检测和显示等功能。

系统监控程序采用汇编语言编写,程序流程如图16-4所示。

4.参考程序(资源分配、加注释的程序清单)

(1)资源分配常量定义

T2CONDATA0C8H;8052Extensions

RCAP2LDATA0CAH

RCAP2HDATA0CBH

TL2DATA0CCH

TH2DATA0CDH

ET2BIT0ADH

PT2BIT0BDH

TF2BIT0CFH

TR2BIT0CAH

KEYPORTEQUP1;4*4的矩阵键盘接在P1口

DA0832_ADDREQU00H;DAC0832地址

DA0832_CSBITP2.0

WAVE_TYPEDATA30H;存放波形类型,0:

正弦波,1:

方波,2:

三角波,3:

锯齿波

WAVE_FREQDATA31H;存放波形频率

WAVE_PTDATA32H;存放表格指针偏移量

KEYCODEDATA33H;按键扫描码存放单元

FREQ_BUFEQU34H;频率设置和显示值存放单元首址(占34H~37H)

T0_INT_FLAGBIT20H.0;T0定时器中断标志

KEYOKBIT20H.1;按键响应标志,防止连击

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 家庭教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1