51单片机不用定时器毫秒级延时
时间: 2023-07-02 15:04:44 浏览: 69
在51单片机中,如果不使用定时器,可以使用延时循环来进行毫秒级延时。具体步骤如下:
1. 定义一个计数变量,作为循环计数器。
2. 循环一定的次数,每次循环让计数器自增1。
3. 在循环内部加入NOP指令,以消耗CPU的时间。
4. 判断计数器是否达到指定的值,如果达到则退出循环。
下面是一个简单的示例代码:
```c
void delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<114;j++);
}
```
在上面的代码中,114是经过实验得到的一个经验值,可以根据实际情况进行调整。注意,由于循环消耗CPU时间,因此在延时期间单片机无法执行其他任务。
相关问题
12M晶振51单片机不用定时器毫秒级延时
可以使用循环实现毫秒级延时,但这种方法会占用CPU资源,不太可靠。更好的方法是使用外部中断或者定时器来实现延时。对于12M晶振的51单片机,可以使用定时器来实现毫秒级延时,具体方法如下:
1. 配置定时器T0或T1,将其设置为定时1ms的模式;
2. 在定时器中断服务程序中,设置一个标志位,表示已经过了1ms;
3. 在需要延时的地方,先清除标志位,然后进入一个循环,等待标志位被设置;
4. 当标志位被设置时,表示已经过了1ms,跳出循环,延时完成。
下面是一个示例代码:
```c
#include <reg51.h>
sbit led = P1^0; //定义LED连接的IO口
volatile unsigned int count = 0; //计数器
//定时器中断服务程序
void timer0_isr() interrupt 1
{
count++; //计数器加1
}
//延时1ms
void delay_ms()
{
count = 0; //清零计数器
while(count < 1000); //等待计数器达到1000
}
void main()
{
TMOD = 0x01; //设置定时器T0为模式1
TH0 = 0xFC; //设置定时器T0的初值为0xFC67,定时1ms
TL0 = 0x67;
ET0 = 1; //使能定时器T0中断
EA = 1; //使能总中断
TR0 = 1; //启动定时器T0
while(1)
{
led = 0; //点亮LED
delay_ms(); //延时1ms
led = 1; //熄灭LED
delay_ms(); //延时1ms
}
}
```
在上述代码中,我们使用定时器T0来实现1ms的定时,并在定时器中断服务程序中对一个计数器进行累加。在延时函数中,我们清零计数器,并在一个循环中等待计数器达到1000,即1ms的时间。当计数器达到1000时,跳出循环,延时完成。
定时器毫秒级延时函数
很多单片机都有自己的定时器模块,可以用来实现毫秒级的延时函数。下面以STM32为例,介绍一种实现定时器毫秒级延时函数的方法:
1. 配置定时器:选择一个定时器,配置为向上计数模式,时钟源选择内部时钟,预分频系数为72-1,自动重载值为1000-1,这样定时器的计数频率就为1MHz,计数器每计数1次,时间就增加1us。
2. 编写初始化函数:初始化定时器,使其开始计数,并开启定时器中断。
3. 编写中断服务函数:在中断服务函数中,判断是否为定时器溢出中断,如果是,则将计数器清零。
4. 编写延时函数:在延时函数中,先保存当前的计数器值,然后进入循环,等待计数器的值增加到指定的延时时间,最后返回延时时间。
下面是一个示例代码:
```c
#include "stm32f10x.h"
volatile uint32_t g_tick = 0;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
g_tick++;
}
}
void Delay_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Delay_ms(uint32_t ms)
{
uint32_t tickstart = g_tick;
while ((g_tick - tickstart) < ms);
}
int main(void)
{
Delay_Init();
while (1)
{
// 延时1000ms
Delay_ms(1000);
// do something
}
}
```