报温度系统课程设计.docx
《报温度系统课程设计.docx》由会员分享,可在线阅读,更多相关《报温度系统课程设计.docx(39页珍藏版)》请在冰豆网上搜索。
![报温度系统课程设计.docx](https://file1.bdocx.com/fileroot1/2023-2/28/fb112f63-f20d-47fe-aa7a-8bd8abe90b3b/fb112f63-f20d-47fe-aa7a-8bd8abe90b3b1.gif)
报温度系统课程设计
单片机课程设计报告
题目:
数字温度计
摘要:
本数字温度计是以STC89C52单片机为主控器,温度传感器DS18b20以及语音芯片ISD1760为辅,来实现数字温度显示以及报数的功能。
温度传感器DS18b20是12位高分辨率,精度可达0.5摄氏度的传感器,它能够全数字温度转换及输出。
输出的温度则在数码管LED上显示。
而语音芯片ISD1760可以用SPI的通讯方式与单片机进行通讯,这样实现定点录音以及定点播放。
把所需的声音录进,当需要读温度则可将所录音按温度值组合在一起,从而实现语音报数。
关键词:
STC89C52温度传感器DS18b20语音芯片1760语音报数
Abstract:
thedigitalthermometerisSTC89C52single-chipmicrocomputerasthemaincontroller,temperatureDS18b20andspeechchipISD1760iscomplementary,torealizethedigitaltemperaturedisplayandthefunctionofthenumberoff.Thetemperaturesensorandb20is12highresolution,theaccuracycanreach0.5degreesCelsiussensor,itcanfullydigitaltemperatureconversionandoutput.TheoutputofthetemperatureinthedigitaltubeLEDdisplay.AndthespeechchipISD1760canuseSPIcommunicationwayandthesinglechipmicrocomputercommunication,sothatrealizepointrecordingandpointplay.Thevoiceoftherequiredtorecord,whenneedtoreadthetemperaturecanbeaccordingtotherecordingtemperaturetogether,soastorealizethevoicecountoff.
Keywords:
STC89C52DS18b20ISD1760countof
1方案论证………………………………………………………3
1.1温度传感器方案论证……………………………………3
1.2语音芯片方案论证………………………………………3
1.3MCU方案论证……………………………………………3
2系统设计………………………………………………………3
2.1总体设计………………………………………………3
2.2单元电路设计…………………………………………4
2.2.1MCU电路设计…………………………………4
2.2.2LED显示电路…………………………………4
2.2.3语音录放芯片电路……………………………5
3软件设计………………………………………………………6
4结论与感想……………………………………………………7
5附加代码………………………………………………………8
1方案论证
1.1温度传感器选择方案
本系统只需把温度转化为数字信号然后显示在LED上即可,因此选择温度传感器DS18b20。
它的测温范围是-55摄氏度~+125摄氏度,固有测温分辨率0.5摄氏度,满足了题目的要求。
而且它工作电压小,仅有三个引出引脚:
VCC,GND以及数字信号输入输出引脚。
1.2语音芯片方案论证
按照题目所需,要实现随机温度报数的功能,因而不用选择具有语音处理功能的语音芯片,而选择可以定点录音和定点播放的芯片。
在这里选择ISD1760。
ISD1760语音录放芯片是Winbond推出的单片优质语音录放芯片,可以录放音达十万次,其中录音可以通过在线录音以及MIC录音。
主控单片机可以通过四线(SCLK,MOSI,MISO,SS)SPI协议对ISD1760进行串行通信。
这样可以通过MCU来控制ISD1760的定点录音和定点播放。
1.3MCU方案论证
方案一、用STM8系列的单片机,资源丰富,包括集成的SPI等外设以及丰富的IO口,而且主控晶振频率高。
但容易造成资源浪费现象。
方案二、用51单片机来作为主控芯片,仅需提供一个引脚来采集温度传感器的数据,还可用IO引脚来模拟SPI引脚与ISD1760进行通讯,还有足够的IO引脚。
因此选择这个方案。
2系统设计
2.1总体设计
通过51单片机对温度传感器的数据进行采集,然后通过数码管LED进行显示。
同时51单片机还控制ISD1760的定点播放(提前把所需的语音录进去),通过按键来进行语音播放功能。
当选择语音播放功能后会读出LED上所显示的温度。
2.2单元电路设计
2.2.1MCU电路设计
参考官方手册的最小系统电路即可。
2.2.2LED显示电路
这里仅采用四位共阳的数码管作为显示各个段选信号分别通过51单片机的P0.0~P0.7来控制,而位选信号则通过三极管S9013和51单片机的P1端口控制。
S9013作为位选原理是:
三极管集电极接+5V电源,发射极分别接各个数码管的片选端,基极接单片机引脚。
这样当上电时给单片机P1^X一个低电平信号时就可以选通某位数码管,从而实现数码管的位选。
2.2.3语音录放芯片电路
语音录放芯片电路参考的是其官方手册的电路进行些许修改得到。
其中引脚4~5可以通过MCU控制语音录放芯片的录音,播放等功能。
另外22~27引脚以及19~20可以直接用按键来实现芯片的各种功能。
AL—in引脚可以支持线录,MIC利用咪头录音。
这里就用MIC的方式进行录音,然后利用SP-和SP+所接的喇叭(最好选择1~8欧,1~4瓦)放音。
另外,ROSC引脚是语音录放芯片的晶振电阻引脚,根据官方手册当该引脚接不通的阻值电阻时录放的时间是不同的。
这里提供两种选择:
一是60K的60秒录放时间,而是80K的75秒的录放时间。
用户可以根据自己的情况来选择。
3软件设计
对于温度传感器的读数利用定时器来不断的更新读取,报数则利用按键实现。
其软件流程图如下(不太会用软件画图,有点丑陋,望见谅)
4结论和感想
通过这次课程设计在此让我意识到学生的动手能力是多么重要。
虽然之间花了还是花了不少时间调试硬件,但经过自己的努力还是把整个作品完成了。
现在想起来今年年头时参加校赛时那种无助的我花了四五十天都没办法完成作品,但现在的课程设计花了不到一个星期的时间就把硬件和软件都搞好了。
虽然感觉课程设计没什么难度,但我觉得我还是有了很明显的进步。
同时在这次课程设计中,我又知道在一个项目中有很多东西要注意的以及学习到很多新的知识。
比如这次学习了温度传感器和语音录放芯片。
还有很多细节性的东西,就比如这次课程设计中为什么会花那么多时间做硬件调试?
就是因为我的粗心大意没有注意到细节上的问题而导致电路短路自己却全然不知。
通过此次的课程设计我也深深意识到,原来学到的理论知识没有拿出来用到实际的应用中,就永远不会知道一些知识的用法还有知识在细节上的问题。
在剩下的大学时光,我会花更多的时间把理论与实际操作结合到一起,来使我的知识更加充实。
5附加代码
一、主程序(报温系统.c):
#include//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<18b20.h>
#include
#include
#defineDataPortP0//定义数据端口程序中遇到DataPort则用P1替换
sbitLATCH1=P2^0;//定义锁存使能端口段锁存
sbitLATCH2=P2^1;//位锁存
sbitSOUND=P3^2;
unsignedintTempH,TempL,temp,Shi,Ge;
bitReadTempFlag;//定义读时间标志
unsignedcharcodeHEYAO_DuanMa[]={0xc0,0xcf,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsignedcharcodeHEYAO_WeiMa[]={0x0e,0x0d,0x0b,0x07};
unsignedcharTempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量
voidDisplay(unsignedcharFirstBit,unsignedcharNum);//数码管显示函数
voidInit_Timer0(void);//定时器初始化
//voidDisTemp();
//voidluyin();
/*------------------------------------------------
主函数
------------------------------------------------*/
voidmain(void)
{
Init_Timer0();
ISD_Init();
SOUND=1;
while
(1)//主循环
{
if(ReadTempFlag==1)
{
ReadTempFlag=0;
temp=ReadTemperature();
TempH=temp>>4;
TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理
if(temp&0x8000)//检测温度的正负
{
TempData[0]=0xBF;//负号标志
temp=~temp;//取反加1
temp+=1;
}
else
{
TempData[0]=0xff;
if(TempH/100==0)
TempData[1]=0XFF;
else
TempData[1]=HEYAO_DuanMa[TempH/100];//百位温度
}
if((TempH/100==0)&&((TempH%100)/10==0))//消隐
TempData[1]=0XFF;
else
TempData[1]=HEYAO_DuanMa[(TempH%100)/10];//十位温度
TempData[2]=HEYAO_DuanMa[(TempH%100)%10]&0x7F;//个位温度,带小数点
TempData[3]=HEYAO_DuanMa[TempL];
}
/*************语音报实时温度*************/
Shi=(TempH%100)/10;
Ge=(TempH%100)%10;
if(SOUND==0)
{
Delay(10);
if(SOUND==0)
{
while(!
SOUND);
if(temp&0x8000)//检测温度的正负
{
SetPLAY(13);
}
else
{
if(TempH/100!
=0)
{
SetPLAY
(1);
SetPLAY(12);
}
}
SetPLAY(Shi);
SetPLAY(10);
SetPLAY(Ge);
SetPLAY(11);
SetPLAY(TempL);
SetPLAY(14);
}
}
}
}
/****************************************************************
用于录音
****************************************************************
voidluyin()
{
//SetREC(14);
ISD_PD();
}
/*------------------------------------------------
用于动态扫描数码管
--------------------------------------------*/
voidDisplay(unsignedcharFirstBit,unsignedcharNum)
{
staticunsignedchari=0;
DataPort=0xff;//清空数据,防止有交替重影
P2=HEYAO_WeiMa[i+FirstBit];//取位码
DataPort=TempData[i];//取显示数据,段码
i++;
if(i==Num)
i=0;
}
/*voidDisTemp()
{
ReadTempFlag=0;
temp=ReadTemperature();
TempH=temp>>4;
TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理
if(temp&0x8000)//检测温度的正负
{
TempData[0]=0xBF;//负号标志
temp=~temp;//取反加1
temp+=1;
}
else
{
TempData[0]=0xff;
if(TempH/100==0)
TempData[0]=0XFF;
else
TempData[0]=HEYAO_DuanMa[TempH/100];//百位温度
}
if((TempH/100==0)&&((TempH%100)/10==0))//消隐
TempData[1]=0XFF;
else
TempData[1]=HEYAO_DuanMa[(TempH%100)/10];//十位温度
TempData[2]=HEYAO_DuanMa[(TempH%100)%10]&0x7F;//个位温度,带小数点
TempData[3]=HEYAO_DuanMa[TempL];
}*/
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
voidInit_Timer0(void)
{
TMOD|=0x01;//使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00;//给定初值
//TL0=0x00;
EA=1;//总中断打开
ET0=1;//定时器中断打开
TR0=1;//定时器开关打开
}
/*voidOutside_Init(void)//开外部中断0
{
EX0=1;//开外部中断0
//EX1=1;
IT0=1;//负边沿触发
//IT1=1;
EA=1;//开总中断
}*/
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
voidTimer0_isr(void)interrupt1
{
staticunsignedintnum;
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,4);//调用数码管扫描
num++;
if(num==300)//
{
num=0;
ReadTempFlag=1;//读标志位置1
}
}
二、语音录放芯片源程序(ISD1760.c):
/*使用独立按键录音,根据所录秒数得到地址,使用放音函数进行放音*/
#include
#include
#include
sbitSS=P1^3;
sbitSCLK=P1^2;
sbitMOSI=P1^1;
sbitMISO=P1^0;
ucharSR0_L;//存放读到的寄存器数据,下同
ucharSR0_H;
ucharSR1;
ucharID,APCL=0,APCH=0;
//-------------------------------------------------------------
//每2秒大约是8个十进制地址,即十六进制0x08,后一段声音越界
//就只会播前段声音的后面的一部分,遇到“EOM”停止,所根据录得
//秒上述乘以8,转化成十六进制数,得到大概地址,后面进行微调
//-------------------------------------------------------------
uintcaToneAdd[]={0x0010,0x0010+0x08,0x0010+0x08,0x0010+0x10,//0,1
0x0010+0x10,0x0010+0x18,0x0010+0x18,0x0010+0x20,//2,3
0x0010+0x20,0x0010+0x28,0x0010+0x28,0x0010+0x30,//4,5
0x0010+0x30,0x0010+0x38,0x0010+0x38,0x0010+0x40,//6,7
0x0010+0x40,0x0010+0x48,0x0010+0x48,0x0010+0x50,//8,9
0x0010+0x50,0x0010+0x58,0x0010+0x58,0x0010+0x60,//10,点
0x0010+0x60,0x0010+0x68,0x0010+0x68,0x0010+0x70,//百,负
0x0010+0x70,0x0010+0x78};//摄氏度
voidI_delay(void)
{
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
}
//----------------------------------------------------------------
//MS级延时函数
//----------------------------------------------------------------
//----------------------------------------------------------------
//MS级延时函数
//----------------------------------------------------------------
voidDelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
{
for(y=110;y>0;y--);
}
}
/**************************************************************************
*函数名:
voidISD_Init(void);
*初始化:
包括了复位、上电、读状态、清除中断、设置APC2、读APC等子函数
**************************************************************************/
voidISD_Init(void)
{
ISD_Reset();
do
{
ISD_PU();
RdStatus();
}while((SR0_L&0x01)||(!
(SR1&0x01)));//if(SR0_L^0==1){systemErr}
ClrInt();
RD_DevID();
ISD_WR_APC2();
RdAPC();
}
//----------------------------------------------------------------
//函数名:
SPISendData()
//SPI传输数据(发送数据)子程序
//----------------------------------------------------------------
ucharSPISendData(ucharBUF_ISD)
{
uchari,dat=BUF_ISD;
SCLK=1;
SS=0;//拉低准备
//Delay(5);
for(i=0;i<8;i++)
{
SCLK=0;
I_delay();
if(dat&0x01)
{
MOSI=1;
}
else//发送
{
MOSI=0;
}
dat>>=1;
if(MISO)
{
dat|=0x80;
}
SCLK=1;
I_delay();
}
MOSI=0;
//SS=1;
return(dat);
}
/**************************************************************************
*函数名:
voidRdStatus(void);
*读状态
**************************************************************************/
voidRdStatus(void)
{
//SS=0;
//Delay(10);
SPISendData(RD_STATUS);//向ISD1760发送命令读寄存器状态
SPISendData(0x00);//数据字节1
SPISendData(0x00);//起始地址字节1