找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4684|回复: 12
打印 上一主题 下一主题
收起左侧

关于ds18b20与单片机定时器中断共存

[复制链接]
跳转到指定楼层
楼主
温度需要实时显示在LCD上,利用温度控制pwm占空比调节电机速度 。如果在ds18b20读取温度前后关闭开启中断,定时器产生的pwm方波会受影响如果不加,温度又没办法读取。总之如果要温度正常读取显示就没法正常控制电机速度,要能正常控制定时器产生pwm方波,就不能正常读取显示温度,怎么解决呀


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-5-1 08:14 | 只看该作者
由于ds18b20对时序要求比较严格,掌握不好会出错,所以温度读取函数往往是以一个整体,一次全部完成。但需占用时间较长,约10ms。这就造成与数码管动态扫描,PWM调制,超声波测距等其它外设难以协调工作。如果仔细分析ds18b20的读写函数时序,可以看出:读写1个字节的时间都不大于1ms,而两次读写1个字节之间的时间间隔要求不高。这就给与其它外设的分时操作提供机会。温度读取函数使用switch-case-break语句,分若干次运行温度读取函数完成一次读取温度的任务。给你一个应用示例参考。 4位数码管时钟温度表仿真.zip (212.37 KB, 下载次数: 85)

回复

使用道具 举报

板凳
ID:517951 发表于 2021-5-1 08:50 | 只看该作者
读DS18B20 和中断没关系,直接 读就好了,不用开启关闭中断。中断该干什么活就好了,二者没有关联和冲突
回复

使用道具 举报

地板
ID:390416 发表于 2021-5-1 09:47 | 只看该作者
你要求的PWM周期多少?
回复

使用道具 举报

5#
ID:390416 发表于 2021-5-1 09:49 | 只看该作者
DS18B20 每bit 延迟最少35us,读一次需要1250us
回复

使用道具 举报

6#
ID:383215 发表于 2021-5-1 16:59 | 只看该作者
沙发的回答非常正确,18B20没有必要一口气读完,可以按步数慢慢的读,板凳的说法不对,18B20在写命令和读出数据期间不能被任何中断打断,否则数据就会错乱,解决的方法就是两个,一是18B20在写命令和读出数据期间关闭中断,二是关闭中断影响程序运行就把18B20程序放在中断里一步一步的读写,如果还有中断嵌套就把18B20程序放在最后一级中断里,最后一级中断不能有不响应的情况,如果有,还要再想其它方法。曾经我过零触发可控硅还要调功,就把18B20程序放在定时中断里,做到了调功的情况下也可以读18B20的温度,后来发现不需要调功,又把18B20程序放回外中断。

这是我在触发可控硅外中断过零检测程序里分9步读出18B20温度,每一步开头置高一个I/O口结束拉低I/O口得到的波形图,上面的波形是过零信号,下面波形高电平部分就是18B20每一步的时间,一开始测试分别置高拉低两次I/O口把每一步的时间检测出来,然后再置高拉低一次I/O口把每一步的时间检测出来,第一步的时间分别是20.9和16.6微秒,第二步的时间分别是68.4和61.3微秒,我就大概知道置高拉低一次I/O口的时间是4微秒左右,我把第二次测试的时间减去4微秒,就比较精确的知道每一步的具体时间,最短的一步是4.88微秒,最长的一步是826微秒,也就是最后一步读出数据,感觉好像有点不太对,时间有点长,这个程序运行了好几年了,没有发现问题,AVR单片机内部1兆RC振荡器编出来的。9步一共花了3412.88微秒,这个时间感觉也是偏长, 3412.88微秒是18B20占用单片机的总时间,对于单片机的一个循环周期,18B20占用单片机的时间最大就是826微秒,所以,我这样编程CPU应用率算是比较高的,9步读出18B20温度的全部时间是80.6毫秒,这是示波器测量出来的时间,都快有0.1秒了,这个时间肯定是严重偏长,但是,问题不大,温度基本上都是渐变,不太可能是突变,就是花一秒钟把温度读出来也没有任何影响。至于5楼说的DS18B20读一次需要1250us,这个1250us是读出18B20温度的总时间还是某一步的最长时间,我也搞不清楚了。我多次说过编单片机程序必须要有仿真器和示波器,没有这两样东西,我宁愿不编程序,因为编程效率太低了,我从来不计算任何程序的时间,都是设计电路的时候多预留一个I/O口,就用这个口靠示波器测量,示波器是300元左右的虚拟示波器,基本够我用了,档次高的示波器测量的精度肯定更高。
所以,楼主想让18B20与单片机定时器中断共存,把18B20的程序放在中断里就可以了,只要pwm的最小脉冲不要小于1000Hz的那个脉冲宽度,18B20与单片机定时器中断共存,没有什么难度。

回复

使用道具 举报

