毕业论文_基于stc89c52单片机的家用红外遥控系统(编辑修改稿)内容摘要:

容,经验证完全满足要求。 由于本电路上电即可以使单片机复位,又具有电源开关,故省去了按键复位开关。 另外,由于本 设计 采用单片机内部存储器存储程序,故单片机的第 31 引脚( EA)接高电平,用来访问片内程序。 系统电源电路的设计 由于所选用单片 机为 5V 单片机,为得到较稳定的 5V 电压,本 设计 采用了L7805cv 三端集成稳压管。 输出电压 ,最大输入电压 35v,压差 35v 时工作在理想状态。 输出电 流可达 (需做好散热),同时 L7805cv 内部含有限流保护电路和过 热保护电路,防止负载过大温度过高烧坏器件。 本 设计 中 L7805cv的应用电路如图 219 所示。 图 219 L7805cv 稳压电路图 泰山学院本科毕业论文(设计) 15 3 软件开发平台及软件 开发环境介绍及程序总体结构 开发环境介绍 本 设计 采用 KEIL C51 集成开发环境,它具 良好用户 的界面,使用极为方便。 支持汇编语言, C 语言及其混合编程,能够兼容绝大多数 51 系列单片机的程序设计和仿真。 在本 设计 中,所有的程序采用 C 语言编写,最后把调试通过的程序编译成二进制文件并通过串口下载到目标板。 程序总体结构 由于整个系统涉及到的外设模块较多,故采用了多 文件模块化编程,这样大大提高了程序的可读性,也为以后可能遇到的程序移植和升级提供了方便。 整个设计 的程序结构如图 31 所示。 图 31 程序结构图 其中, 是 设计 主函数包含了各种外设的初始化及其功能函数的调用,、 、 、 分别为温度传感器、红外接收器、时钟芯片和液晶的驱动程序, 是用来定时、定温的功能模块。 DS18B20 温度程序模块 DS18B20 操作流程 使用 DS18B20 时首先应遵循图 28 所示的时序图,然后按照流程进行具体操作。 DS18B20 操作流程如图 32 所示。 泰山学院本科毕业论文(设计) 16 图 32 DS18B20 操作流程 DS18B20 重点 代码 及其分析 DS18B20 程序的核心部分是利用单片机读取芯片内部的温度值,其读函数如下, /********************************************************** *从 DS1820 中读出数据 **********************************************************/ uchar DS1820_RData() { uchar i,j,Tmep。 for(i=8。 i0。 i) { Tmep=1。 初始化 复位、发跳过 ROM 命令 发温度转换命令、等待 发读取温度命令 复位、发跳过 ROM 命令 调用显示函数 存储并转化数据 泰山学院本科毕业论文(设计) 17 DS1820_bit=0。 //低电平 ,产生读信号 for(j=2。 j0。 j)。 //延时 4us DS1820_bit=1。 //释放总线 ,准备读数据 for(j=4。 j0。 j)。 //延时 if(DS1820_bit==1) {Tmep|=0x80。 } for(j=30。 j0。 j)。 //延时 DS1820_bit=1。 //拉高数据线,准备读下一位 } return(Tmep)。 //返回数据 } 通过上面的读函数,温度值 被保存到 Tmep 变量内,接下来便可以按照一 定 的规则对 Tmep 的值进行转化,最后显示在液晶屏上。 另外,应当注意在每次获取温度值时都要对 DS18B20 进行复位操作。 DS1302 时间程序模块 DS1302 总体操作及基本读写功能函数 本设计中 DS1302 操作主要包括读取内部时间值和修改时间值两部分, DS1302模块 总体操作如图 33 所示。 图 33 DS1302 操作总流程 泰山学院本科毕业论文(设计) 18 DS1302 读写操作流程如图 34 所示。 图 34 DS1302 读写操作流程 在对 DS1302 操作时,只要调用 Write1302_Cmd_Dat(),和 Read1302()就可以实现其与单片机之间的数据交流。 下面是读写函数的实现。 /********************************************************** /向 DS1302 写地址和数据, Addr 地址, Dat 数据 **********************************************************/ void Write1302_Cmd_Dat(unsigned char Addr, unsigned char Dat) { DS1302_RST = 0。 DS1302_CLK = 0。 DS1302_RST = 1。 DS1302_WriteByte(Addr)。 // 地址,命令 DS1302_WriteByte(Dat)。 // 写 1Byte 数据 DS1302_CLK = 1。 DS1302_RST = 0。 } /********************************************************** /读取 DS1302 某地址的数据 , **********************************************************/ uchar Read1302(unsigned char Addr) { uchar Dat。 开始 结束 设置 CE 为高 上升沿,按位传输地址 读取或写入相应地址的数据 设 置 C E 为 低 泰山学院本科毕业论文(设计) 19 DS1302_RST = 0。 DS1302_CLK = 0。 DS1302_RST = 1。 DS1302_WriteByte(Addr|0x01)。 // 以写数据时的地址为参考,读时应加 1 Dat = DS1302_ReadByte()。 // 读取数据到变量 Dat DS1302_CLK = 1。 DS1302_RST = 0。 return(Dat)。 } 读取时间数据并转化成字符串 由于时间数据包含年、月、日、时、分、秒、周,为了方便可以定义一个时间类型结构体,把转换前后的数据都作为这个结构体的成员。 typedef struct { unsigned char Week。 unsigned char Second。 unsigned char Hour。 unsigned char Minute。 unsigned char Hour。 unsigned char Month。 unsigned char Day。 unsigned char Year。 unsigned char Str_Time[9]。 unsigned char Str_Year[5]。 unsigned char Str_Month[3]。 unsigned char Str_Day[3]。 } struct_TIM。 然后,通过 Read1302()函数读取各个地址处的时间数据分别保存于 Second、Minute 等变量中并转换成十进制,如读取并 转 换秒值可以用以下两个语句: temp = Read1302(0x80)。 //低四位是秒的个位,高三位是秒的十位(原来是 BCD码) TimeSecond = ((temp amp。 0x70)4)*10 + (temp amp。 0x0F)。 接着就可以把数值转换成字符串了,仍以秒值为例转换语句如下: TimeStr_Time[0] = TimeSecond/10 + 39。 039。 //十 位 TimeStr_Time[1] = TimeSecond%10 + 39。 039。 //个位 至此,所得数据便可以方便的显示在液晶屏上了。 泰山学院本科毕业论文(设计) 20 LCD12864 液晶驱动程序 LCD12864 初始化 LCD12864 初始化流程如图 35 所示。 图 35 12864 液晶初始化 LCD12864 液晶屏 使用前先要进行初始化,已设定不同的功能和模式,本设计中 液晶初始化为基本指令集,开显示关闭游标, 光标从 左 向 右 加 1 移动 ,初始化通过 Init_12864()函数完成。 写数据到 LCD12864 功能函数 LCD12864 的功能函数主要是显示从其他模块采集到的并转化后的数据,这里主要提供了两种显示函数, writestring()和 writedat()两个函数, writestring()用来显示从一个地址开始的字符串, writedat()函数用来在某个地址显示一个字符。 下面是相应的实现代码。 泰山学院本科毕业论文(设计) 21 //从地址 addr_12864 开始,写字符串到 LCD void writestring(uchar addr_12864 ,uchar * str) { uchar i = 0。 Write12864_Cmd_Dat(addr_12864,0)。 while(str[i] != 39。 \039。 ) { Write12864_Cmd_Dat(str[i++],1)。 } } //在地址 addr,写一个字符到 LCD void writedat(uchar addr ,uchar dat) { Write12864_Cmd_Dat(addr,0)。 Write12864_Cmd_Dat(dat,1)。 } HS0038 红外解码程序模块 红外遥控器编码介绍 在进行红外解码之前首先要对本 设计 采用的红外遥控器编码方式进行简要介绍。 遥控器发送一组完整数据 (如 图 36 所示) ,首先是 9ms 高电平和 低电平组成的前导码,紧接着是 8 位地址码及其反码,最后便是 8 位操作码及其反码。 具体的编码方式为脉宽调制的串行码,用 的高电平和 的低电平表示二进制 0,以 的高电平和 的低电平表示二进制 1,编码形式如图 37所示。 图 36 遥控器发送一组完整数据 泰山学院本科毕业论文(设计) 22 图 37 遥控器编码的 0 和 1 红外解码程序流程及重要代码分析 本 设计 中红外遥控器作为控制单片机运行的按键,为了更好的实现按键功能红外接收端接在了单片机的外部中断 0 引脚,另外 遥控器编码采用脉宽调制方式,为了更精确的记录脉宽时间需要启用定时器功能,所以程序开始要进行中断和定时器的初始化。 为了保证精度,定时器初始化为工作方式 2 即 8 位自动重装模式。 中断触发方式采用下降沿触发,中断程序只需要记录两个中断之间时间值并保存,然后对相应脉冲的时间值与标准的脉冲时间进行比较,这样得出了是 0 还是 1。 由于中断函数尽量要短,进行解码的工作尽量不要在中断函数中进行。 下面是中断函数。 /********************************************************** 晶振 12M,一个机械周期为 12/12020000 为 1 微秒,则每一次中断 256*= **********************************************************/ void timer0() interrupt 1 { timer++。 } /********************************************************** startflag 初始值位 0,第一次进入中断标记为 1,同时时间清零,如果 经判断有引导码出现,就开始记录了。 **********************************************************/ void int0() interrupt 0 { if(startflag) { if( timer45) //9+ 的引导码 { ir_num=0。 } ir_time_data[ir_num]=timer。 泰山学院本科毕业论文(设计) 23 timer=0。 irnum++。 if(ir_num==33) { Ir_num=0。 Ir_end=1。 //一组接收完成 } } else { startflag=1。 //第一次进来时被标记为 1, timer 清 0 timer=0。 } } 另外,根据通过实际应用发现,外部光源特别是太阳光对红外通信干扰较大,为了避免光源干扰可能带来的麻烦,这里采用了软件解决的方式。 按键按下后把得到的数据分别与操作码和操作反码比较,每次比较通过后要立即清零。 下面是一段示例代码: if(。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。