问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

在单片机上用定时器做延时怎么用比如在DS18B20中延时要求那么精确

发布网友 发布时间:2022-04-30 20:31

我来回答

5个回答

热心网友 时间:2023-10-10 21:53

用定时器,定时1ms,每当到了、中断,就把 n1、n2、n3,分别加一,然后退出中断。
在主函数中,分别检测n1、n2、n3是否到了50、30、60,到了,用一个定时器,基本就可以满足所有的定时需求。

热心网友 时间:2023-10-10 21:54

我这没有具体程序,定时器的程序太依赖片子上定时器的硬件了,涉及相当多的配置字和状态寄存器控制寄存器,给你个思路。
看主频是多少,有没有分频,再看定时器的配置字,有没有在此处分频,就能算出定时器计一个数的时间,设置初始的计数值,有的片子是从小到大计数,溢出中断,有的是从大到小,归零中断,有的可以通过配置字自由选择。这些是初始化定时器,还包括刷新方式和启动定时器。主程序:

刚才的初始化定时器;
初始化定时器中断(定时器中断使能);
...
if(中断标志位置位) //表示定时器时间到
{
。。。。
}
清除中断 //要一轮一轮的不停中断要加循环
}

定时器计数时不占CPU资源,它的计数精度高,CPU可以先干别的,等它中断了再干需要定时的事。注意定时器中断级别,避免跟其它中断冲突。

热心网友 时间:2023-10-10 21:54

给你个51的,其实延时不需要那么准确的,你可以用_nop_()延时的,在头文件#include<intrins.h>中,

#include <reg52.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2; //温度传感器信号线
sbit la=P2^6; //数码管段选线
sbit wela=P2^7; //数码管位选线
sbit beep=P2^3; //蜂鸣器

uint temp;
float f_temp;
uint warn_l1=260;
uint warn_l2=250;
uint warn_h1=300;
uint warn_h2=320;

sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;

unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0xbf,0x86,
0xdb,0xcf,0xe6,0xed,
0xfd,0x87,0xff,0xef}; //不带小数点的编码

void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void dsreset(void) //18B20复位,初始化函数
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}

bit tempreadbit(void) //读1位函数
{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return (dat);
}

uchar tempread(void) //读1个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}

void tempwritebyte(uchar dat) //向18B20写一个字节数据
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写 1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写 0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}

}
}

void tempchange(void) //DS18B20 开始获取温度并转换
{
dsreset();
delay(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}

uint get_temp() //读取寄存器中存储的温度数据
{
uchar a,b;

dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread(); //读低8位
b=tempread(); //读高8位
temp=b;
temp<<=8; //两个字节组合为1个字
temp=temp|a;
f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
return temp; //temp是整型
}

////////////////////显示程序//////////////////////////
void display(uchar num,uchar dat)
{
uchar i;
la=0;
P0=table[dat];
la=1;
la=0;

wela=0;
i=0XFF;
i=i&(~((0X01)<<(num)));
P0=i;
wela=1;
wela=0;
delay(1);
}

void dis_temp(uint t)
{
uchar i;
i=t/100;
display(0,i);
i=t%100/10;
display(1,i+10);
i=t%100%10;
display(2,i);
}
//////////////////////////////////////////////
void warn(uint s,uchar led) //蜂鸣器报警声音 ,s控制音调
{
uchar i;i=s;
la=0;
wela=0;

beep=0;
P1=~(led);
while(i--)
{
dis_temp(get_temp());
}
beep=1;
P1=0XFF;
i=s;
while(i--)
{
dis_temp(get_temp());
}
}
void deal(uint t)
{
uchar i;
if((t>warn_l2)&&(t<=warn_l1)) //大于25度小于27度
{
warn(40,0x01);

}
else if(t<=warn_l2) //小于25度
{
warn(10,0x03);
}
else if((t<warn_h2)&&(t>=warn_h1)) //小于32度大于30度
{
warn(40,0x04);
}
else if(t>=warn_h2) //大于32度
{
warn(10,0x0c);
}
else
{
i=40;
while(i--)
{
dis_temp(get_temp());
}
}
}

void init_com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}

