硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4204|回复: 9
收起左侧

[有问必答] 今天调试DS18B20遇到的奇怪现象

[复制链接]

20

主题

56

回帖

116

积分

初级会员

积分
116
发表于 2017-7-27 21:57:11 | 显示全部楼层 |阅读模式
#include "stm32f10x.h"

void Delay(uint16_t delay)                        // 因为时钟为1MHz,delay的值代表延时的uS数
{
    TIM4->CCR1 = TIM4->CNT + delay;
    TIM4->SR &= ~TIM_SR_CC1IF;
    TIM4->CR1 |= TIM_CR1_CEN;
    while (!(TIM4->SR & TIM_SR_CC1IF));
    TIM4->CR1 &= ~TIM_CR1_CEN;
}

int main(void)
{
    // 初始化RCC
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    RCC->APB2ENR |= RCC_APB2ENR_IOPGEN;
    // 初始化GPIOG
    GPIOG->CRH = GPIOG->CRH & 0xFFFFFFF0 | 0x00000007;        // PG.8为开漏输出
    GPIOG->BSRR 1 << 8;                        // PG.8拉高
    // 初始化TIM4
    TIM4->CR1 &= ~TIM_CR1_CEN;
    TIM4-&gtSC = 71;                            // 分频得到1MHz时钟
    TIM4->ARR = 65535;
    TIM4->CCMR1 = TIM_CCMR1_OC1M_0;                    // 输出比较模式
    // 开始DS18B20复位
    GPIOG->BRR 1 << 8;                        // 复位开始,将PG.8拉低
    Delay(550);                            // 延时550uS
    GPIOG->BSRR 1 << 8;                        // PG.8拉低
    Delay(50);                            // 延时50uS
    if (GPIOG->IDR & 1 << 8)                     // 测试数据线是否被DS18B20拉低
    {
        // 数据线电平错误
        ……                            // 本应是低电平,但基本上都是检测出高电平
    }
        // 以下省略
    while (1);
}
自编的DS18B20复位的源码附上
按说对照DS18B20的资料代码是没错的,在MCU的PG8由下拉转为开漏状态后,上拉电阻会将数据线拉高,然后再由DS18B20输出拉低的信号,可是,MCU竟然未检测到DS18B20输出的这个低电平。找了一天的原因,发现如果使用开发板附带的使用systick延时函数就能正常复位,这一点很奇怪,实在是想不通用了通用定时器做延时竟然会发生如此现象。下面可以看示波图像
256384265998668410.jpg 522898729487781471.jpg

这是分别用两种延时方法测得的反复复位时数据线波形,两个图的波形基本是一致的,几乎看不出存在什么差别,但使用通用定时器延时的复位就是不正常。
微信截图_20170727221000.jpg

波形说明
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2017-7-27 22:08:58 | 显示全部楼层
还一个奇怪的现象,通用定时器都是使用APB1总线时钟的,时钟最高频率36MHz,可是非得将TIM4的预分屏器设为72,实际产生72分频所产生的延时才正确,望解答。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107379
QQ
发表于 2017-7-28 01:31:51 | 显示全部楼层
寄存器配置,看着头疼,实在帮不上了。

ps:只看一个问题,TIM4->ARR = 65536;  这个是16位寄存器,最大65535
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2017-7-28 18:35:28 | 显示全部楼层

回 eric2013 的帖子

eric2013:
寄存器配置,看着头疼,实在帮不上了。

ps:只看一个问题,TIM4->ARR = 65536;  这个是16位寄存器,最大65535

