资源描述
第 1 页 共 59 页 目 录 引言 .1 1 设计内容及要求 .2 1.1 设计内容 .2 1.2 设计要求 .2 2 方案设计与选取 .2 2.1 方案设计 .2 2.2 方案选取 .3 3 硬件部分 .3 3.1 电源部分 .3 3.2 温度采集部分.4 3.3 键盘部分 .12 3.4 核心控制部分.13 3.5 显示部分 .17 3.6 扬声器部分 .21 4 软件部分 .21 4.1 软件设计需要完成的任务 .21 4.2 软件设计要点.22 4.3 凌阳音频压缩算法 .22 4.4 程序流程图 .26 4.4.1 系统程序流程图.26 4.4.2DS18B20 程序流程图 .27 4.4.3LCD1602 程序流程图 .27 4.4.4 语音播放程序流程图 .28 5 系统测试 .28 5.1 SPCE061A 简易开发板的测试 .28 5.2 电源部分测试.29 5.3 键盘部分测试.29 5.4 液晶显示部分测试 .29 6 调试总结 .30 6.1 硬件部分调试.30 6.2 软件部分调试.30 第 2 页 共 59 页 7 总结 .31 谢 辞 .32 参考文献: .33 附 录 1.34 附 录 2.53 附 录 3.57 第 4 页 共 58 页 4 引言 在日常生活中,我们一般采用温度计对环境温度进行测量。而在某些特殊领域, 比如工业、医疗等,我们要采用温度传感器等来测量。在传统的模拟信号远距离温度 测量系统中,需要很好的解决引线误差补偿问题、多点测量切换误差问题和放大电路 零点漂移误差问题等技术问题,才能够达到较高的测量精度。另外一般监控现场的电 磁环境都非常恶劣,各种干扰信号较强,模拟温度信号容易受到干扰而产生测量误差, 影响测量精度。因此,在温度测量系统中,采用抗干扰能力强的新型数字温度传感器 是解决这些问题的最有效方案,新型数字温度传感器 DS18B20 具有体积更小、精度更 高、适用电压更宽、采用一线总线、可组网等优点,在实际应用中取得了良好的测温 效果。 随着微电子技术的迅速发展,目前各公司研制出了试用于各种应用领域的单片机。 高性能单片机芯片市场也异常活跃,不断采用新技术,使单片机的种类、性能不断提 高,应用领域不断扩大。SPCE061A 型单片机是凌阳科技公司推出的一款 16 位微处理 器,具有体积小,集成度高,易扩展,可靠性高、功耗低、结构简单、中断处理能力 强等特点,内嵌 32K 字闪存 FLASH,2K 字(Word)SRAM,内置十位 ADC、DAC,有多达 十四个的中断源等丰富的片内资源,处理速度高,能够很方便地完成普通单片机的功 能,尤其适用于数字语音播报和识别应用领域,是数字语音识别与语音信号处理的理 想产品,在数字语音播报和识别应用领域得到了广泛的应用。本方案使用具有语音处 理功能的凌阳 16 位单片机 SPCE061A,充分发挥 SPCE061A 语音处理能力,再配合 1602 液晶显示器等来实现语音温度计系统的设计。 第 5 页 共 58 页 5 1 设计内容及要求 1.1 设计内容 结合生产实际,在洗衣机,空调等家用电器的设计当中,大都采用了温度报警技术。 课题要解决对外界环境的温度采集,用单片机来实现对所测温度结果的分析,对 所测温度进行显示,且能语音报告。用户可自行设定报警的温度限,通过按键控制可 对它进行加、减设置,随时可以改变报警的温度设限值。 1.2 设计要求 1.熟练掌握 Protel 的使用方法。 2.使用单片机等器件设计电路。 3.掌握数字电路、接口电路的设计方法。 4.可通过按键来设定并控制温度。 5.温度测量范围为:099C 摄氏度 2 方案设计与选取 2.1 方案设计 方案一:语音温度计采用AT89S51 单片机作为控制核心,对温度传感器DS18B20 控制,读取温度信号并进行计算处理,分析并作出是否进行报警的判断,如果超过报 警温度限则用扬声器报警。控制语音芯片例如ISD1420 或者ISD1760等语音专用芯片实 现语音的录放,使用按键实时播报温度和对报警温度的调整,并送入液晶显示器1602 显示。方案一的系统设计框图如图所示: 第 6 页 共 58 页 6 语音模块:包 括录音和放音 部分) 电源电路 键盘电路 温度传感电路 路路路 液晶显示器 扬声器 51 系 列 单 片 机 方案二:语音温度计采 用 SPCE061A 单片机作 为控制核心,对温度传感器 DS18B20 控制,读取温度信号并进行计算处理,分析并作 出是否进行报警的判断,如果超过报警温度限则用扬声器报警。但是不同的是语音方 面使用 SPCE061A 单片机自身带有的语音录放音功能,使用按键实时播报温度和对报警 温度的调整,并送入液晶显示器 1602 显示。方案二的系统设计框图如图所示: 2.2 方案选取 方案一中使用的是 51 系列单片机作为控制器,但是 51 系列单片机不具备处理语 音信号的能力,还需要加上具有语音处理功能的专用编码和解码芯片才能够完成语音 信号的数字化处理。而方案二使用的是 SPCE061A 作为控制器的,而 SPCE061A 自身是 一款具有语音功能的 16 位单片机,而且 SPCE061A 还配有专用的语音压缩函数,只需 要扩展少部份外围电路就能完成语音信号的数字化处理。因此本系统采用方案二来实 现语音温度计的设计。 电源电路 键盘电路 温度传感电路 路路路 液晶显示器 扬声器 SPCE061A 单 片 机 图 2.2 方案二系统设计框图 图 2.1 方案一的系统设计框图 第 7 页 共 58 页 7 3 硬件部分 3.1 电源部分 如图所示电路为输出电压+5V、输出电流 1.5A 的稳压电源。它由电源变压器 B,桥 式整流电路 D1D4,滤波电容 C1、C3,防止自激电容 C2、C4 和一只固定式三端稳压 器(7805)极为简捷方便地搭成的。 220V 交流电通过电源变压器变换为交流低压,再经过桥式整流电路 D1D4 和滤波 电容 C1 的整流和滤波,在固定式三端稳压器 LM7805 的 Vin 和 GND 两端形成一个并不 十分稳定的直流电压(该电压常常会因为市电电压的波动或负载的变化等原因而发生变 化)。此直流电压经过 LM7805 的稳压和 C3 的滤波便在稳压电源的输出端产生了精度高、 稳定度好的直流输出电压。LM7805 是常用的三端稳压器,一般使用的是 TO-220 封装, 能提供 DC 5V 的输出电压,应用范围广,内含过流和过载保护电路。带散热片时能持 续提供 1A 的电流,如果使用外围器件,它还能提供不同的电压和电流。 本稳压电源可作为单片机电路的电源。三端稳压器是一种标准化、系列化的通用 线性稳压电源集成电路,以其体积小、成本低、性能好、工作可靠性高、使用简捷方 便等特点,成为目前稳压电源中应用最为广泛的一种单片式集成稳压器件。 桥式整流是对二极管半波整流的一种改进。半波整流利用二极管单向导通特性, 在输入为标准正弦波的情况下,输出获得正弦波的正半部分,负半部分则损失掉。桥 式整流器利用四个二极管,两两对接。输入正弦波的正半部分是两只二极管导通,得 到正的输出;输入正弦波的负半轴部分时,另两只管导通,由于这两只二极管是反接 的,所以输出还是得到正弦波的正半部分。桥式整流器对输入正弦波的利用效率比半 波整流高一倍。桥式整流是交流电转换成直流电的第一个步骤。 桥式整流电路的整流效率和直流输出与全波整流电路相同,变压器的利用率最高。 现在常用的全桥整流,不用单独的四只二极管而用一只全桥,其中包括四只二极管, 但是要标清符号,有交流符号的两端接变压器输出,+、-两端接入整流电路。 图 3.1 LM7805 构成的 5V 稳压电源图 第 8 页 共 58 页 8 需要特别指出的是,二极管作为整流元件,要根据不同的整流方式和负载大小加 以选择。如选择不当,则或者不能安全工作,甚至烧了管子;或者大材小用,造成浪 费。 78 系列在降压电路中应注意以下事项: 1、输入输出压差不能太大,太大则转换效率急速降低,而且容易击穿损坏; 2、输出电流不能太大,1.5A 是其极限值。大电流的输出,散热片的尺寸要足够大, 否则会导致高温保护或热击穿; 3、输入输出压差也不能太小,太小效率很差。 3.2 温度采集部分 数字温度传感器 DS18B20 测量温度,直接输出数字信号。便于单片机处理及控制, 节省硬件电路。且该芯片的物理化学性稳定,此元件线形性能好,在 0100时,最 大线形偏差小于 1 摄氏度。DS18B20 的最大特点之一采用了单总线的数据传输,由数字 温度计 DS18B20 和 SPCE061A 构成的温度测量装置,它直接输出温度的数字信号到微控 制器。每只 DS18B20 具有一个独有的不可修改的 64 位序列号,根据序列号可访问不同 的器件。这样一条总线上可以挂接多个 DS18B20 传感器,实现多点温度测量,轻松的 组建传感网络。DS18B20 温度传感器是美国 DALLAS 半导体公司最新推出的一种改进型 智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且 可根据实际要求通过简单的编程实现 912 位的数字值读数方式。 DS18B20 的主要特点: (1)适应电压范围更宽,电压范围:3.05.5V,在寄生电源方式下可由数据线供电 (2)独特的单线接口方式,DS18B20 在与微处理器连接时仅需要一条口线即可实现微 处理器与 DS18B20 的双向通讯 (3)DS18B20 支持多点组网功能,多个 DS18B20 可以并联在唯一的三线上,实现组网 多点测温 (4)DS18B20 在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一 只三极管的集成电路内 (5)温度范围55125,在-10+85时精度为0.5 (6)可编程的分辨率为 912 位,对应的可分辨温度分别为 0.5、0.25、0.125 和 0.0625,可实现高精度测温 (7)在 9 位分辨率时最多在 93.75ms 内把温度转换为数字,12 位分辨率时最多在 750ms 内把温度值转换为数字,速度更快 (8)测量结果直接输出数字温度信号,以一线总线串行传送给 CPU,同时可传送 CRC 校验码,具有极强的抗干扰纠错能力 第 9 页 共 58 页 9 (9)负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。 DS18B20 内部结构主要由四部分组成:64 位光刻 ROM、温度传感器、非挥发的温度 报警触发器 TH 和 TL、配置寄存器。 DS18B20 引脚定义: (1)DQ 为数字信号输入/输出端; (2)GND 为电源地; (3)VDD 为外接供电电源输入端(在寄生电源接线方式时接地) 。 ( 1) 64 位 ROM 的结构如下: 开始 8 位是产品类型的编号, 接着是每个器件的惟一的序号 , 共有 48 位, 最后 8 位是前 56 位的 CRC 校验码, 这也是多个 DS18B20 可以采用一线进行通信的原因。 ( 2) 非易失性温度报警触发器 TH 和 TL, 可通过软件写入用户报警上下限。 ( 3) 高速暂存存储器。DS18B20 温度传感器的内部存储器包括一个高速暂存 RAM 和一个非易失性的可电擦除的 EP2RAM。后者用于存储 TH, TL 值。数据先写入 RAM, 经 校验后再传给 EP2RAM。而配置寄存器为高速暂存器中的第 5 个字节,他的内容用于确定 温度值的数字转换分辨率, DS18B20 工作时按此寄存器中的分辨率将温度转换为相应精 度的数值。该字节各位的定义如下: 后 5 位一直都是 1, TM 是测试模式位, 用于设置 DS18B20 在工作模式还是在测试 模式, 在 DS18B20 出厂时该位被设置为 0,用户不要去改动, R1 和 R0 决定温度转换的 图 3.2 DS18B20 内部结构图 表 3.1 64 位 ROM 的结构 表 3.2 字节各位的定义 第 10 页 共 58 页 10 精度位数, 即是来设置分辨率, 如表所示(DS18B20 出厂时被设置为 12 位) : 由表可见, 设定的分辨率越高, 所需要的温度数据转换时间就越长。因此, 在实 际应用中要在分辨率和转换时间两者之间进行权衡考虑。 高速暂存存储器除了配置寄存器外, 还有其它 8 个字节组成, 其分配如下所示。 其中温度信息( 第 1, 2 字节) 、TH 和 TL 值第 3, 4 字节、第 68 字节未用, 表现为 全逻辑 1; 第 9 字节读出的是前面所有 8 个字节的 CRC 码, 可用来保证通信正确。 当 DS18B20 接收到温度转换命令后, 开始启动转换。转换完成后的温度值就以 16 位带符号扩展的二进制补码形式存储在高速暂存存储器的第 1, 2 字节。单片机可通过 单线接口读到该数据, 读取时低位在前, 高位在后, 数据格式以 0.0625 /LSB 形式 表示。温度值格式如下: 表 3.3 R1 和 R0 模式表 表 3.4 寄存器字节分配 表 3.5 DS18B20 温度数据表 第 11 页 共 58 页 11 DS18B20 完成温度转换后, 就把测得的温度值与 TH, TL 作比较, 若 TTH 或 TS480S240。 (1)波形编码:sub-band 即 SACM-A2000 特点:高质量、高码率,适于高保真语音音乐。 (2)参数编码:声码器(vocoder)模型表达,抽取参数激励信号进行编码。线性 预测编码 (LPC)即 SACM-S240。 特点:压缩比大,计算量大,音质不高,廉价! (3)混合编码:CELP 即 SACM-S480 特点:综合参数和波形编码之优点。 除此之外,还具有 FM 音乐合成方式即 SACM-MS01SACM_DVR 是凌阳公司建立的语 音函数库中的一个应用程序接口函数中的一个库函数,本设计就是以这个函数为核心 进行语音的处理的。由于麦克风输入生成的 WAVE 文件占用的存储空间较大,对于单片 机来说想要存储大量的信息显然是不现实的,凌阳公司提出了解决的方法, 即建立 SACM-LIB 库及相应的应用程序接 API(Application ProgrammingInterface)函数,将 语音处理需要的 A/D,编码、解码、存储及 D/A 作为相应的模块,对于每个模块都有其 应用程序接口 API,只需要了每个模块所要实现的功能及其参数的内容,然后调用该 API 函数既可实现该功能。SACM_DVR(A2000)的数据压缩率是 16K/S,采样率是 8KHz,采 样速率是 16/KHz。 相关 API 函数如下: int SACM_DVR_Initial(int Init_Index) /初始化 void SACM_DVR_ServiceLoop(void) /获取资料,填入译码队列 void SACM_DVR_Encode(void) /录音 SACM_DVR_StopEncoder(); /停止编码 SACM_DVR_InitEncoder(RceMonitorOn) /初始化编码器 void SACM_DVR_Stop(void) /停止录音 void SACM_DVR_Play(void) /开始播放 第 27 页 共 58 页 27 unsigned int SACM_DVR _Status(void) /获取 SACM_DVR 模块的状态 void SACM_DVR _InitDecoder(int Channel) /开始译码 void SACM_DVR _Decode(void) /获取语音资料并译码,中断播放 SACM_DVR_StopDecoder(); /停止解码 unsigned int SACM_DVR _ TestQueue(void) /获取语音队列状态 int SACM_DVR _Fetchqueue(void) /获取录音编码数据 void SACM_DVR_FillQueue(unsigned int encoded_data) /填充资料到语音队列, 等待播放 int GetResource(long Address) (Manual) / 从资源文件里获取一个字型 语音资料 中断服务函数: Call F_FIQ_Service_ SACM_DVR /playing Call F_IRQ1_Service_ SACM_DVR /recode 具体函数如下: (1) int SACM_DVR_Initial(int Init_Index) 调用方式:C:void SACM_ DVR _Initial(int Init_Index) ASM:R1= Init_Index Call F_ SACM_ DVR _Initial 功能说明:SACM_ DVR 语音播放之前的初始化:设置中断源、定时器以及播放方式 (自动) (2) void SACM_DVR_ServiceLoop(void) 调用方式: C:void SACM_DVR_ServiceLoop(void) ASM:Call F_ SACM_DVR _ServiceLoop 功能说明:在录音期间从 ADC 通道获取录音资料,且将其以 SACM_A2000 格式进行 编码后存入外接 SRAM 中;而在播放期间从 SRAM 中获取语音资料,对其进行解码,然 后等候中断服务子程序将其送出 DAC 通道。 (3) void SACM_DVR_Encode(void) /录音 调用方式:C:void SACM_DVR_Encode(void); ASM:Call F_ SACM_DVR_ Encode 功能说明:开始以自动方式录制声音资料到外接 SRAM 中。 备 注:该函数仅适用于 SACM_DVR 模块,且只有自动方式。 (4) void SACM_DVR_Stop(void) 调用方式:C:void SACM_DVR _Stop(void); ASM:Call F_ SACM_DVR _Stop 功能说明: 以自动方式停止录音。 第 28 页 共 58 页 28 (5)void SACM_DVR_Play(void) 调用方式:C:int SACM_DVR _Play(int Speech_Index, int Channel, int Ramp_Set); ASM:Call SACM_DVR _Play 功能说明:以自动方式播放外接 SRAM 中的录音资料。 (6)unsigned int SACM_DVR _Status(void) 调用方式 C:unsigned int SACM_DVR _Status(void); ASM:Call F_ SACM_DVR _ Status 功能说明:获取 SACM_DVR 模块的状态。 (7)void SACM_DVR _InitDecoder(int Channel) 调用方式:C:void SACM_DVR_InitDecoder(int Channel); ASM:Call F_SACM_DVR_Decode 功能说明:开始对 SACM_DVR 语音资料以非自动方式(编程控制)进行译码。 参 数:Channel=1,2,3;分别表示使用 DAC1、DAC2 通道以及 DAC1 和 DAC2 双通 道。 (8)void SACM_DVR_Decode(void) 调用方式:C:void SACM_DVR_Decode(void); ASM:Call F_ SACM_DVR_Decode 功能说明:从语音队列里获取的 SACM_DVR 语音资料,并进行译码,然后通过中断 服务子程序将其送入 DAC 通道播放。 (9) unsigned int SACM_DVR_TestQueue(void) 调用方式:C:unsigned int SACM_DVR_TestQueue(void); ASM:Call F_SACM_DVR_TestQueue 功能说明:获取语音队列的状态。 返 回 值:R1=0,语音队列不空不满 =1,语音队列满 =2;语音队列空。 (10) int SACM_DVR _FetchQueue(void) 调用方式:C:int SACM_DVR _FetchQueue(void); ASM:Call F_SACM_DVR _FetchQueue Return_Value=R1 功能说明:获取录音编码(SACM_A2000)数据。 返 回 值:16 位录音资料。 (11)void SACM_DVR _FillQueue(unsigned int encoded-data) 调用方式:C:void SACM_DVR _FillQueue(unsigned int encoded-data); 第 29 页 共 58 页 29 ASM:R1=语音编码资料 Call F_ SACM_DVR _FillQueue 功能说明: 填充 SACM_A2000 语音资料到 DVR 译码器等待播放 参 数:encoded-data 为语音编码资料。 返 回 值:无。 备 注 : 从语音队列里至少每 48ms 获取 48 个字资料( 16K 资料率) 。 仅用 于非自动方式下。 (12)F_FIQ_Service_ SACM_DVR 调用方式:ASM:Call F_FIQ_Service_ SACM_DVR ASM:Call F_IRQ1_Service_SACM_DVR 功能说明: 用作 SACM_DVR 语音背景程序的中断服务子程序。通过前台子程序 (自动方式的 SACM_DVR _ServiceLoop 及手动方式的 SACM_DVR _Decode)对语音资料 进行译码,然后将其送入 DAC 通道播放。即 FIQ 中断服务子程序用于声音播放的背景 程序;而 IRQ1 中断服务子程序则用于声音录制的背景程序。 备 注:SACM_DVR 语音背景子程序只有汇编指令形式,且应将此子程序安置在 TMA_FIQ 中断源上。额外的中断服务子程序安置在 IRQ1_TMA 中断源上。 第 30 页 共 58 页 30 4.4 程序流程图 4.4.1 系统程序流程图 Y 开始 扫描按键 读出掉电前设定的温度 刷新显示 初始化 读取 18B20 温度 温度是否超过设定值 报警 是否有键按下 Y 分析按键 执行相关操作 设 定 温 度 语 音 播 报 N N 4.4.2DS18B20 程序流程图 显示当前温度 开始 DS18B20 初始化 单片机开始对 DS18B20 先写读操作 图 4.1 本系统的程序流程图 第 31 页 共 58 页 31 4.4.3LCD1602 程序流程图 N Y 液晶初始化 对液晶写操作 液晶显示所接收的数据 液晶是否处 于忙状态 对液晶读操作 开始 图 4.2 DS18B20 运行程序流程图 图 4.3 LCD1602 程序流程图 第 32 页 共 58 页 32 4.4.4 语音播放程序流程图 5 系统测试 5.1 SPCE061A 简易开发板的测试 使用的 61 开发板 DEMO1 自检程序进行自检,这些自检程序是由淩阳公司提供的, 相对操作起来比较简单。具体步骤如下: 第一步:接上电源,可以连接 2 节或 3 节电池,也可以直接接 5V 的稳压源: 第二步:用连线分别将 I/OA 口的低 8 位和 IOB 口的低 8 位相连,IOA 口的高 8 位 和 IOB 口的高 8 位相连,然后按下 REST 复位键; 现象:当按下复位键后,程序开始执行,语音提示“欢迎进入自检模式” ,当听到 语音:“I/O 测试成功”后,进行第三步操作; 第三步:按 K1 键进行睡眠功能测试: 现象:如果测试成功,会看到绿色的发光二极管亮灭一下,并有语音提示“睡眠 测试成功” ,否则提示“睡眠测试失败” ,然后进行第四步操作; 第四步:按下 K2 键进行 A/D 转换的测试: 图 4.4 SACM_S480 播放语音流 程图 第 33 页 共 58 页 33 现象:语音提示:“A/D 测试成功” ,否则提示“A/D 测试失败” ,进入最后一步 操作; 第五步:拔掉第一步测试时的连接线,并按下 K3 键测试 MIC 输入及 D/A 转换输出 是否正常; 现象:可以在 MIC 上轻轻的拍几下,同时听是否有声音输出,如果有,则说明 MIC 输入和 D/A 转换输出部分正常。 在测试过程中,若有问题则下一步就不能进行,根据停止的那一步就去检查对应 的电路,可以很快的查出并解决。如果 61 开发板可以通过以上测试,说明开发板工作 正常。 5.2 电源部分测试 把插头接入 220V 交流电,经过 9V 变压器后,再经过 7805 稳压后,测得为单片机 供电的电源部分输出为 5.02V,而且比较稳定。 5.3 键盘部分测试 键盘电路的测试主要是利用单片机和万用表测试,单片机控制输出的 I/O 口中接 矩阵键盘横向的设置高电平,接矩阵的纵向的 I/O 口接高电平。万用表调到短路报警 档,分别按下按键。如果可以正常使用,这时万用表就会发出长鸣“滴”声的短路报 警声。全部通过测试后,即可确认键盘测试成功,则可以完成本设计中的工作。 5.4 液晶显示部分测试 把液晶模组1602和SPCE061A的I/O口一一对应连接好后,下载测试程序到SPCE061A 中,下载完毕后按复位键开始测试,会有一个语音提示“LCD测试开始”,然后LCD先 满屏显示以确认屏幕没有坏点,然后在显示各种字符和图形,通过测试后会有语音提 示“LCD”测试成功。 6 调试总结 6.1 硬件部分调试 硬件部分调试:我的硬件部分调试相对比较简单,因为使用了凌阳61简易小系统 板,凌阳公司提供了小系统的自检程序。键盘的调试也比较简单,在电源的调试时, 由于自己没有注意,把LM7805的管脚次序弄错了,使得经过LM7805后没有得到5V,经 过仔细检查以后才发现问题。解决完电源的问题,我的硬件电路部分调试也就结束了。 第 34 页 共 58 页 34 6.2 软件部分调试 本系统的软件部分调试的步骤应先把LCD1602调试出来,这样调DS18B20才方便, 可以通过液晶显示的信息判断温度传感器DS18B20的处理是否正确。首先是得把1602的 资料通读几遍,可还是没有什么头绪,就试这把每个脚的功能写在纸上,方便查阅。 通过看资料上的汇编程序,了解程序的思路,试着自己编程,把RS,R/W,E都设置为 有效后,1602还是一点反应都没有,后来才发现,还要对1602进行初始化,即是清除 显示,在资料写入或读取时,光标的移动方向,打开显示等一系列步骤。还有比较重 要要注意的是当模块在接受指令前,微处理器必须先确认模块内部处于非忙碌状态, 才可接受新的指令;如果在送出一个指令前并不检查忙碌状态标志,那么在前一个指 令和这个指令中间必须延迟一段较长的时间,等待前一个指令确实执行完成。调了两 天之后,终于可以看到1602稳定的显示了。 第二个步骤就是要把DS18B20的温度读取部分调试出来,这一部分的程序相对 来说比较困难,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法 读取测温结果。较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理 器间采用串行数据传送。在DS1820测温程序设计中,向DS1820发出温度转换命令后, 程序总要等待DS1820的返回信号,一旦某个DS1820接触不好或断线,当程序读该 DS1820时,将没有返回信号,程序容易进入死循环。经过认真的阅读资料和反复的调 试之后,才准确的读出了温度。 语音处理功能主要是利用凌阳16 位单片机SPCE061A实现,调用其内部的函数即可 实现语音的播放。 最后再经过对键盘功能调试和整体调试,即完成了本次系统功能的实现。 7 总结 经过一个学期的毕业设计制作,终于完成了。实现了一个具有可调节报警温度功 能的语音温度计,比较圆满的完成了设计的任务。 首先就是要考虑在此设计方案的可行性,有些方案只能是停留在理论层,但可操 作性很差,一定要进行可行性分析。对比几个方案,要找出最佳的实现功能的方案。 大学就要结束了,这是我们在大学的最后一个作品。在本次毕业设计中,几经周 折我的作品在规定时间内完成了,虽然作品效果和工艺还不是十分理想,但是这是我 亲自动手设计和制作的。我还是很有成就感的,在制作过程中我遇到了不少问题,得 到了老师和同学们的帮助和指点,使我得到了很大的鼓舞,问题都能很好解决,真是 不胜感激,他们的每一个看起还微不足道的帮助,都是我这次毕业作品成功的基石。 第 35 页 共 58 页 35 都是有他们热心的帮助我才得以成功,我衷心的感谢。 在取得成绩的同时,我也感受到了一定的压力和不足。这主要是由于平时学习不 够扎实,不够全面,分析问题、解决问题的能力不足。本来还想增加人体识别模块, 在有人靠近的时候实现语音报温,使系统更加智能化和人性化。但是由于时间和本身 知识水平的有限,最终没能实现。我认为毕业设计最大的体会是提高了自己独立查找 资料的能力和从资料中取出有用的东西来设计电路的能力。因此,这次的毕业设计不 仅使我学到了更多的知识,也使我学会更好地处理遇到的问题。 本次的毕业设计既是一次对我们电子类知识的一次检验,也是我们从理论到实践 的一次考验。在此过程当中,既有成功的喜悦,也有失败的经历。或许更多的是对自 己的不足有了深刻的认识,发现许多不足是经实践检验出来的。 第 36 页 共 58 页 36 谢 辞 首先深深的感谢熊发明老师在本设计期间给予的悉心的指导和精心的培养。老师渊 博的知识及严谨的治学态度令我钦佩,同时为我提供了良好的条件,使我极其顺利的 完成了毕业设计。在老师那里不仅学到了知识,而且学会了研究的方法,这些都使我 受益匪浅。在此特向给予我帮助的所有人表示诚挚的谢意。可能还有许多不尽如人意 的地方,希望能够得到老师和同学们的批评和指导意见。 在此也深深感谢大学四年教过我,带过我的老师们,他们交给了我丰富的知识及为 人做事的道理,也感谢那些默默的关心和帮助我的同学,使我能顺利的完成毕业设计。 第 37 页 共 58 页 37 参考文献: 1 高海生. 最新电子元器件应用技术M. 南昌: 江西科技大学出版,2004. 2 李晶皎. 嵌入式语音技术及凌阳 16 位单片机应用.北京. 北京航空航天大学出版社,2003 3 罗万钧 田立炎 冯子纲. 汇编语言程序设计.西安. 西安电子科技大学出版社,2001 4 罗亚飞.凌阳十六位单片机应用基础.北京. 北京航空航天大学出版社,2003 5 唐家玉 郑大宇.单片机原理及接口技术.哈尔滨.哈尔滨工业大学出版社,2003 6 朱定华.单片机原理及接口技术第一版M. 北京:电子工业出版社,2003. 7 谭浩强.C 程序设计.北京.清华大学出版社,1999 8 李维言 郭强. 液晶显示应用技术.北京. 电子工业出版社,2003 9 姚天任.数字语音处理M.武汉:华中科技大学出版社,2001:1536. 10 薛钧义.张彦斌.凌阳 16 位单片机原理及应用M.北京:北京航空航天大学出版社,2003. 第 38 页 共 58 页 38 附 录 1 / /= /=语音温度计= /作者:蒋立城 /2008.5.10 #include bsrsd.h #include 1602.H #include DS18B20.h /= /用于写入 FLASH 时用到的全局变量 extern unsigned int BSR_SDModel100; unsigned int commandID; /用来写命令进 FLASH 时用的 unsigned int g_Ret; int temp; int time_count=0; /用于定时 int time_count2=0; int blink=0;/用于实现输入跟踪 int Reset_bit=0;/ 重设表标,1 表示重设, int hour=0; int minite=0; int seconde=0; /= int Set_tempeliy4=0,0,0,0;/用来存放设定值的 /.全程变量. int gActivated = 0; /用于检测是否有触发命令,当有识别出语句为触发名称则该 位置 1 extern void ClearWatchDog(); int PlayFlag = 0; / 0-播放 S480 格式 1-播放 A2000 格式 /= /LCD 相关 unsigned char Show_error16= - warning - ; unsigned char Show_Set16 = S:35.00 : : ; /第一行 unsigned char Show_temreal16=Real: C ;/第二行 unsigned char tab10=0,1,2,3,4,5,6,7,8,9; /为了提 取数字的 ASCII 码 /- /按键相关 int Key; int Setnew_bit=0; /设新温度时的标志 第 39 页 共 58 页 39 /= /子程序定义 void delay(void); void delay_10us(unsigned char x); void delay_ms(unsigned char cnt) ; void Show(void); /总体显示程序 void PlayRespond2(int Result);/名称:放 A2000 格式子程序- - void PlayRespond(int Result);/放音 S480 子程序 void Key_Use(void);/-键盘子程序- /把读到的温度转为摄氏度 int translate(unsigned int uiData); void Error(void); /报错 在密码输入不正确时的处理 void Pass(void); /报对 在密码输入正确时的处理 void write_to_flash(int tp,int addr); /把设定的值存入 flash 中,做到掉电后 下次开机还有 void Read_Set(int addr,int *sep); /读出 flash 中的原设定 PPM 值 int main() int *p,BS_Flag=0,ulAddr,res,Ret,jk,k,i; /写 FLASH 时用到的变量 unsigned int temp1=0,temp2=0; *P_SystemClock = 0 x0018; /初始化,调整系统时钟 24.576MHz/1, 强振模式 *P_IOA_Dir=0 x0f00; /IOA0IOA7 初始化为输出 *P_IOA_Attrib=0 x0f00; *P_IOA_Data=0 x0f00; *P_IOB_Dir=0 xffff; *P_IOB_Attrib=0 xffff; *P_IOB_Data=0 x7fff; init_LCD(); Read_Set(0 xfa00,Show_Set); _asm(IRQ ON); PlayRespond(11); PlayRespond(11); while(1) ClearWatchDog(); Key_Use(); Show(); if(seconde=60) 第 40 页 共 58 页 40 seconde=0; minite+; if(minite=60) minite=0; hour+; if(hour=24) hour=0; if(time_count=0) /1 秒钟进行一次温度读取, temp1=Read_Temp(); temp2=translate(temp1); if(Reset_bit=0) CompareT(temp2); Show_Set15=seconde%10+0; Show_Set14=seconde/10+0; Show_Set12=minite%10+0; Show_Set11=minite/10+0; Show_Set9=hour%10+0; Show_Set8=hour/10+0; /= /延时子程序 void delay(void) unsigned int i,j; for(i=100;i0;i-) for(j=50;j0;j-); /*delay_ms* void delay_10us(unsigned char x) while(x-) ClearWatchDog(); 第 41 页 共 58 页 41 void delay_ms(unsigned char cnt) unsigned char i; do i = 4; do delay_10us(39); while(-i); while(-cnt); /= void Show(void) /总体显示程序 if(Reset_bit=1) /设置温度的显示 display_1602(0 x80,Show_Set,16); /第一行显示“new password” wr_com(blink+2)+0 x80); /光标闪烁 blink 为要显示的位置 wr_com(0 x0f); delay_ms(100); else display_1602(0 x80,Show_Set,16); /第一行 /-键盘子程序- void Key_Use(void) unsigned int mid,mik,temp; int SetTem=0; temp=*P_IOA_Data; temp=temp *P_IOA_Data=temp|0 x0100; /相当于 P1_4=0; mik=*P_IOA_Data; mik=mik if(mik!=0) delay_ms(5); /延时 10MS mik=*P_IOA_Data; mik=mik if(mik!=0) 第 42 页 共 58 页 42 switch(mik) case 0 x1000:Key=3;break; case 0 x2000:Key=2;break; case 0 x4000:Key=1;break; case 0 x8000:Key=0;break; /0 default:break; while(mik!=0) mik=*P_IOA_Data; mik=mik ClearWatchDog(); if(Reset_bit=1) Show_Setblink+2=Key+0; blink+; /输入位数累加 temp=*P_IOA_Data; temp=temp *P_IOA_Data=temp|0 x0200; mik=*P_IOA_Data; mik=mik if(mik!=0) delay_ms(10); /延时 10MS mik=*P_IOA_Data; mik=mik if(mik!=0) switch(mik) case 0 x1000:Key=7; break; case 0 x2000:Key=6; break; case 0 x4000:Key=5; break; case 0 x8000:Key=4; break; default:break; while(mik!=0) mik=*P_IOA_Data; 第 43 页 共 58 页 43 mik=mik ClearWatchDog(); if(Reset_bit=1) Show_Setblink+2=Key+0; blink+; /输入位数累加 temp=*P_IOA_Data; temp=temp *P_IOA_Data=temp|0 x0400; mik=*P_IOA_Data; mik=mik if(mik!=0) delay_ms(10); /延时 10MS mik=*P_IOA_Data; mik=mik if(mik!=0) switch(mik) case 0 x1000:Key=11;blink=0; /重设温度- Reset_bit=1; wr_com(0 x01); /*清屏* break; case 0 x2000:Key=10; /语音播报 if(Show_temreal6-0)!=0) PlayRespond(Show_temreal6-0); /十位 PlayRespond(10); PlayRespond(Show_temreal7-0); /个位 PlayRespond(13); /点 PlayRespond(Show_temreal9-0); /十分 位 PlayRespond(Show_temreal10-0); /百分 位 PlayRespond(14); /摄氏度 break; /锁上门 case 0 x4000:Key=9; if(Reset_bit=1) 第 44 页 共 58 页 44 Show_Setblink+2=Key+0; blink+; /输入位数累加 break; case 0 x8000:Key=8; if(Reset_bit=1) Show_Setblink+2=Key+0; blink+; /输入位数累加 break; default:break; while(mik!=0) mik=*P_IOA_Data; mik=mik ClearWatchDog(); temp=*P_IOA_Data; temp=temp *P_IOA_Data=temp|0 x0800; mik=*P_IOA_Data; mik=mik if(mik!=0) delay_ms(10); /延时 10MS mik=*P_IOA_Data; mik=mik if(mik!=0) switch(mik) case 0 x1000:Key=15; /后退一位 if(Reset_bit=1) blink-; /后退一个 正常输入密码 if(blink=2)blink=1; Show_Setblink+2= ; break; 第 45 页 共 58 页 45 case 0 x2000:Key=14;Reset_bit=0; / 保存密码- break; case 0 x4000:Key=13; /storage(); break; case 0 x8000:Key=12; /-0-无输入状态 1-开始输入 2- break; default:break; while(mik!=0) mik=*P_IOA_Data; mik=mik ClearWatchDog(); /- if(blink=2) blink=3; Show_Setblink-1+2=.; if(blink4) /设完 Reset_bit=0; SetTem=(Show_Set2- 0)*1000+(Show_Set3-0)*100+(Show_Set5-0)*10+(Show_Set6-0); write_to_flash(SetTem,0 xfa00); /= /名称:放 A2000 格式子程序- /功能:放 A2000 格式的音频文件 /输入: void PlayRespond2(int Result) PlayFlag = 1; /0-S480 1-A2000 BSR_StopRecognizer(); /停止识别 SACM_A2000_Initial(1); SACM_A2000_Play(Result, 3, 3); while(SACM_A2000_Status() ClearWatchDog(); 第 46 页 共 58 页 46 SACM_A2000_Stop(); BSR_InitRecognizer(BSR_MIC); BSR_EnableCPUIndicator(); PlayFlag = 0; /0-S480 1-A2000 void PlayRespond(int Result)/放音子程序 PlayFlag = 0; BSR_StopRecognizer(); SACM_S480_Initial(1); SACM_S480_Play(Result, 3, 3); while(SACM_S480_Status() ClearWatchDog(); SACM_S480_Stop(); BSR_InitRecognizer(BSR_MIC); BSR_EnableCPUIndicator();/启动实时监控 void Error(void) /报错 / wr_com(0 x01); /*清屏* display_1602(0 x80,Show_error,16); /第一行 显示 PlayRespond(12); / delay_ms(100); /延时 10MS / delay_ms(100); /延时 10MS void write_to_flash(int tp,int addr1) /把设定的值存入 flash 中,做到掉电后 下次开机还有 unsigned char i; unsigned char addr=addr1; F_FlashErase(addr); F_FlashWrite1Word(addr,tp); /= /输入:addr 为要读的地址。sep 为读得的数,放到的数组 void Read_Set(int addr,int *sep) /读出 flash 中的原设定 PPM 值 char i; int *poin_set,temp; poin_set=addr; 第 47 页 共 58 页 47 temp=*poin_set; sep6=temp%10+0; /百分位 temp/=10; sep5=temp%10+0; /十分位 temp/=10; sep3=temp%10+0; /个位 temp/=10; sep2=temp+0; /十位 /= /函数:void IRQ5(void) /描述:IRQ5 中断入口程序 /参数:无 /返回:无 /注意:采用了 2Hz 中断 /= void IRQ5(void)_attribute_(ISR); void IRQ5(void) if(*P_INT_Ctrl time_count+; if(time_count=2) time_count=0; seconde+; /- /把读到的温度放到要显示缓存中 int translate(unsigned int uiData) int m; unsigned int uiInteger; /数据的整数部分 unsigned int uiDecimal; /数据的小数部分 unsigned int uiBai; /显示温度的百位 unsigned int uiShi; /显示温度的十位 unsigned int uiGe; /显示温度的个位 unsigned int uiShi_d; /显示温度的十分位 unsigned int uiBai_d; /显示温度的百分位 unsigned int uiQian_d; /显示温度的千分位 unsigned int uiResidue; /数据的余数,作除法 第 48 页 共 58 页 48 uiInteger = 0; uiDecimal = 0; if(uiData /转换为整数部分 if(uiData if(uiData if(uiData if(uiData if(uiData if(uiData if(uiData /转换为小数部分 if(uiData if(uiData if(uiData uiBai = uiInteger/100; /小数点前面部分 uiResidue = uiInteger%100; uiInteger = uiResidue; uiShi = uiInteger/10; uiResidue = uiInteger%10; uiGe = uiResidue; uiShi_d = uiDecimal/1000; /小数点后面部分 uiResidue = uiDecimal%1000; uiD
展开阅读全文