龙空技术网

C语言构造软件定时器

yasindar 666

前言:

眼前大家对“c语言调试软件”大约比较着重,姐妹们都需要了解一些“c语言调试软件”的相关文章。那么小编在网上汇集了一些有关“c语言调试软件””的相关文章,希望我们能喜欢,咱们快快来学习一下吧!

嵌入式用定时器很常见,一般单片机有几个定时器,但项目中可能用到的定时业务会非常之多,一般的做法是用一个硬件定时器来模拟多个软件定时。请看下面代码:

// 定时器回调函数类型

typedef void (*timer_callback_t)(void *);

// 定时器结构体

typedef struct {

uint16_t cnt; // 计数器

uint16_t init_cnt; // 初始计数器值

bool expired; // 到期标志

timer_callback_t callback; // 到期回调函数

void *arg; // 回调函数参数

} timer_t;

#define MAX_TIMER_INDEX 10

// 定时器数组,最多可以同时使用10个定时器

static timer_t timers[MAX_TIMER_INDEX];

// 定时器初始化函数,需要指定硬件定时器和定时时间

void timer_init(TIM_HandleTypeDef *htim, uint16_t timer_period) {

HAL_TIM_Base_Start_IT(htim); // 启动硬件定时器中断

__HAL_TIM_SET_AUTORELOAD(htim, timer_period); // 设置硬件定时器定时时间

}

// 定时器添加函数,返回定时器的ID,如果添加失败则返回-1

int timer_add(uint16_t time_ms, timer_callback_t callback, void *arg) {

uint8_t i;

for (i = 0; i < MAX_TIMER_INDEX; i++) {

if (timers[i].callback == NULL) { // 找到一个空闲的定时器

timers[i].cnt = time_ms / HARD_TIMER_TIME;

timers[i].init_cnt = timers[i].cnt;

timers[i].expired = false;

timers[i].callback = callback;

timers[i].arg = arg;

return i; // 返回定时器的ID

}

}

return -1; // 定时器数组已满,添加失败

}

// 定时器删除函数,根据定时器ID删除对应的定时器

void timer_remove(int timer_id) {

timers[timer_id].callback = NULL;

}

// 定时器处理函数,需要在主循环中调用

void timer_process() {

uint8_t i;

for (i = 0; i < MAX_TIMER_INDEX; i++) {

if (timers[i].callback != NULL && timers[i].expired) { // 找到到期的定时器

timers[i].expired = false;

timers[i].callback(timers[i].arg); // 执行回调函数

timers[i].cnt = timers[i].init_cnt; // 重新设置计数器

}

}

}

// 硬件定时器中断处理函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

uint8_t i;

for (i = 0; i < MAX_TIMER_INDEX; i++) {

if (timers[i].callback != NULL) { // 找到正在使用的定时器

timers[i].cnt--;

if (timers[i].cnt == 0) {

timers[i].expired = true; // 定时器已到期

}

}

}

}

定时器可以控制灯闪烁,串口或CAN发送数据等。还可以用软件定时器来定时控制硬件设备。

标签: #c语言调试软件 #c语言定时器编程 #c语言控制闪烁 #c语言定时器1使用方法 #c语言定时中断