打印
[51单片机]

1ms的外部中断试能,我的18B20读不出数据了

[复制链接]
1509|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chuandaoxy|  楼主 | 2021-2-4 14:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
ayb_ice| | 2021-2-4 14:19 | 只看该作者
关键时候关中断,避免被影响,读取时不需要全程关中断

使用特权

评论回复
板凳
chuandaoxy|  楼主 | 2021-2-4 14:33 | 只看该作者
ayb_ice 发表于 2021-2-4 14:19
关键时候关中断,避免被影响,读取时不需要全程关中断

因为要跟随外部中断信号的状态,所以中断不能关闭

使用特权

评论回复
地板
ayb_ice| | 2021-2-4 14:47 | 只看该作者
chuandaoxy 发表于 2021-2-4 14:33
因为要跟随外部中断信号的状态,所以中断不能关闭

那就没办法了

使用特权

评论回复
5
chuandaoxy|  楼主 | 2021-2-4 14:50 | 只看该作者

要不改一个模拟温感,要不用串口,动作都不小

使用特权

评论回复
6
ayb_ice| | 2021-2-4 14:58 | 只看该作者
本帖最后由 ayb_ice 于 2021-2-4 14:59 编辑
chuandaoxy 发表于 2021-2-4 14:50
要不改一个模拟温感,要不用串口,动作都不小

可以只在关键的时候关中断(最大关中断时间可以 小于1MS),只是有些中断延迟而已,除非你有硬件1WIRE接口
或者在中断退出后立刻开始读写,这需要同步,但很难操作

使用特权

评论回复
7
henangongda123| | 2021-2-4 15:20 | 只看该作者
18B20是单总线双向通信,通信效率低,时序要求严格,如果你的产品避不开这个1ms中断,建议你还是放弃使用它吧,选那种可以支持I2C、SPI等接口通信的温度传感器,我之前用过SHT31,I2C接口,可以避开这种资源冲突的情况

使用特权

评论回复
评论
zlf1208 2021-2-5 15:49 回复TA
18B20通讯是个大坑,很害人的 
8
gx_huang| | 2021-2-4 16:07 | 只看该作者
18B20,对时序有严格要求的,就是前面的写0写1脉冲的低电平时间最严格,这个时间段禁止中断,总线恢复高电平后允许中断。当然中断程序的执行时间也不能太长。

使用特权

评论回复
9
coody| | 2021-2-4 16:20 | 只看该作者
用一个8腿的MCU读DS18B20然后用串口发给主MCU吧。我最讨厌的就是单总线,没有之一。

使用特权

评论回复
评论
zlf1208 2021-2-5 15:50 回复TA
别选单总线呗 
10
ColeYao| | 2021-2-4 16:36 | 只看该作者
18B20中关键的地方关定时中断或外部中断就好,请参考下列代码!
//往DS18B20中写一个字节
void Ds18B20::Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     //关systick中断
        SetDir_PortSensorA_Out();
        SA_DQ0;    delay_us(7);       //==延时0us---25us===
        if((n&0X01)==0X01)
        {
          SetDir_PortSensorA_IN();
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断   
          delay_us(100);        //64us delay_us(192)
        }
        else
        {
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断
          delay_us(100);         //60uS delay_us(160);
          SetDir_PortSensorA_IN();  
          delay_us(16);          //10uS delay_us(32);
        }
        n=n>>1;
    }
}

//从DS18B20读取一个字节
unsigned char Ds18B20::Read_18B20(void)
{
    unsigned char i;
    unsigned char temp;
    for(i=0;i<8;i++)
    {
        temp=temp>>1;
        SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     //关systick中断   
        SetDir_PortSensorA_Out();
        SA_DQ0;    delay_us(2);  //==延时0us---4us===               
        SetDir_PortSensorA_IN();   delay_us(1);                //==延时0us---25us===
        if((InPortBit)==0)
        {
            temp=temp&0x7F;
        }else
        {
            temp=temp|0x80;
        }
        SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;      //开systick中断
        delay_us(90);          //==延时55us===
    }
    return    temp;
}

使用特权

评论回复
11
henangongda123| | 2021-2-4 16:38 | 只看该作者
coody 发表于 2021-2-4 16:20
用一个8腿的MCU读DS18B20然后用串口发给主MCU吧。我最讨厌的就是单总线,没有之一。 ...