void comm(char *parr)
{
do
{
SBUF = *parr++; //发送数据
while(!TI); //等待发送完成标志为1
TI =0; //标志清零
}while(*parr); //保持循环直到字符为'\0'
}

void main()
{
uchar buff[4],i;
la=0;
wela=0;
init_com();
while(1)
{
tempchange();
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
deal(temp);

sprintf(buff,"%f",f_temp);

for(i=10;i>0;i--)
{
dis_temp(get_temp());}

comm(buff);

for(i=10;i>0;i--)
{
dis_temp(get_temp());}

}
}
你自己修改一下,这个除了基本功能外还有和电脑连接,向电脑发送数据的功能。是郭天翔写的,你看看吧

热心网友 时间:2023-10-10 21:55

启动内部定时器,开定时器中断
最好是用汇编,这样比较精确,
你可以去查一下每步指令所暂用
的时间,然后再修正一下定时器初值就可以了

热心网友 时间:2023-10-10 21:55

首先要戒掉手撸的不良习性,保持积极乐观的生活态度。其次是加强锻炼。第三是辅助食物调里。每次提前喷涂些 /耏美而/可以多了20多分钟,自己可以骑车游泳锻炼!
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
华为p7支持法语操作系统? 大白鲨HD6750 1GB GDDR5白金版这个显卡怎么样? 请高手们看看我的配置,加装显卡精影HD6670和HD6750哪个比较合适点... 蓝宝石HD 6750 1GB GDDR5白金版基本参数 ...HD5770 HD6750 HD6670 这几个显卡哪个好一些?大神们帮帮忙 蓝宝HD6750 1GB GDDR5白金版重要参数 ...是蓝宝石 HD6670 1G DDR5 白金版 HD6770 1G DDR5 白金版 HD6750 1G... 蓝宝石: HD6750/1G 黄金版和HD6670 1GB GDDR5白金版哪个好点啊?我的... 如何理解“从众”心理是一把“双刃剑”。 领动用5W30还是用5W40啊 多方达电器上市了吗? s7-200系列西门子定时器t37在计数时需要使能端一直有效吗 沈阳大唐光伏能源有限公司哈尔滨分公司怎么样? 哈尔滨中博路灯厂怎么样? 关于定时器如何触发定时器中断? 哈尔滨那家太阳能路灯质量最好 plc定时器名词解释 日普 冰熊 赛亿 奥马, 这几个冰箱品牌哪个相对质量好,噪音小的? 单片机里的定时器与定时器中断是两个东西。 stm32的定时器,能不能让定时器在指定的条件下开始计时?比如说,我用if语句判断,if成立定时器 定时器0中断使能的符号TF0是于IE的第几位? 鼻子右边有颗黑痣 代表什么啊 plc定时器ton和tof stm32定时器输出pwm,预装载寄存器为什么要被使能,而定时器中断时却没有看到使能预装载寄存器呢? 脖子右侧有个痣是什么意思 单片机定时器0中断使能什么意思? 痔的含义是什么 pwm调制,定时器由输出使能吗 stm32系统滴答定时器怎么使能 女生右手无名指长痣 360怎么调屏幕分辨率 关于合泰单片机的定时器中断函数,看一下这个函数的意思 买冰箱选什么牌子的好? xbox360 怎样调节分辨率? 格兰仕冰箱和美菱冰箱哪个好 太阳能灯生产厂家 用360驱动重新装系统后,屏幕分辨率怎么不能调整了。怎么解决? 太阳能路灯厂家这么多?我该选哪家啊??、 xbox360如何调视窗分辨率 太阳能信号灯厂家推荐 xbox360盲调分辨率教程,或者恢复初始设置,谢谢! 东风日产车子自带360可以调分辨率吗? 豆汁怎么做? XBOX360 怎样调分辨率? 怎么样煮豆汁 脚底病毒疣用液氮冷冻后多久能好以及注意事项 跖疣冷冻后几天可以看到效果 液氮冷冻治疗瘊子后要痛多久? 在家怎么做老北京豆汁 跖疣冷冻后结痂掉了之后,原来长跖疣的地方还是硬硬的有些凸起,是不是没治好啊