一个51单片机延时任意秒,毫秒,微妙的C语言程序
时间: 2025-01-01 19:35:30 浏览: 21
在51单片机上实现定时器延时功能,通常使用的是硬件定时器如Timer0或Timer1配合中断处理机制。这里提供一种基本的方法,使用中断来实现大约的延时,因为51系列单片机精确到微秒级的延时可能会受限于硬件和CPU速度。
下面是一个简单的示例,通过设置定时器溢出次数来模拟延时:
```c
#include <reg52.h> // 包含51单片机的寄存器定义
// 定义定时器初值
unsigned int count = 65536; // 对于11MHz的晶振,每计满一次溢出约为11ms
unsigned char delay_ms = 1000; // 目标延迟时间,这里是1s
void delay(unsigned int ms) {
while (delay_ms--) {
TMOD = 0x01; // 设置定时器工作模式1,8位自动重装定时器
TH0 = count / ms; // 计算并加载初始定时器值
TL0 = count % ms;
EA = 1; // 开启全局中断
ET0 = 1; // 启动定时器0中断
TR0 = 1; // 启动定时器0
while (!(TF0)); // 等待定时器溢出
TF0 = 0; // 清除溢出标志
}
}
int main(void) {
delay(1000); // 这里延时1秒
return 0;
}
相关问题
基于51单片机控制舵机转动任意角度的详细代码
以下是基于51单片机控制舵机转动任意角度的详细代码:
```C
#include <reg51.h> // 引入51单片机头文件
sbit servo = P1^0; // 定义舵机控制引脚
void main() {
unsigned int angle = 0; // 定义角度变量
TMOD = 0x01; // 设置定时器0为模式1
TH0 = 0xFC; // 设定初值,使定时器每10ms中断一次
TL0 = 0x67;
TR0 = 1; // 启动定时器0
while(1) {
if (angle == 0) { // 如果角度为0,舵机转到初始位置
servo = 1;
delay(20); // 延时20ms
servo = 0;
delay(180); // 延时180ms
} else if (angle == 90) { // 如果角度为90,舵机转到中间位置
servo = 1;
delay(15); // 延时15ms
servo = 0;
delay(185); // 延时185ms
} else if (angle == 180) { // 如果角度为180,舵机转到最大位置
servo = 1;
delay(10); // 延时10ms
servo = 0;
delay(190); // 延时190ms
} else { // 如果角度为其他值,计算脉冲宽度并转动舵机
unsigned int pulse_width = (unsigned int)(angle / 180.0 * 2000.0 + 500.0); // 计算脉冲宽度
servo = 1;
delay_us(pulse_width); // 延时脉冲宽度微秒
servo = 0;
delay_us(20000 - pulse_width); // 延时20ms减去脉冲宽度微秒
}
}
}
void timer0_isr() interrupt 1 { // 定时器0中断服务程序
TH0 = 0xFC; // 重新赋初值
TL0 = 0x67;
}
void delay(unsigned int ms) { // 毫秒级延时函数
unsigned int i, j;
for(i = ms; i > 0; i--) {
for(j = 110; j > 0; j--);
}
}
void delay_us(unsigned int us) { // 微秒级延时函数
unsigned int i, j;
for(i = us; i > 0; i--) {
for(j = 2; j > 0; j--);
}
}
```
上述代码中,使用定时器0每10ms中断一次,并在中断服务程序中重新赋初值,以保证控制舵机的脉冲宽度准确。然后使用一个无限循环,根据角度值计算脉冲宽度并转动舵机。其中,0度、90度和180度的脉冲宽度已经确定,其他角度的脉冲宽度通过公式计算得到。延时函数分别为毫秒级和微秒级,用于控制舵机转动和脉冲宽度延时。
51单片机编程简单计算器
以下是51单片机编程简单计算器的程序示例,可以实现加、减、乘、除四种基本运算。
```
#include <reg52.h> // 导入单片机头文件
sbit LED = P2^0; // 定义LED灯所在的引脚
sbit KEY_ADD = P1^0; // 定义加法键所在的引脚
sbit KEY_SUB = P1^1; // 定义减法键所在的引脚
sbit KEY_MUL = P1^2; // 定义乘法键所在的引脚
sbit KEY_DIV = P1^3; // 定义除法键所在的引脚
int num1 = 0; // 第一个操作数
int num2 = 0; // 第二个操作数
int result = 0; // 计算结果
void delay(int ms) // 延时函数
{
int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 110; j++);
}
}
void main()
{
while (1) { // 无限循环
if (KEY_ADD == 0) { // 按下加法键
num1 = 10; // 设置第一个操作数为10
num2 = 20; // 设置第二个操作数为20
result = num1 + num2; // 计算结果
LED = 0; // 点亮LED灯
delay(500); // 延时500毫秒
LED = 1; // 熄灭LED灯
}
if (KEY_SUB == 0) { // 按下减法键
num1 = 30; // 设置第一个操作数为30
num2 = 15; // 设置第二个操作数为15
result = num1 - num2; // 计算结果
LED = 0; // 点亮LED灯
delay(500); // 延时500毫秒
LED = 1; // 熄灭LED灯
}
if (KEY_MUL == 0) { // 按下乘法键
num1 = 5; // 设置第一个操作数为5
num2 = 8; // 设置第二个操作数为8
result = num1 * num2; // 计算结果
LED = 0; // 点亮LED灯
delay(500); // 延时500毫秒
LED = 1; // 熄灭LED灯
}
if (KEY_DIV == 0) { // 按下除法键
num1 = 50; // 设置第一个操作数为50
num2 = 10; // 设置第二个操作数为10
result = num1 / num2; // 计算结果
LED = 0; // 点亮LED灯
delay(500); // 延时500毫秒
LED = 1; // 熄灭LED灯
}
}
}
```
在程序示例中,我们定义了四个按键和一个LED灯。按下不同的按键,就会进行不同的运算,并在LED灯上显示结果。程序中的操作数和结果都是整数类型,如果需要进行浮点数运算,则需要使用浮点数类型。同时,程序中的计算方式是固定的,如果需要实现输入任意操作数进行计算的功能,则需要使用键盘输入等其他方式。
阅读全文