这方法也不错,8脚的STC 0.75元,成本增加一点,问题解决了

使用特权

评论回复
评论
coody 2021-2-5 11:59 回复TA
这是我常用的方法,特别是有多路温度时。 
12
henangongda123| | 2021-2-4 16:39 | 只看该作者
ColeYao 发表于 2021-2-4 16:36
18B20中关键的地方关定时中断或外部中断就好,请参考下列代码!
//往DS18B20中写一个字节
void Ds18B20::Wr ...

人家的外部中断信号很重要,这样搞,万一漏中断一次就不行了

使用特权

评论回复
13
ColeYao| | 2021-2-4 16:54 | 只看该作者
henangongda123 发表于 2021-2-4 16:39
人家的外部中断信号很重要,这样搞,万一漏中断一次就不行了

  关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开应该还能响应的),当然如果架构很差,中断里面要执行一段几毫秒的代码是会漏掉中断,但那个和关中断没关系!

使用特权

评论回复
14
chuandaoxy|  楼主 | 2021-2-4 17:02 | 只看该作者
ColeYao 发表于 2021-2-4 16:54
关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开 ...

波形跟随,只要有其他中断接入,波形就会抖动,头大

使用特权

评论回复
15
chongdongchen| | 2021-2-4 17:33 | 只看该作者
18B20和中断打架,而且都是不能让步的那种。这个情况只能换个别的传感器了。

使用特权

评论回复
16
雪山飞狐D| | 2021-2-4 19:29 | 只看该作者
    温度的东西不需要时时刻刻追踪,18B20这种读法,实时追踪单片机系统卡死太久,你可以根据实际情况,比如间隔10S查询一次,就这一次关闭中断

使用特权

评论回复
17
henangongda123| | 2021-2-5 08:56 | 只看该作者
ColeYao 发表于 2021-2-4 16:54
关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开 ...

你能保证每次关中断的时候,刚好没有中断信号进来?ms级和us级是相差一个级别不错,不过你看看18B20是多少us级别,有的操作需要几百us,人家信号是1ms,你这样粗暴的关中断,外部信号中断被屏蔽的概率还是很大的,人家要求不能屏蔽每一个次中断

使用特权

评论回复
18
ColeYao| | 2021-2-5 09:04 | 只看该作者
本帖最后由 ColeYao 于 2021-2-5 09:37 编辑
henangongda123 发表于 2021-2-5 08:56
你能保证每次关中断的时候,刚好没有中断信号进来?ms级和us级是相差一个级别不错,不过你看看18B20是多 ...

16F讲了,一般DS18B20采集信号的周期1秒左右就够了,要丢中断也就是0.1%的误差,一般系统如果不是通讯等对误码率要求比较高的场合,0.1%的误差影响可以忽略了。  另外屏蔽外部中断有多种关法(直接关外部中断、关总中断、使用较高优先级中断抢占),你确定不管哪种屏蔽外部中断的方法都会丢外部中断!
   通常来说,使用代码实现一个功能有N个可能的方法,如果因为某个条件限制无法实现预定的功能,至少我会把所有可能绕过条件限制的N个方法全部测试一遍才会死心,就像最近的stm32F407使用DMA+定时器实现任意IO口模拟高速率(115200)串口这个问题,我实现了发送,最终卡在了接收上,DMA+定时器接收时偶尔会出错(但比直接使用定时器软件模拟误码率要低)解决不了,最终只能放弃。

使用特权

评论回复
19
ayb_ice| | 2021-2-5 09:06 | 只看该作者
henangongda123 发表于 2021-2-5 08:56
你能保证每次关中断的时候,刚好没有中断信号进来?ms级和us级是相差一个级别不错,不过你看看18B20是多 ...

也不能那么绝对说,那只是他那么认为而已,就算不关中断,中断也是有一定的延时的(而且是不等的延时),这与当前正在运行的指令有关

开始就应该考虑到这些的

使用特权

评论回复
20
Prry| | 2021-2-5 09:27 | 只看该作者
18B20时序要求比较严格,产品上还是不建议使用,用个i2c接口的传感器更香,还比18B20便宜。

使用特权

评论回复
评论
zlf1208 2021-2-5 15:54 回复TA
太多人踩过18B20坑 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

855

主题

1044

帖子

4

粉丝