7#
ID:914633 发表于 2021-5-2 21:56 | 只看该作者
kmsj 发表于 2021-5-1 16:59
沙发的回答非常正确,18B20没有必要一口气读完,可以按步数慢慢的读,板凳的说法不对,18B20在写命令和读出 ...
  1. void time0(void) interrupt 1
  2. {
  3.         TH0 = 0xfc;        //配置1ms定时
  4.         TL0 = 0x18;
  5.                         timer0++;        //timer0开始计数,每1毫秒加一
  6.                    if(timer0>5)  //PWM周期为5毫秒
  7.                 {
  8.                         timer0=0;
  9.                 }
  10.                 if(timer0 <speed)       
  11.                 {
  12.                         PWM=1;
  13.                 }
  14.                 else
  15.                 {
  16.                         PWM=0;
  17.                 }
  18.          switch(step)
  19.          {
  20.                   case 0:Ds18b20Init();break;
  21.                  case 1:Ds18b20WriteByte(0xcc);break;
  22.                  case 2:Ds18b20WriteByte(0x44);break;
  23.                  case 3:Ds18b20Init();break;
  24.                  case 4:Ds18b20WriteByte(0xcc);break;
  25.                  case 5:Ds18b20WriteByte(0xbe);break;
  26.                  case 6:tml = Ds18b20ReadByte();break;
  27.                  case 7:tmh = Ds18b20ReadByte();break;
  28.                  case 8: temp = tmh;
  29.                      temp <<= 8;
  30.                      temp |= tml;break;
  31.                  case 9: display(temp);break;
  32.          } step++;step%=10;          
  33.                
  34.          
  35. }
复制代码

谢谢了 pwm周期太大了控制电机转的不流畅 只能暂时这样了
回复

使用道具 举报

8#
ID:383215 发表于 2021-5-3 23:30 | 只看该作者
hoodieboi 发表于 2021-5-2 21:56
谢谢了 pwm周期太大了控制电机转的不流畅 只能暂时这样了

我从来没有编过pwm程序,也搞不清楚多高的频率电机转的流畅?我编的控制可控硅过零触发,频率低的要命,倒是很容易,我是用18步读出两个18B20的温度,所以读写单个字节的时间偏长了一些,我是第9步和18步同时读高低字节,看你的程序,高低字节你都分开读了,你已经编出占用CPU时间最短,也是最高效的18B20程序,你只有再看看还有什么办法可以缩短读写18B20单个字节的时间,这个时间就是最小脉宽了,再比这个小,18B20就无法读出来了。然而我仔细看了你的程序,你是先操作pwm,后读写18B20,18B20每一步的时间都不一样,会不会影响pwm频率?我的理解是把pwm操作和18B20每一步穿插在一起,操作完一次就运行18B20的一步,不要被18B20不同步数的时间影响pwm频率,这个简单啊,先不读18B20,试试1000Hz的频率是否流畅,流畅了再把18B20程序穿插进去,1000Hz不行,只有提高频率,但也不可能太高,2000Hz可能就很难读出18B20了。不过我只是猜想,目前我对pwm一窍不通。
回复

使用道具 举报

9#
ID:383215 发表于 2021-5-4 11:06 | 只看该作者
我百度了一下,pwm无非就是脉宽调制,楼主的程序没有问题,温度是渐变,可以把case后面的数字0、1、2、3改成0、10、20、30……,读写速度就放慢了10倍,就是改成100、200、300……,放慢100倍也没有问题,我用10秒钟读出18B20的温度都不会出错,唯一就是没有做过读写单个字节最小时间的试验,因为我用不着啊,估计2000Hz左右的频率就是极限了,实在不行,楼主只有换读出时间更短的温度传感器或者双CPU。
回复

使用道具 举报

10#
ID:213173 发表于 2021-5-4 18:45 | 只看该作者
hoodieboi 发表于 2021-5-2 21:56
谢谢了 pwm周期太大了控制电机转的不流畅 只能暂时这样了

如果楼主实在协调不了两者冲突可以换有内置PWM的MCU。如STC15系列。
回复

使用道具 举报

11#
ID:1075970 发表于 2023-7-27 00:05 | 只看该作者
hoodieboi 发表于 2021-5-2 21:56
谢谢了 pwm周期太大了控制电机转的不流畅 只能暂时这样了

楼主,用了那么多全局变量啊……
回复

使用道具 举报

12#
ID:1085441 发表于 2023-7-27 01:30 | 只看该作者
2个办法,一是单独用一个单片机都1820温度,再发给主单片机。
而是,换I2C接口的温度传感器,中断不影响读温度数据。
回复

使用道具 举报

13#
ID:1015233 发表于 2023-7-27 08:20 | 只看该作者
如果控制器是STM32的话,PWM输出建议用CCR比较器输出,可以一个定时器多通道,不需要中断就可以产生。所以就可以避免被打断。MSP430F5529也是可以的。如果是51单片机这种的话,那就很难搞了 。极个别STC里面有一些专门产生PWM波形的寄存器,可以直接调用,不过,难度会大一些。不过可以尝试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表