Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
STM32
输入捕获
stm32的输入捕获驱动
发布于 2020-08-23 14:36:44 浏览:3071
订阅该版
最近项目中用到了输入捕获。发现rtthread没有stm32的输入捕获驱动。 于是自己做了一个,基于TIM4,其他的TIMER应该没有太大区别,每个通道都可以独立捕获。 ``` #include
#define DRV_DEBUG #define LOG_TAG "drv.tcap" #include
#include
#define BSP_USING_TIMER_CAPTURE #if defined(BSP_USING_TIMER_CAPTURE) #include
#include "drv_config.h" /* Private typedef --------------------------------------------------------------*/ typedef struct stm32_capture_device{ struct rt_inputcapture_device parent; TIM_HandleTypeDef timer; uint32_t u32LastCnt; uint32_t u32PluseCnt; uint8_t input_data_level; uint8_t not_first_edge; uint32_t over_under_flowcount; IRQn_Type irq; uint8_t ch; char* name; }stm32_capture_device; /* Private functions ------------------------------------------------------------*/ static rt_err_t stm32_capture_init(struct rt_inputcapture_device *inputcapture); static rt_err_t stm32_capture_open(struct rt_inputcapture_device *inputcapture); static rt_err_t stm32_capture_close(struct rt_inputcapture_device *inputcapture); static rt_err_t stm32_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us); /* Private define ---------------------------------------------------------------*/ /* Public functions -------------------------------------------------------------*/ /* Private variables ------------------------------------------------------------*/ enum { #ifdef BSP_USING_TIMER4_CAPTURE #ifdef TIMER4_CAPTURE_CHANNEL1 TIMER4_CAPTURE_CH1_INDEX, #endif #ifdef TIMER4_CAPTURE_CHANNEL2 TIMER4_CAPTURE_CH2_INDEX, #endif #ifdef TIMER4_CAPTURE_CHANNEL3 TIMER4_CAPTURE_CH3_INDEX, #endif #ifdef TIMER4_CAPTURE_CHANNEL4 TIMER4_CAPTURE_CH3_INDEX, #endif #endif TIMER_CAPTURE_INDEX_MAX, }; static struct stm32_capture_device stm32_capture_obj[] = { #ifdef BSP_USING_TIMER4_CAPTURE #ifdef TIMER4_CAPTURE_CHANNEL1 TIMER4_CAPTURE_CH1_CONFIG, #endif #ifdef TIMER4_CAPTURE_CHANNEL2 TIMER4_CAPTURE_CH2_CONFIG, #endif #endif }; static struct rt_inputcapture_ops stm32_capture_ops = { .init = stm32_capture_init, .open = stm32_capture_open, .close = stm32_capture_close, .get_pulsewidth = stm32_capture_get_pulsewidth, }; /* Functions define ------------------------------------------------------------*/ void capture_updata_isr(struct stm32_capture_device* device) { /* TIM Update event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_UPDATE) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_UPDATE); for(uint8_t i = 0; i < TIMER_CAPTURE_INDEX_MAX; i++) device[i].over_under_flowcount++; } /* Capture compare 1 event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_CC1) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_CC1); #ifdef TIMER4_CAPTURE_CHANNEL1 uint32_t cnt = HAL_TIM_ReadCapturedValue(&device[TIMER4_CAPTURE_CH1_INDEX].timer, device[TIMER4_CAPTURE_CH1_INDEX].ch);//获取当前的捕获值. if(!device[TIMER4_CAPTURE_CH1_INDEX].not_first_edge){ //first device[TIMER4_CAPTURE_CH1_INDEX].not_first_edge = 1; device[TIMER4_CAPTURE_CH1_INDEX].input_data_level = 0; }else{ device[TIMER4_CAPTURE_CH1_INDEX].input_data_level = !device[TIMER4_CAPTURE_CH1_INDEX].input_data_level; device[TIMER4_CAPTURE_CH1_INDEX].u32PluseCnt = cnt + 0xffff * device[TIMER4_CAPTURE_CH1_INDEX].over_under_flowcount - device[TIMER4_CAPTURE_CH1_INDEX].u32LastCnt; rt_hw_inputcapture_isr(&device[TIMER4_CAPTURE_CH1_INDEX].parent, device[TIMER4_CAPTURE_CH1_INDEX].input_data_level); } if(device[TIMER4_CAPTURE_CH1_INDEX].input_data_level) __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH1_INDEX].timer, device[TIMER4_CAPTURE_CH1_INDEX].ch, TIM_INPUTCHANNELPOLARITY_FALLING); //切换捕获极性 else __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH1_INDEX].timer, device[TIMER4_CAPTURE_CH1_INDEX].ch, TIM_INPUTCHANNELPOLARITY_RISING); //切换捕获极性 device[TIMER4_CAPTURE_CH1_INDEX].over_under_flowcount = 0; device[TIMER4_CAPTURE_CH1_INDEX].u32LastCnt = cnt; HAL_TIM_IC_Start_IT(&device[TIMER4_CAPTURE_CH1_INDEX].timer, device[TIMER4_CAPTURE_CH1_INDEX].ch); #endif } /* Capture compare 2 event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_CC2) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_CC2); #ifdef TIMER4_CAPTURE_CHANNEL2 uint32_t cnt = HAL_TIM_ReadCapturedValue(&device[TIMER4_CAPTURE_CH2_INDEX].timer, device[TIMER4_CAPTURE_CH2_INDEX].ch);//获取当前的捕获值. if(!device[TIMER4_CAPTURE_CH2_INDEX].not_first_edge){ //first device[TIMER4_CAPTURE_CH2_INDEX].not_first_edge = 1; device[TIMER4_CAPTURE_CH2_INDEX].input_data_level = 0; }else{ device[TIMER4_CAPTURE_CH2_INDEX].input_data_level = !device[TIMER4_CAPTURE_CH2_INDEX].input_data_level; device[TIMER4_CAPTURE_CH2_INDEX].u32PluseCnt = cnt + 0xffff * device[TIMER4_CAPTURE_CH2_INDEX].over_under_flowcount - device[TIMER4_CAPTURE_CH2_INDEX].u32LastCnt; rt_hw_inputcapture_isr(&device[TIMER4_CAPTURE_CH2_INDEX].parent, device[TIMER4_CAPTURE_CH2_INDEX].input_data_level); } if(device[TIMER4_CAPTURE_CH2_INDEX].input_data_level) __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH2_INDEX].timer, device[TIMER4_CAPTURE_CH2_INDEX].ch, TIM_INPUTCHANNELPOLARITY_FALLING); //切换捕获极性 else __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH2_INDEX].timer, device[TIMER4_CAPTURE_CH2_INDEX].ch, TIM_INPUTCHANNELPOLARITY_RISING); //切换捕获极性 device[TIMER4_CAPTURE_CH2_INDEX].over_under_flowcount = 0; device[TIMER4_CAPTURE_CH2_INDEX].u32LastCnt = cnt; HAL_TIM_IC_Start_IT(&device[TIMER4_CAPTURE_CH2_INDEX].timer, device[TIMER4_CAPTURE_CH2_INDEX].ch); #endif } /* Capture compare 3 event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_CC3) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_CC3); #ifdef TIMER4_CAPTURE_CHANNEL3 uint32_t cnt = HAL_TIM_ReadCapturedValue(&device[TIMER4_CAPTURE_CH3_INDEX].timer, device[TIMER4_CAPTURE_CH3_INDEX].ch);//获取当前的捕获值. if(!device[TIMER4_CAPTURE_CH3_INDEX].not_first_edge){ //first device[TIMER4_CAPTURE_CH3_INDEX].not_first_edge = 1; device[TIMER4_CAPTURE_CH3_INDEX].input_data_level = 0; }else{ device[TIMER4_CAPTURE_CH3_INDEX].input_data_level = !device[TIMER4_CAPTURE_CH3_INDEX].input_data_level; device[TIMER4_CAPTURE_CH3_INDEX].u32PluseCnt = cnt + 0xffff * device[TIMER4_CAPTURE_CH3_INDEX].over_under_flowcount - device[TIMER4_CAPTURE_CH3_INDEX].u32LastCnt; rt_hw_inputcapture_isr(&device[TIMER4_CAPTURE_CH3_INDEX].parent, device[TIMER4_CAPTURE_CH3_INDEX].input_data_level); } if(device[TIMER4_CAPTURE_CH3_INDEX].input_data_level) __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH3_INDEX].timer, device[TIMER4_CAPTURE_CH3_INDEX].ch, TIM_INPUTCHANNELPOLARITY_FALLING); //切换捕获极性 else __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH3_INDEX].timer, device[TIMER4_CAPTURE_CH3_INDEX].ch, TIM_INPUTCHANNELPOLARITY_RISING); //切换捕获极性 device[TIMER4_CAPTURE_CH3_INDEX].over_under_flowcount = 0; device[TIMER4_CAPTURE_CH3_INDEX].u32LastCnt = cnt; HAL_TIM_IC_Start_IT(&device[TIMER4_CAPTURE_CH3_INDEX].timer, device[TIMER4_CAPTURE_CH3_INDEX].ch); #endif } /* Capture compare 4 event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_CC4) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_CC4); #ifdef TIMER4_CAPTURE_CHANNEL4 uint32_t cnt = HAL_TIM_ReadCapturedValue(&device[TIMER4_CAPTURE_CH4_INDEX].timer, device[TIMER4_CAPTURE_CH4_INDEX].ch);//获取当前的捕获值. if(!device[TIMER4_CAPTURE_CH4_INDEX].not_first_edge){ //first device[TIMER4_CAPTURE_CH4_INDEX].not_first_edge = 1; device[TIMER4_CAPTURE_CH4_INDEX].input_data_level = 0; }else{ device[TIMER4_CAPTURE_CH4_INDEX].input_data_level = !device[TIMER4_CAPTURE_CH4_INDEX].input_data_level; device[TIMER4_CAPTURE_CH4_INDEX].u32PluseCnt = cnt + 0xffff * device[TIMER4_CAPTURE_CH4_INDEX].over_under_flowcount - device[TIMER4_CAPTURE_CH4_INDEX].u32LastCnt; rt_hw_inputcapture_isr(&device[TIMER4_CAPTURE_CH4_INDEX].parent, device[TIMER4_CAPTURE_CH4_INDEX].input_data_level); } if(device[TIMER4_CAPTURE_CH4_INDEX].input_data_level) __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH4_INDEX].timer, device[TIMER4_CAPTURE_CH4_INDEX].ch, TIM_INPUTCHANNELPOLARITY_FALLING); //切换捕获极性 else __HAL_TIM_SET_CAPTUREPOLARITY(&device[TIMER4_CAPTURE_CH4_INDEX].timer, device[TIMER4_CAPTURE_CH4_INDEX].ch, TIM_INPUTCHANNELPOLARITY_RISING); //切换捕获极性 device[TIMER4_CAPTURE_CH4_INDEX].over_under_flowcount = 0; device[TIMER4_CAPTURE_CH4_INDEX].u32LastCnt = cnt; HAL_TIM_IC_Start_IT(&device[TIMER4_CAPTURE_CH4_INDEX].timer, device[TIMER4_CAPTURE_CH4_INDEX].ch); #endif } /* TIM Break input event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_BREAK) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_BREAK); } /* TIM Trigger detection event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_TRIGGER) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_IT_TRIGGER); } /* TIM commutation event */ if (__HAL_TIM_GET_FLAG(&device->timer, TIM_FLAG_COM) != RESET) { __HAL_TIM_CLEAR_IT(&device->timer, TIM_FLAG_COM); } } #ifdef BSP_USING_TIMER4_CAPTURE void TIM4_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); capture_updata_isr(stm32_capture_obj); /* leave interrupt */ rt_interrupt_leave(); } #endif static rt_err_t stm32_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us) { rt_err_t ret = RT_EOK; struct stm32_capture_device *stm32_capture; stm32_capture = (stm32_capture_device *)inputcapture; *pulsewidth_us = stm32_capture->u32PluseCnt; return -(ret); } static rt_err_t stm32_timer_capture_init(struct stm32_capture_device* device) { rt_err_t ret = RT_EOK; #if defined(BSP_USING_TIMER4_CAPTURE) static uint8_t TIM4_INIT = 0; if (device->timer.Instance == TIM4){ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; if(!TIM4_INIT){ device->timer.Init.Prescaler = 108-1; device->timer.Init.CounterMode = TIM_COUNTERMODE_UP; device->timer.Init.Period = 0xffff; device->timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; device->timer.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&device->timer) != HAL_OK){ Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&device->timer, &sClockSourceConfig) != HAL_OK){ Error_Handler(); } if (HAL_TIM_IC_Init(&device->timer) != HAL_OK){ Error_Handler(); } HAL_NVIC_SetPriority(device->irq, 3, 0); HAL_NVIC_EnableIRQ(device->irq); HAL_TIM_Base_Start_IT(&device->timer); TIM4_INIT = 1; } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; if (HAL_TIM_IC_ConfigChannel(&device->timer, &sConfigIC, device->ch) != HAL_OK){ Error_Handler(); } } #endif return -(ret); } static rt_err_t stm32_capture_init(struct rt_inputcapture_device *inputcapture) { rt_err_t ret = RT_EOK; RT_ASSERT(inputcapture != RT_NULL); if (stm32_timer_capture_init((struct stm32_capture_device *) inputcapture) != RT_EOK){ rt_kprintf("Failed to initialize TIMER.\n"); ret = RT_ERROR; } return -(ret); } static rt_err_t stm32_capture_open(struct rt_inputcapture_device *inputcapture) { rt_err_t ret = RT_EOK; RT_ASSERT(inputcapture != RT_NULL); struct stm32_capture_device* device = (struct stm32_capture_device*)inputcapture; device->not_first_edge = 0; device->input_data_level = 0; device->over_under_flowcount = 0; device->u32LastCnt = 0; __HAL_TIM_SET_CAPTUREPOLARITY(&device->timer, device->ch, TIM_INPUTCHANNELPOLARITY_FALLING); HAL_TIM_IC_Start_IT(&device->timer, device->ch); return ret; } static rt_err_t stm32_capture_close(struct rt_inputcapture_device *inputcapture) { rt_err_t ret = RT_EOK; RT_ASSERT(inputcapture != RT_NULL); struct stm32_capture_device* device = (struct stm32_capture_device*)inputcapture; HAL_TIM_IC_Stop_IT(&device->timer, device->ch); return ret; } /* Init and register timer capture */ static int stm32_timer_capture_device_init(void) { struct stm32_capture_device *device; for (uint8_t i = 0; i < sizeof(stm32_capture_obj) / sizeof(stm32_capture_obj[0]); i++){ device = &stm32_capture_obj[i]; device->parent.ops = &stm32_capture_ops; if (rt_device_inputcapture_register(&device->parent, stm32_capture_obj[i].name, device)!= RT_EOK){ LOG_E("%s register failed", stm32_capture_obj[i].name); return -RT_ERROR; } } return 0; } INIT_DEVICE_EXPORT(stm32_timer_capture_device_init); #endif //#if defined(BSP_USING_TIMER_CAPTURE) ```
4
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
yushigengyu
这家伙很懒,什么也没写!
文章
2
回答
25
被采纳
0
关注TA
发私信
相关文章
1
裸机工程移植 RT-Thread
2
Keil MDK 移植 RT-Thread Nano
3
移植 Nano,rt_thread_mdelay()延迟时间不对
4
裸机工程移植 RT-Thread内核
5
关于利用0x68000000作为扩展sram?
6
STM32F413 SD 卡写入速度提升方法
7
STM32 RTC 闹钟
8
http_ota 提示no memory
9
studio中怎么把PB3 和PA15引脚设置为普通IO口使用?
10
求一份基于RTT系统封装好的STM32F1系列的FLASH操作程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
SFUD
msh
ulog
C++_cpp
MicroPython
本月问答贡献
三世执戟
5
个答案
1
次被采纳
KunYi
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
xiaorui
1
个答案
1
次被采纳
JonasWen
1
个答案
1
次被采纳
本月文章贡献
出出啊
1
篇文章
3
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部