完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
这个帖子有深度
程序都是实战性的 收藏起来慢慢研究 |
|
|
|
|
|
学习了 。。谢谢。。
|
|
|
|
|
|
HENHAO
|
|
|
|
|
|
很好…………
|
|
|
|
|
|
初学者借鸿哥帖子献丑!
代码原创,程序思路采用的是基于状态转移的分段设计! 我也是个初学者,做实验1602液晶代码写过,数码管代码也写过,但是很多时候多个功能一组合,工作就不正常了;这里牵涉一个很重要的问题,也就是前辈们说的“释放CPU”!向各种教材上面说的写的代码一样,DelayMS(1000)延时1000毫秒,还有很多while(key);等等诸如此类的代码;多个功能组合起来就是容易出问题,为什么呢?就是因为我们学习的程序设计,都是顺序编程方法,各个功能模块一多,难免互相干扰,看了鸿哥的程序风格,收益良多;借花献佛 鸿哥没更新时候,我把我操作DS18b20的代码放上来,让大家吐槽一番!!!! /********************************************************************** 文件名称:DS18b20.C 主控芯片:STC89C52RC 晶振11.0592MHz 功能描述:单总线操作DS18b20温度传感器(整数直接显示,小数查表显示) ROM指令:读取33H、匹配55H、跳过ccH、搜索f0H、温度报警搜索ecH 寄存器指令:温度转换44H、写暂存器4eH、读暂存器beH、复制暂存器48H、读电源b4H、重读EEPROM b8H 作者日期:田卫卫 / 2013年3月7日 版 本:V1.2 **********************************************************************/ #include"define.h" #include"ds18b20.h" #include"time.h" u8 ResetDS(); //DS18b20初始化(0应答、1无应答) u8 RD_DS(); //从DS18b20读取一个字节 void WR_DS(u8 val); //向DS18b20写入一个字节 u8 TemperatureUpdate(); // 启动温度转换/读取转换结果。 static u8 code HaetTAB[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //温度小数查询表 u8 Temperature[3]; //温度缓冲区(正负、整数、小数) /********************************************************************** 功能描述:DS18b20初始化(函数执行>1ms) 函数原型:u8 ResetDS() 返 回 值:0应答、1无应答 时序原理:发送低电平复位脉冲、DS置高、延时60us+420us内检测存在脉冲 **********************************************************************/ static u8 ResetDS() { u8 temp; DS = 0; //开始复位脉冲 Delayus(250); //精确延时:【时序要求480 DS = 1; //数据线拉高,准备检测存在脉冲 Delayus(26); //15~60us后,可检测存在脉冲(11.0592MHz) Delayus(26); temp = DS; //检测存在脉冲 Delayus(170); return temp; //返回值:0应答、1无应答 } /********************************************************************** 功能描述:从DS18b20读取一个字节 函数原型:u8 RD_DS() 返 回 值:从DS18b20读取的一个字节 时序原理:DS拉低1us、DS拉高、读DS上的1位数据、延时满足周期60us,循环8次 **********************************************************************/ static u8 RD_DS() { u8 i,val=0; for(i=0;i<8;i++) //循环8次,每次读取一位 { DS = 0; //数据线拉低1us:开始读时间隙(11.0592MHz晶振,因机器周期大于1us,所以无需延时) DS = 1; //数据线拉高 if (DS) //读取一位 //val >>= 1; val |= BIT(i); //if(DS) val|=0x80; Delayus(25); //满足时序60us周期 } return val; //返回值:读取的一个字节 } /********************************************************************** 功能描述:向DS18b20写入一个字节 函数原型:void WR_DS(u8 val) 输入参数:val为向DS18b20写入的一个字节数据 时序原理:向DS18b20写入一个字节数据 **********************************************************************/ static void WR_DS(u8 val) { u8 i; for(i=0;i<8;i++) //循环8次,每次写入一位 { DS = 0; //数据线拉低:开始写时间隙(11.0592MHz晶振,因机器周期大于1us,所以无需延时) DS = val & 0x01; //取最低位逐个发!! val >>= 1; //右移1位,待发 Delayus(24); //满足时序60us周期(57.6us) DS = 1; //精确时序:>1us恢复时间 } } /********************************************************************** 功能描述:分段式程序设计:启动温度转换、读取转换结果。 函数原型:void TemperatureUpdate() 包含函数:ResetDS()、WR_DS()、RD_DS() 特别注意:启动温度转换,必须延时>750ms才能执行读取操作。 **********************************************************************/ u8 TemperatureUpdate() { static u8 DSstep; //定义温度转换步骤DSstep变量。 switch (DSstep) { case 0: //步骤0:总线初始化 if (ResetDS() == 0) //DS18b20初始化 DSstep = 1; //切换到:步骤1 break; case 1: //步骤1:跳过ROM、启动温度转换 WR_DS(0xcc); //跳过ROM指令 WR_DS(0x44); //启动温度转换指令 DSstep = 2; //切换到:步骤2 break; case 2: //步骤2:总线初始化 if (ResetDS() == 0) //DS18b20初始化 DSstep = 3; //切换到:步骤3 break; case 3: //步骤3:跳过ROM指令、读暂存器 WR_DS(0xcc); //跳过ROM指令 WR_DS(0xbe); //读暂存器指令 DSstep = 4; //切换到:步骤4 break; case 4: //步骤4:读取温度转换结果 { u8 tempL,tempH; //tempL温度低8位(内部RAM第0字节)、tempH温度高8位(内部RAM第1字节) u16 TempDat; //存储温度 tempL = RD_DS(); //读温度低8位(内部RAM第0字节) tempH = RD_DS(); //读温度高8位(内部RAM第1字节) TempDat = tempH; //高8位 TempDat = (TempDat<<8)|tempL; //组合温度 if (tempH & 0xf0) //判断正负温度 { Temperature[0] = 1; //温度符号位 - TempDat = (~TempDat) + 1; //处理负温度! } else { Temperature[0] = 0; //温度符号位 + } tempL = TempDat & 0x000f; //取温度小数 Temperature[1] = (TempDat >> 4); //取温度整数(小数部分被舍弃,单独处理) Temperature[2] = HaetTAB[tempL]; //查表法精确到小数点1位 DSstep = 0; //返回到:步骤0 函数起始位置 } break; default: beep = 0; //正常程序不会进入这里!!! break; } return DSstep; } /********************************************************************** 文件名称:DS18b20.H 主控芯片:STC89C52RC 晶振11.0592MHz 功能描述:单总线操作DS18b20温度传感器(温度整数直接处理显示,小数四舍五入查表显示) ROM指令:读取33H、匹配55H、跳过ccH、搜索f0H、温度报警搜索ecH 寄存器指令:温度转换44H、写暂存器4eH、读暂存器beH、复制暂存器48H、读电源b4H、重读EEPROM b8H 作者日期:田卫卫 / 2013年3月7日 版 本:V1.2 **********************************************************************/ #ifndef _DS18b20_H_ #define _DS18b20_H_ // ***it DS = P2^2; /*DS18b20 单总线*/ u8 TemperatureUpdate(); //启动温度转换后必须延时>750ms才能执行读取操作;启动温度转换/读取转换结果。 extern u8 Temperature[3]; //温度缓冲区(正负、整数、小数) #endif /********************************************************************** if (T2Count[0] == 0) //温度采集任务 { switch (TemperatureUpdate()) { case 0: //返回值0:一轮转换结束,温度值保存在Temperature[3]数组 LCDUpdate(); ////////////////////////////// T2Count[0] = 5; /////////////////T2进中断的次数 break; case 2: //返回值2:已经启动温度采集,需延时750MS T2Count[0] = 400; /////////////////T2进中断的次数 break; default: break; } } **********************************************************************/
|
|
|
|
|
|
我想请教大家一下,590#的复位程序段,如果复位时有中断产生,是不是会打扰延时的准确性,如果对其开关中断操作,那么此时的中断的实时性不也是被打扰了,不知道大家是怎么处理的,鸿哥麻烦您指点下,,,
|
|
|
|
|
|
|
|
|
|
第二十节:按键操作液晶显示屏菜单的基本程序框架 (1) 开场白: 大部分带液晶显示屏的机器,都要求可以跟按键进行配合以便达到可以设置机器内部参数的目的,菜鸟们可能会觉得很复杂,可是鸿哥觉得那都是小菜一碟,因为鸿哥在做那么多项目中早已经发现了它们的规律,现在提取出来跟大家分享。大家不要感激我那么晚了还熬夜写技术贴,要感谢就感谢电子发烧友论坛的管理员zhihuizhou,他花了那么多时间帮我把这个帖子整理出一套目录链接来,我今天看到后非常感动,再苦再忙也不能有负于他。 在编写液晶显示程序中,有两个最核心的要素。它们分别是窗口变量与更新变量。 (a) 窗口变量:在编写整个程序中,必须要有一条主线,然后按键等所有操作都围绕着这条主线展开,这样无论程序有多复杂也不会乱。这条主线就是窗口(变量名为wd_sec),在窗口的主线下,再分出一个局部窗口(变量名为part_sec)。 (b) 更新变量:液晶屏是属于静态控制的屏,因为涉及到整屏更新(wd_update)和局部更新(part_X_Y_update)。把不用经常更新显示的内容放到整屏更新里,把要经常更新显示的内容放到局部更新里。 大家只要仔细阅读本程序,领悟到了这条窗口变量与更新变量的精髓,以后做再复杂的人机对话界面都难不倒你。 (2)功能需求: 结合第二节的独立按键与第十一节的12864显示屏驱动程序,要求可以显示两个窗口,每一屏液晶显示窗口可以显示4行8X16字符的内容,每一行显示一个数字,按“上”“下”键时,每一行中的数字可以上下依次负显,相当于光标上下移动,按“加”“减”键时,被选择中的某一行中带负显的数字会依次增加或减小(最大范围是0至99)。当负显光标停留在第一屏第4行的数字时,如果继续按“下”键,则负显光标会切换到第二屏的第1行数字。负显光标停留在第二屏的第4行的数字时,继续按“下”键,则又会切换返回到第一屏的第1行数字。 (3)硬件原理: 请参考第二节的独立按键与第十一节的12864显示屏的硬件电路。 (4)源码适合的单片机: PIC18F4520,晶振为11.0592MHz。 (5)源代码讲解如下: 请下载附件源代码讲解。 (6)小结: 曾经有很多老板咨询我,单色液晶屏品种那么多,什么时候该选段码屏,什么时候该选COB的点阵液晶模块,什么时候应该选COG的点阵液晶模块.鸿哥的建议是: (a) 段码屏的优点:单价最便宜,显示效果最漂亮。 段码屏的缺点:因为是定制的,非标准的,前期要一两千的开模费用。因为不是点阵的,不能在一个位置任意显示一个字体,仅适用于界面要求不高的场合。 (b) COB点阵液晶模块的优点:可以显示字符或汉字,标准化,普及化,小批量采购不用愁,不用收开模费,厂家众多,而且还相互兼容。 COB点阵液晶模块的缺点:单价高,体积大。 (C) COG点阵液晶模块的优点:可以显示字符或汉字,单价比COB液晶模块便宜,体积小。 COG点阵液晶模块的缺点:也是属于非标准屏,开模费最高。有些不用开模费的屏,是因为某个厂家给他的大客户已经开模做了,顺便给你做的时候当然不用收开模费,但是,如果你的产品量不大,就意味着你以后有可能会缺货,而且这种屏不是标准屏,这家公司有的品种,其他家的公司往往没有相同的,或者能够兼容的。 (7)下集预告: 从下一节开始进入一个新的领域,我会花很多章节来讲常用的几种数码管驱动方式以及基本编程框架。 (未完待续,下节更精彩,不要走开哦) |
|
|
|
|
|
|
|
有很多种情况: (1)在考虑整个设计方案的时候,就可以考虑不用定时中断,比如可以考虑把动态数码管显示改成专用的数码管驱动芯片来驱动,这样所有的程序都放在main函数的循环里。 (2)如果非要定时中断,那么定时中断里的程序运行时间尽可能少。然后调试看看实际效果。如果不用关闭中断,也能满足,那就可以不用关闭中断。 (3)如果以上两种条件都不行,那么就只能进入核心驱动程序前先关闭所有中断,执行完之后再把中断打开。 (4)我认为所有C语言写的程序,时间都是做不到绝对准确的,只能是尽可能减少误差。所以感觉很重要。 |
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
求解外围电路实现的是4脚给持续低电平复位并正常工作,高电平不工作的原因
2077 浏览 1 评论
3501 浏览 3 评论
PIC1946程序有一个变量在运行过程中恢复初始值其他变量保持不变
2333 浏览 2 评论
2760 浏览 0 评论
PIC16F1825的RC5引脚,在主程序中操作无效,在中断中可以改变是为什么?
4015 浏览 5 评论
965浏览 0评论
用XC8编译PIC18F25K80时提示下面Error,求怎么解决这个问题
6349浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 05:43 , Processed in 1.267793 second(s), Total 110, Slave 92 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号