历史上的今天
返回首页

历史上的今天

今天是:2025年02月10日(星期一)

正在发生

2020年02月10日 | 用51单片同时测温度(DS18B20)和频率(外部中断测)

2020-02-10 来源:51hei

void main()//主函数
{           
    delay1ms(1000);     
        lcd_init();//液晶显示初始化
        init_play(); 

while(1)
{        
     EA=0; //因DS18B20对时序要求高且受中断影响,故先关闭总中断
     read_temp();//读取温度
     ds1820disp();//显示
     CT_init();//定时计数器初始化     
     EA=1;//开总中断 
         EX0=1;//允许外部中断
         IT0=1;//设置外部中断方式为下降沿触发
         P3=0xff;                                                        
         t0=(u*65536+x)*(12/22.1);//计算脉冲时间宽度(单位:ms)
         f=1000000/(2*t0);//计算频率                        
         if(f>8000&&tflag==1)          
          init_play1();         //显示Frozen
   else init_play2(); //显示Not frozen
}
}
这是主函数,初步怀疑是中断测频率时和温度传感器读取数据相影响,怎么解决 ?
方法1:读频率实时性要求不高的话,就开这个关那个,轮流来,其他没招了
先测1秒温度,然后测1秒频率,再测一秒温度?
方法2:我给你个参考程序,也是单总线的数据采集(时钟11.0592)。
在你的主循环中不要关闭中断,调用读温度时,有校验码确定数据的有效性(如果读温度程序中间有中断,数据可能会是无效的)。
#include
#include "public.h"

sbit DS2401Bus  = P3^5;

//DS2401.c
//  首先对单总线发复位:
//        总线保持低电平超过480us;总线上的所有器件将复位
//        主机释放总线,并进入接收模式
//        从机等待15-60us,接着拉低总线60-240us,以产生应答脉冲
//    写0x33H命令: 仅适合于单节点(读ROM[0x33]命令)
//                  所有写(0或1)时隙至少需要60us 且在两次独立的写时隙之间至少需要1us的恢复时间
//                  两种写时隙均起始于主机拉低总线
//                          写1时隙: 主机在拉低总线后接着必须在15us之内释放总线,由5k上拉电阻将总线拉至高电平
//                           写0时隙: 主机拉低总线后只需在整个时隙期间保持低电平即可至少60us
//                           -- 在写时隙起始后15-60us期间,单总线器件采样总线电平状态(0或1)
//           读时隙
//                   器件仅在主机发出读时隙时才向主机传输数据。所以在主机发出读数据命令后必须马上产生读时隙
//                  所有读时隙至少需要60us 且在两次独立的读时隙之间至少需要1us的恢复时间
//                  每个读时隙都由主机发起,至少拉低总线1us
//                  在主机发起读时隙之后单总线器件才开始在总线上发送0或1
//                  从机发出的数据在起始时隙之后保持有效时间15us
//                  因而,主机在读时隙期间必须释放总线并且在时隙起始后的15us之内采样总线状态
//
#pragma ot(4,SPEED)

void delay_500us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 56; i++) ;   
}    
void delay_250us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 28; i++) ;   
}    
void delay_90us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 9; i++) ;   
}    
void delay_60us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 6; i++) ;   
}    

unsigned char InitDS2401(void)  //复位DS2401
{
        unsigned char tmp;
        DS2401Bus = 0;                   // 输出:0;总线保持低电平超过480us
        delay_500us();                  // 498us
        DS2401Bus = 1;                   // 释放总线,由5k上拉电阻将总线拉至高电平
        delay_60us();            // 64us,等待器件发出应答脉冲
        tmp = DS2401Bus;        // 检查应答脉冲
        delay_250us();                // 255us,延时240us以上
        if(tmp)                                // 读取数据
                return 0;
        else
                return 1;
}

void WriteDS2401(unsigned char d)//写2401命令
{
        unsigned char i;
        for(i=0;i<8;i++) {
                DS2401Bus = 0;                   // 主机在拉低总线后接着必须在15us之内释放总线
                _nop_(); _nop_(); _nop_();        // 每个nop估计耗时 1.085us
                if(d & 1) {                           // 输出:数据位
                        DS2401Bus = 1;
                }
                d >>= 1;
                delay_60us();                // 至少保持60us
                DS2401Bus = 1;            // 将总线拉至高电平, 至少需要1us的恢复时间
                _nop_();_nop_();_nop_();                  
        }
}

unsigned char ReadDS2401()         //读2401数据
{
        unsigned char i,d;
        for(i=0;i<8;i++) {
                d >>= 1;
                DS2401Bus = 0;                    // 至少拉低总线1us
                _nop_();_nop_();_nop_();             
                DS2401Bus = 1;            // 释放总线
                _nop_();_nop_();_nop_();_nop_();_nop_();
                if(DS2401Bus == 1) d |= 0x80;           // 读取数据
                delay_90us();                // 90us
        }
        return d;
}

unsigned char crctest()         //进行CRC校验
{
        unsigned char i1, i2, crc=0;
        for(i1=0; i1<8; i1++) {
                crc ^= DS2401IDBuf[i1];
                for(i2=0; i2<8; i2++) {
                        if (crc & 0x01) 
                                crc = (crc >> 1) ^ 0x8C;
                        else
                                crc >>= 1;
                }
        }
        return (crc);
}

unsigned char ReadRS2401ID()         //读出DS2401的
{
        unsigned char i;
        if (!InitDS2401()) return(0);
        WriteDS2401(0x33);
        for(i=0;i<8;i++) DS2401IDBuf[i]=ReadDS2401();
        if (crctest() != 0) return(0);
        return(1);         //CRC校验成功
}