这个不是单位调试的代码,是在家里打的,检查的不够,难免有些录错的地方,现已修改更正。
这个问题今天没彻底解决,如果将延时判断程序改为while (TIM4->CCR1 != TIM4->CNT);那个复位是可以正常通过的。
下午又有个发现,先用库函数调通延时程序,再用寄存器法替换,最终对比出一奇怪现象,原来我用的寄存器初始化TIM4,代码如下:
TIM4-&gtSC = 71;
TIM4->ARR=65535;
和库函数法
TIM_TimeBaseStructure.TIM_Prescaler = 71;//预分频值
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;//在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x01;//重复计数值
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化
两者最终寄存器值完全一致,但运行结果有差别。仍以昨天的那个延时函数调试,用库函数的能得到正确的延时值,寄存器法初始化的延时值要多一些,例如:延时1000uS的话,前者定时器加了1000(0x3E8)结束,后者是0x423,,改变预分频器的值也是如此,做了各种实验没找到原因。
PS:以上差别是在开发板上运行出现的,如果用软件模拟仿真则不出问题。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107379
QQ
发表于 2017-7-28 18:45:02 | 显示全部楼层
其实不管是滴答定时器还是通用定时器,搞这个微妙延迟,太麻烦了。

参考我这个用时钟周期计数器做的微妙延迟,简单易用,效果杠杠的,原始函数在bsp_dwt.C文件中
QQ截图20170728184129.png
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2017-7-28 21:24:32 | 显示全部楼层

回 eric2013 的帖子

eric2013:其实不管是滴答定时器还是通用定时器,搞这个微妙延迟,太麻烦了。

参考我这个用时钟周期计数器做的微妙延迟,简单易用,效果杠杠的,原始函数在bsp_dwt.C文件中

 (2017-07-28 18:45) 
实际上单纯用定时的方法测DS18B20还是容易的,我的想法是利用定时中断+状态机来实现DS18B20测量,这样可以减少其他任务等待的时间,这种方法以前在AVR单片机上实现过,目前STM32F103只要一使用定时器状态就发生奇怪现象。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107379
QQ
发表于 2017-7-28 23:21:38 | 显示全部楼层

回 bucker 的帖子

bucker:实际上单纯用定时的方法测DS18B20还是容易的,我的想法是利用定时中断+状态机来实现DS18B20测量,这样可以减少其他任务等待的时间,这种方法以前在AVR单片机上实现过,目前STM32F103只要一使用定时器状态就发生奇怪现象。 (2017-07-28 21:24) 
18B20这种无实时性的器件,微妙延迟死循环,每秒更新一次,CPU利用率 0.4%。可以了。
使用时钟周期计数器不是一般简单,无需占用任何硬件外设,而且用在RTOS上极其合适,可以在RTOS启动前就可以做硬件外设初始化,好处大大的多。
回复

使用道具 举报

74

主题

1217

回帖

1439

积分

至尊会员

积分
1439
发表于 2020-1-9 10:51:49 | 显示全部楼层
eric2013 发表于 2017-7-28 23:21
18B20这种无实时性的器件,微妙延迟死循环,每秒更新一次,CPU利用率 0.4%。可以了。
使用时钟周期计数器 ...

硬汉哥,你好,我下载了你的ds18b20的驱动,没看到你说的“做好开关中断保护,切不可被任何其它任务打断,18B20就是这个样子的。”
还望指点下。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107379
QQ
发表于 2020-1-9 11:40:52 | 显示全部楼层
wdliming 发表于 2020-1-9 10:51
硬汉哥,你好,我下载了你的ds18b20的驱动,没看到你说的“做好开关中断保护,切不可被任何其它任务打断 ...

都做了。
回复

使用道具 举报

74

主题

1217

回帖

1439

积分

至尊会员

积分
1439
发表于 2020-1-9 11:56:16

看到了。谢谢

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2020-1-9 13:26:25 | 显示全部楼层
eric2013 发表于 2017-7-28 23:21
18B20这种无实时性的器件,微妙延迟死循环,每秒更新一次,CPU利用率 0.4%。可以了。
使用时钟周期计数器 ...

原来是这样估CPU的占用率。前端时间帮忙维护一个产品,发现大循环都没有延时的,每时每刻都是在检测任务的状态。看着就怪。最近学蓝牙BLE,发现这个平台的习惯就这样
再多学一点,发现人家压根就不需要过多的延时,处理完就CPU就待机休息了。
Releasing your creativity
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-29 08:18 , Processed in 0.195667 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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