像下面这样,我用t0_sr1定时15ms,用t0_sr2定时100ms。但都是调用T0定时器,这样写可以吗?
void t0_sr1() interrupt 1{
}
void t0_sr2() interrupt 1{
}
void t0_sr3() interrupt 1{
}
肯定不能这样写啊,一个中断只能有1个中断服务函数
你这种应用,可以取多个定时周期的最大公约数,比如5毫秒,在中断里计数,计数到3,执行15毫秒的任务,计数到20,执行100毫秒的任务。
作为语言模型AI,我无法针对代码给出具体的解决方案。但是我可以根据信息给出一些指导和建议。
首先需要了解的是,51单片机的定时器只有一个,不能被多个服务函数同时调用。因此,不建议在多个服务函数中分别设置不同的定时器时间。相反,可以在一个服务函数中设置定时器的时间,并在定时器中断函数中处理不同的任务。具体步骤可以如下:
1.先定义一个任务列表,包含需要定时执行的任务以及它们的执行时间。
typedef struct {
void (*task)(void); // 任务函数指针
uint16_t interval; // 任务执行时间间隔
uint16_t count_down; // 倒计时器
} task_t;
task_t tasks[] = {
{task1, 15, 0}, // 每隔15ms执行task1
{task2, 100, 0} // 每隔100ms执行task2
};
2.在一个服务函数中,调用定时器并开始倒计时。
void start_timer(void) {
TH0 = (65536 - 1000) >> 8; // 定时器初值,这里设为1ms
TL0 = (65536 - 1000) & 0xff;
TMOD |= 0x01; // 设置为模式1
IE |= 0x82; // 允许定时器0中断
TR0 = 1; // 启动定时器
}
void service_function(void) {
start_timer();
while(1) {
// 执行其他任务
}
}
3.在定时器中断函数中处理任务列表。每当定时器中断产生时,遍历任务列表,将每个任务的倒计时器减一,如果某个任务的倒计时器变为0,则执行该任务并重置倒计时器。具体代码可以如下:
void timer0_isr() interrupt 1 {
uint8_t i;
for(i = 0; i < (sizeof(tasks) / sizeof(task_t)); i++) {
tasks[i].count_down--;
if(tasks[i].count_down == 0) {
tasks[i].task();
tasks[i].count_down = tasks[i].interval;
}
}
TH0 = (65536 - 1000) >> 8; // 重新设置定时器初值
TL0 = (65536 - 1000) & 0xff;
}
这种方法可以避免多个服务函数同时调用定时器产生的冲突和错误,并实现了多个定时任务的同时执行,建议采用。