1、单片机课程设计报告题目:数字温度计摘要:本数字温度计是以STC89C52单片机为主控器,温度传感器DS18b20以及语音芯片ISD1760为辅,来实现数字温度显示以及报数的功能。温度传感器DS18b20是12位高分辨率,精度可达0.5摄氏度的传感器,它能够全数字温度转换及输出。输出的温度则在数码管LED上显示。而语音芯片ISD1760可以用SPI的通讯方式与单片机进行通讯,这样实现定点录音以及定点播放。把所需的声音录进,当需要读温度则可将所录音按温度值组合在一起,从而实现语音报数。关键词:STC89C52 温度传感器DS18b20 语音芯片1760 语音报数Abstract: the digi
2、tal thermometer is STC89C52 single-chip microcomputer as the main controller, temperature DS18b20 and speech chip ISD1760 is complementary, to realize the digital temperature display and the function of the number off. The temperature sensor and b20 is 12 high resolution, the accuracy can reach 0.5
3、degrees Celsius sensor, it can fully digital temperature conversion and output. The output of the temperature in the digital tube LED display. And the speech chip ISD1760 can use SPI communication way and the single chip microcomputer communication, so that realize point recording and point play. Th
4、e voice of the required to record, when need to read the temperature can be according to the recording temperature together, so as to realize the voice count off.Keywords: STC89C52 DS18b20 ISD1760 count of1 方案论证31.1 温度传感器方案论证31.2 语音芯片方案论证31.3 MCU方案论证32 系统设计3 2.1 总体设计3 2.2 单元电路设计4 2.2.1 MCU电路设计42.2.2
5、 LED显示电路42.2.3 语音录放芯片电路53 软件设计64 结论与感想75 附加代码81 方案论证1.1 温度传感器选择方案本系统只需把温度转化为数字信号然后显示在LED上即可,因此选择温度传感器DS18b20。它的测温范围是-55摄氏度+125摄氏度,固有测温分辨率0.5摄氏度,满足了题目的要求。而且它工作电压小,仅有三个引出引脚:VCC,GND以及数字信号输入输出引脚。1.2 语音芯片方案论证按照题目所需,要实现随机温度报数的功能,因而不用选择具有语音处理功能的语音芯片,而选择可以定点录音和定点播放的芯片。在这里选择ISD1760。ISD1760语音录放芯片是Winbond推出的单片
6、优质语音录放芯片,可以录放音达十万次,其中录音可以通过在线录音以及MIC录音。主控单片机可以通过四线(SCLK,MOSI,MISO,SS)SPI协议对ISD1760进行串行通信。这样可以通过MCU来控制ISD1760的定点录音和定点播放。1.3 MCU方案论证方案一、用STM8系列的单片机,资源丰富,包括集成的SPI等外设以及丰富的IO口,而且主控晶振频率高。但容易造成资源浪费现象。方案二、用51单片机来作为主控芯片,仅需提供一个引脚来采集温度传感器的数据,还可用IO引脚来模拟SPI引脚与ISD1760进行通讯,还有足够的IO引脚。因此选择这个方案。2 系统设计2.1 总体设计通过51单片机对
7、温度传感器的数据进行采集,然后通过数码管LED进行显示。同时51单片机还控制ISD1760的定点播放(提前把所需的语音录进去),通过按键来进行语音播放功能。当选择语音播放功能后会读出LED上所显示的温度。2.2 单元电路设计2.2.1 MCU电路设计 参考官方手册的最小系统电路即可。2.2.2 LED显示电路 这里仅采用四位共阳的数码管作为显示各个段选信号分别通过51单片机的P0.0P0.7来控制,而位选信号则通过三极管S9013和51单片机的P1端口控制。S9013作为位选原理是:三极管集电极接+5V电源,发射极分别接各个数码管的片选端,基极接单片机引脚。这样当上电时给单片机P1X一个低电平
8、信号时就可以选通某位数码管,从而实现数码管的位选。2.2.3 语音录放芯片电路 语音录放芯片电路参考的是其官方手册的电路进行些许修改得到。其中引脚45可以通过MCU控制语音录放芯片的录音,播放等功能。另外2227引脚以及1920可以直接用按键来实现芯片的各种功能。ALin引脚可以支持线录,MIC利用咪头录音。这里就用MIC的方式进行录音,然后利用SP-和SP+所接的喇叭(最好选择18欧,14瓦)放音。另外,ROSC引脚是语音录放芯片的晶振电阻引脚,根据官方手册当该引脚接不通的阻值电阻时录放的时间是不同的。这里提供两种选择:一是60K的60秒录放时间,而是80K的75秒的录放时间。用户可以根据自
9、己的情况来选择。3 软件设计 对于温度传感器的读数利用定时器来不断的更新读取,报数则利用按键实现。其软件流程图如下(不太会用软件画图,有点丑陋,望见谅)4 结论和感想通过这次课程设计在此让我意识到学生的动手能力是多么重要。虽然之间花了还是花了不少时间调试硬件,但经过自己的努力还是把整个作品完成了。现在想起来今年年头时参加校赛时那种无助的我花了四五十天都没办法完成作品,但现在的课程设计花了不到一个星期的时间就把硬件和软件都搞好了。虽然感觉课程设计没什么难度,但我觉得我还是有了很明显的进步。同时在这次课程设计中,我又知道在一个项目中有很多东西要注意的以及学习到很多新的知识。比如这次学习了温度传感器
10、和语音录放芯片。还有很多细节性的东西,就比如这次课程设计中为什么会花那么多时间做硬件调试?就是因为我的粗心大意没有注意到细节上的问题而导致电路短路自己却全然不知。通过此次的课程设计我也深深意识到,原来学到的理论知识没有拿出来用到实际的应用中,就永远不会知道一些知识的用法还有知识在细节上的问题。在剩下的大学时光,我会花更多的时间把理论与实际操作结合到一起,来使我的知识更加充实。5 附加代码一、主程序(报温系统.c):#include /包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include #include #include #define DataPort P0 /定义
11、数据端口 程序中遇到DataPort 则用P1 替换sbit LATCH1=P20;/定义锁存使能端口 段锁存sbit LATCH2=P21;/位锁存sbit SOUND=P32;unsigned int TempH,TempL,temp,Shi,Ge;bit ReadTempFlag;/定义读时间标志unsigned char code HEYAO_DuanMa=0xc0,0xcf,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;unsigned char code HEYAO_WeiMa=0x0e,0x0d,0x0b,0x07;unsigned char T
12、empData8=0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF; /存储显示值的全局变量void Display(unsigned char FirstBit,unsigned char Num);/数码管显示函数void Init_Timer0(void);/定时器初始化/void DisTemp();/void luyin();/*- 主函数-*/void main (void) Init_Timer0();ISD_Init();SOUND=1;while (1) /主循环 if(ReadTempFlag=1)ReadTempFlag=0; temp=Re
13、adTemperature(); TempH=temp4; TempL=temp&0x0F; TempL=TempL*6/10;/小数近似处理 if(temp&0x8000)/检测温度的正负 TempData0=0xBF;/负号标志 temp=temp; / 取反加1 temp +=1;else TempData0=0xff; if(TempH/100=0) TempData1=0XFF; else TempData1=HEYAO_DuanMaTempH/100; /百位温度if(TempH/100=0)&(TempH%100)/10=0)/消隐TempData1=0XFF;else Temp
14、Data1=HEYAO_DuanMa(TempH%100)/10; /十位温度 TempData2=HEYAO_DuanMa(TempH%100)%10&0x7F; /个位温度,带小数点 TempData3=HEYAO_DuanMaTempL; /*语音报实时温度*/Shi=(TempH%100)/10;Ge=(TempH%100)%10;if(SOUND=0)Delay(10);if(SOUND=0)while(!SOUND);if(temp&0x8000)/检测温度的正负SetPLAY(13);elseif(TempH/100!=0)SetPLAY(1);SetPLAY(12);SetPL
15、AY(Shi);SetPLAY(10);SetPLAY(Ge);SetPLAY(11);SetPLAY(TempL);SetPLAY(14); /*用于录音*void luyin()/SetREC(14);ISD_PD();/*-用于动态扫描数码管-*/void Display(unsigned char FirstBit,unsigned char Num) static unsigned char i=0;DataPort=0xff; /清空数据,防止有交替重影P2=HEYAO_WeiMai+FirstBit; /取位码 DataPort=TempDatai; /取显示数据,段码i+; i
16、f(i=Num)i=0;/*void DisTemp() ReadTempFlag=0; temp=ReadTemperature(); TempH=temp4; TempL=temp&0x0F; TempL=TempL*6/10;/小数近似处理 if(temp&0x8000)/检测温度的正负 TempData0=0xBF;/负号标志 temp=temp; / 取反加1 temp +=1;else TempData0=0xff; if(TempH/100=0) TempData0=0XFF; else TempData0=HEYAO_DuanMaTempH/100; /百位温度if(TempH
17、/100=0)&(TempH%100)/10=0)/消隐TempData1=0XFF;else TempData1=HEYAO_DuanMa(TempH%100)/10; /十位温度 TempData2=HEYAO_DuanMa(TempH%100)%10&0x7F; /个位温度,带小数点 TempData3=HEYAO_DuanMaTempL;*/*- 定时器初始化子程序-*/void Init_Timer0(void)TMOD |= 0x01; /使用模式1,16位定时器,使用|符号可以在使用多个定时器时不受影响 / TH0=0x00; /给定初值 / TL0=0x00; EA=1; /总
18、中断打开 ET0=1; /定时器中断打开 TR0=1; /定时器开关打开/*void Outside_Init(void)/开外部中断0EX0 = 1; /开外部中断0/EX1 = 1;IT0 = 1; /负边沿触发/IT1 =1; EA = 1; /开总中断*/*- 定时器中断子程序-*/void Timer0_isr(void) interrupt 1 static unsigned int num; TH0=(65536-2000)/256; /重新赋值 2ms TL0=(65536-2000)%256; Display(0,4); / 调用数码管扫描 num+; if(num=300)
19、 / num=0; ReadTempFlag=1; /读标志位置1二、语音录放芯片源程序(ISD1760.c):/*使用独立按键录音,根据所录秒数得到地址,使用放音函数进行放音*/ #include #include #include sbit SS = P13;sbit SCLK = P12 ; sbit MOSI = P11 ; sbit MISO = P10 ;uchar SR0_L; /存放读到的寄存器数据,下同uchar SR0_H; uchar SR1; uchar ID,APCL=0,APCH=0;/-/每2秒大约是8个十进制地址,即十六进制0x08,后一段声音越界/就只会播前段
20、声音的后面的一部分,遇到“EOM”停止,所根据录得/秒上述乘以8,转化成十六进制数,得到大概地址,后面进行微调/-uint caToneAdd=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,0x0
21、010+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;/摄氏度 void I_delay(void)NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP; NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;/-/MS级延时函数/-/-/MS级延时函数/-void Del
22、ay( uint z ) uint x,y;for ( x = z; x 0; x- ) for ( y = 110; y 0; y- );/* *函数名: void ISD_Init(void); *初始化:包括了复位、上电、读状态、清除中断、设置APC2、读APC等子函数*/ void ISD_Init(void) ISD_Reset(); do ISD_PU(); RdStatus();while(SR0_L&0x01)|(!(SR1&0x01);/if(SR0_L0=1)system Err ClrInt();RD_DevID();ISD_WR_APC2( ); RdAPC(); /-
23、/ 函数名: SPISendData( )/ SPI传输数据(发送数据)子程序/-uchar SPISendData(uchar BUF_ISD) uchar i,dat=BUF_ISD; SCLK=1; SS=0; /拉低准备/Delay(5);for(i=0;i=1; if(MISO) dat|=0x80; SCLK=1; I_delay(); MOSI=0; / SS=1; return(dat); /* * 函数名: void RdStatus(void); * 读状态*/ void RdStatus(void) /SS=0;/Delay(10);SPISendData(RD_STAT
24、US); /向ISD1760发送命令读寄存器状态SPISendData(0x00);/数据字节1SPISendData(0x00);/起始地址字节1SS=1;/发送数据Delay(10);/延时10MS /SS=0;/Delay(10);SR0_L =SPISendData(RD_STATUS);/存储状态寄存器的数据SR0_H =SPISendData(0x00); SR1 =SPISendData(0x00); SS=1; Delay(10); /* * 函数名: void ClrInt(void); * 清除中断*/ void ClrInt(void) /SS=0;/Delay(10);
25、SPISendData(CLI_INT);/原理同上SPISendData(0x00); SS=1; Delay(10); /* * 函数名: void ISD_WR_NVCFG(void); * 永久写入寄存器*/ void ISD_WR_NVCFG(void) /SS=0;/Delay(10);SPISendData(WR_NVCFG); SPISendData(0x00); SS=1; Delay(10); /* *函数名: void ISD_WR_APC2(uchar voiceValue); *设置APC2*/ void ISD_WR_APC2(void) /SS=0;/Delay(
26、10);SPISendData(WR_APC2); /SPISendData(0xa8); /0XA8声音最大,0xaf声音最小,0xa0去掉了录音时的监听 /SPISendData(0x0c); /D11=1,在SETPLAY模式下,执行到EOM自动结束。或者在连续两个/SET_PLAY命令后,执行到第一个EOM自动跳到第二段开始 SPISendData(0x40); /同上,数据字节1D7:D0,MIC录音 SPISendData(0x08); /数据字节2 SS=1; Delay(10); ISD_WR_NVCFG(); /永久写入寄存器 /* *函数名: void RD_APC(voi
27、d); *读取APC*/ void RdAPC(void) /SS=0;/Delay(10);SPISendData(RD_APC); SPISendData(0x00); SPISendData(0x00); SPISendData(0x00); SS=1; Delay(10);/SS=0;/Delay(10); SR0_L =SPISendData(RD_APC);/同样用来存储所读到的数据SR0_H =SPISendData(0x00); APCL =SPISendData(0x00); APCH =SPISendData(0x00); SS=1; Delay(10); /* *函数名:
28、 void ISD_CHK_MEM(void);*空间检测:检查环状存储体系* void ISD_CHK_MEM(void) SS=0;Delay(10);SPISendData(CHK_MEM); SPISendData(0x00); SS=1; Delay(10); * *函数名: void ISD_Reset(void); *复位函数*/ void ISD_Reset(void) /SS=0;/Delay(10);SPISendData(RESET); SPISendData(0x00); SS=1;Delay(50);/延时50ms /* *函数名: void ISD_Stop(voi
29、d); *停止当前操作 * void ISD_Stop(void) /SS=0;/Delay(10);SPISendData(STOP); SPISendData(0x00); SS=1; Delay(50); /* *函数名: void ISD_PU(void); *上电*/ void ISD_PU(void) /SS=0;/Delay(10);SPISendData(PU); SPISendData(0x00); SS=1; Delay(50); /* *函数名: void ISD_PD(void); *掉电 *void ISD_PD(void) SPISendData(PD); SPIS
30、endData(0x00); SS=1; Delay(10); /* *函数名: void RdStatus(void); *读取ID,应该相当于片选什么的?*/ uchar RD_DevID(void) /SS=0;/Delay(10);SPISendData(RD_DEVID); SPISendData(0x00); SPISendData(0x00); SS=1; Delay(10); /SS=0;/Delay(10); SR0_L =SPISendData(RD_DEVID); SR0_H =SPISendData(0x00); ID =SPISendData(0x00); SS=1; Delay(10); return(ID); /* *函数名: void GetToneAdd(uchar cNum, Uint * ipStartAdd, Uint * ipEndAdd); *取当前语音的首末地址*/ void GetToneAdd(uchar cNum, uint * ipStartAdd, uint * ipEndAdd) *ipStartAdd=caToneAddcNum*2; *ipEndAdd=caToneAddcNum*2+1; /* *函数名: void SetPLAY(uchar cNum); *定点播放 *
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100