前言:
眼前大家对“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语言定时中断