推荐阅读

史海拾趣

Gigabit Logic Inc公司的发展小趣事
通过控制脉冲信号的频率或占空比,可以实现更精细的调速范围。
Ceratech Corporation公司的发展小趣事

在电子行业中,压敏技术是一项重要的技术。Ceratech Corporation公司针对这一领域进行了深入研究和探索。公司研发团队经过多次试验和改进,成功研发出具有自主知识产权的压敏产品。这些产品不仅具有高灵敏度和高稳定性,而且能够适应各种复杂环境。通过压敏技术的研发与应用,Ceratech Corporation进一步提升了其在电子行业的技术实力和市场竞争力。

Digital Core Design公司的发展小趣事

1988年,Core Design由Jeremy Heath-Smith创立,起初仅有8名员工和1万6千英镑的注册资金。这家新兴的游戏开发公司很快凭借其首款游戏《Rick Dangerous》在英国游戏市场崭露头角。这款游戏凭借其独特的游戏机制和引人入胜的故事情节,迅速登上英国游戏销量榜的榜首,并赢得了欧洲年度游戏奖,为Core Design的未来发展奠定了坚实的基础。

Global Specialties公司的发展小趣事

在电子技术的不断推动下,Global Specialties始终保持对新技术的高度敏感。公司不断投入研发资源,对现有产品进行升级换代,并推出了一系列具有创新性的新产品。例如,公司开发的智能测试仪器能够自动完成复杂的测试任务,大大提高了测试效率和准确性。这些技术创新不仅巩固了Global Specialties在业内的领先地位,还为公司带来了更多的商业机会。

Andersen Laboratories Inc公司的发展小趣事

为了更好地服务全球客户,AnalogicTech积极实施全球化运营策略。公司在亚洲和大中华地区建立了广泛的晶圆制造和后端合作伙伴网络,包括香港地区、上海和台湾地区的台北。此外,AnalogicTech还迁入香港科技园,将深圳地区纳入业务版图,提高在中国大陆的销售情况,特别是珠江三角洲地区。

Akustica(Bosch)公司的发展小趣事

自1997年成立以来,AnalogicTech便致力于技术创新,不断推动电子行业的发展。公司总部位于硅谷,设计中心则分布在圣塔克拉拉和上海,汇聚了全球顶尖的研发人才。凭借深厚的技术底蕴和创新能力,AnalogicTech成功研发出一系列具有颠覆性的产品,为当今最具创造性的消费品提供了强大的技术支持。

问答坊 | AI 解惑

Win ce 5.0 下SD卡驱动程序中的"sdbusdriver"

微软自带的Bus层驱动程序中,在其下的文件sdhceventhandlers.cpp下有一个slotstatuschange函数,这个函数是一个死循环专门负责卡插入拨出时的加载和卸载还有设备中断,在循环中有一个pWorkItem->GetMessage(),用来等待消息,以控制循环。有没有高手 ...…

查看全部问答>

MSP430F149单片机,串口通信

我使用USART1模块进行串口通讯,但调试的时候发现程序进不了中断。 相关代码: #include \"msp430x14x.h\" #define uchar unsigned char #define uint  unsigned int #define URXD1 BIT7 #define UTXD1 BIT6 uchar dataSedBuffer[100] ...…

查看全部问答>

新人请教:CE6 模拟器

    wince6.0 编译产生Nk.bin后,如何在pc上模拟啊,怎么设置或者是否要安装其他软件?…

查看全部问答>

RS232发送数据问题

我用单片机IO口模拟RS232通讯,单片机给PC机传数据。但是我不知道PC机的串口数据是如何读取的,因此我就不知道如何发送0和1.比如,串口采用的N8.1格式的数据吗?要发送一个数字或者一个字母(如A),发送的是ASCII码吗?先发送低位还是高位?能具体 ...…

查看全部问答>

C8051F版数字湿度计调试2---硬件调试完成,OLED可显示了!

硬件调试完成,OLED可显示了!           [ 本帖最后由 sdjntl 于 2010-8-17 14:36 编辑 ]…

查看全部问答>

请教:关于LSD-MSP430PRGS-IIIA编程器

请教:关于LSD-MSP430PRGS-IIIA编程器的BSL密码文件,在说明书中提到 “BSL 密码文件:装载代码的密码文件,芯片熔丝烧掉以后,程序需要更新,但是不希望信息FLASH 里的数据被擦除的情况下使用这种方法,进行这种操作时,务必需要执行以下操作:加 ...…

查看全部问答>

请教:Quartus6.0中打开SOPC打不开,出现at.java.awt....(Unknown Source)

请教各路高手:Quartus6.0中点击SOPC打不开,出现很多诸如at.java.awt....(Unknown Source)          注:Nois 已经安装。           此问题困我很久了,望高手指点迷津。 ...…

查看全部问答>

配置寄存器

编写程序的时候怎么依据datasheet的内容配置寄存器啊,datasheet的配置原理我觉得有些难懂,跪求高手指导。。。…

查看全部问答>

关于pic的IIC通信写地址问题

本人利用主机给从机发送数据,如何利用主机给从机写地址…

查看全部问答>

nowECC v2.17 使用疑问,芯片TMS570LS1227-144脚

我是用TMS570LS1227-144脚芯片,在生成ECC时如下配置不明确, memory map 应该是_f021 8M还是16M? 若使用命令“nowecc -i file. out -a -o fileecc.out -f021 8M”则生成附加ECC的.out文件。 利用这种方案生成.out文件烧录至FLASH中是否合理! ...…

查看全部问答>