[51单片机] 1ms的外部中断试能,我的18B20读不出数据了

[复制链接]
2063|28
 楼主| chuandaoxy 发表于 2021-2-4 14:17 | 显示全部楼层 |阅读模式
我的系统有个温感,在外部有个int0的触发信号,1ms1次,在没有触发信号时,18b20的信号没有问题,可以读回来,现在触发信号1来,就读不出温度的数值了,大家想想办法,驱动没有问题,怎末解决,我也尝试把读温度的程序放在外部中断函数里,时间太短1ms,老是失败
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
因为要跟随外部中断信号的状态,所以中断不能关闭

那就没办法了
 楼主| chuandaoxy 发表于 2021-2-4 14:50 | 显示全部楼层

要不改一个模拟温感,要不用串口,动作都不小
ayb_ice 发表于 2021-2-4 14:58 | 显示全部楼层
本帖最后由 ayb_ice 于 2021-2-4 14:59 编辑
chuandaoxy 发表于 2021-2-4 14:50
要不改一个模拟温感,要不用串口,动作都不小

可以只在关键的时候关中断(最大关中断时间可以 小于1MS),只是有些中断延迟而已,除非你有硬件1WIRE接口
或者在中断退出后立刻开始读写,这需要同步,但很难操作
henangongda123 发表于 2021-2-4 15:20 | 显示全部楼层
18B20是单总线双向通信,通信效率低,时序要求严格,如果你的产品避不开这个1ms中断,建议你还是放弃使用它吧,选那种可以支持I2C、SPI等接口通信的温度传感器,我之前用过SHT31,I2C接口,可以避开这种资源冲突的情况

评论

18B20通讯是个大坑,很害人的  发表于 2021-2-5 15:49
gx_huang 发表于 2021-2-4 16:07 | 显示全部楼层
18B20,对时序有严格要求的,就是前面的写0写1脉冲的低电平时间最严格,这个时间段禁止中断,总线恢复高电平后允许中断。当然中断程序的执行时间也不能太长。
coody 发表于 2021-2-4 16:20 | 显示全部楼层
用一个8腿的MCU读DS18B20然后用串口发给主MCU吧。我最讨厌的就是单总线,没有之一。

评论

别选单总线呗  发表于 2021-2-5 15:50
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;
}
henangongda123 发表于 2021-2-4 16:38 | 显示全部楼层
coody 发表于 2021-2-4 16:20
用一个8腿的MCU读DS18B20然后用串口发给主MCU吧。我最讨厌的就是单总线,没有之一。 ...

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

评论

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

人家的外部中断信号很重要,这样搞,万一漏中断一次就不行了
ColeYao 发表于 2021-2-4 16:54 | 显示全部楼层
henangongda123 发表于 2021-2-4 16:39
人家的外部中断信号很重要,这样搞,万一漏中断一次就不行了

  关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开应该还能响应的),当然如果架构很差,中断里面要执行一段几毫秒的代码是会漏掉中断,但那个和关中断没关系!
 楼主| chuandaoxy 发表于 2021-2-4 17:02 | 显示全部楼层
ColeYao 发表于 2021-2-4 16:54
关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开 ...

波形跟随,只要有其他中断接入,波形就会抖动,头大
chongdongchen 发表于 2021-2-4 17:33 | 显示全部楼层
18B20和中断打架,而且都是不能让步的那种。这个情况只能换个别的传感器了。
雪山飞狐D 发表于 2021-2-4 19:29 | 显示全部楼层
    温度的东西不需要时时刻刻追踪,18B20这种读法,实时追踪单片机系统卡死太久,你可以根据实际情况,比如间隔10S查询一次,就这一次关闭中断
henangongda123 发表于 2021-2-5 08:56 | 显示全部楼层
ColeYao 发表于 2021-2-4 16:54
关中断间隔是微秒级的,外部中断是毫秒级的,我不清楚为啥会漏中断(中断标志没清理掉,关中断后再打开 ...

你能保证每次关中断的时候,刚好没有中断信号进来?ms级和us级是相差一个级别不错,不过你看看18B20是多少us级别,有的操作需要几百us,人家信号是1ms,你这样粗暴的关中断,外部信号中断被屏蔽的概率还是很大的,人家要求不能屏蔽每一个次中断
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+定时器接收时偶尔会出错(但比直接使用定时器软件模拟误码率要低)解决不了,最终只能放弃。
ayb_ice 发表于 2021-2-5 09:06 | 显示全部楼层
henangongda123 发表于 2021-2-5 08:56
你能保证每次关中断的时候,刚好没有中断信号进来?ms级和us级是相差一个级别不错,不过你看看18B20是多 ...

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

开始就应该考虑到这些的
Prry 发表于 2021-2-5 09:27 | 显示全部楼层
18B20时序要求比较严格,产品上还是不建议使用,用个i2c接口的传感器更香,还比18B20便宜。

评论

太多人踩过18B20坑  发表于 2021-2-5 15:54
您需要登录后才可以回帖 登录 | 注册

本版积分规则

856

主题

1046

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部