你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
设置PA0为普通定时器,复用推挽输出,但是发现信号经过光耦之后高电平不到2V,不能进行脉冲计数,如果设置成中断输入,高电平是3.3V,请问这是啥原因?现有的电路能否实现脉冲计数功能?
举报
butterflyspring 发表于 2025-5-6 16:34 定时器作为计数功能,应该设为输入。</p> <p>楼主配置成输出,容易引起电平冲突。
设置为输入,可以用做中断,但不能做定时器计数功能,设置成复用推挽输出,主要是用它的复用功能设置成定时器引脚,输入功能我也试过了,进不了定时器计数功能
xmshao 发表于 2025-5-7 10:53 你现在问题是不能实现计数,除了硬件方面原因外,不排除配置方面原因。</p> <p>
芯片是STM32F407,引脚是PA0
定时器计数的初始化:
void gtim_timx_cnt_chy_init(uint16_t psc) { GPIO_InitTypeDef gpio_init_struct; TIM_SlaveConfigTypeDef tim_slave_config = {0}; GTIM_TIMX_CNT_CHY_CLK_ENABLE(); / 使能TIMx时钟 / GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE(); / 开启GPIOA时钟 /
g_timx_cnt_chy_handle.Instance = GTIM_TIMX_CNT; / 定时器x / g_timx_cnt_chy_handle.Init.Prescaler = psc; / 预分频系数 / g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; / 递增计数模式 / g_timx_cnt_chy_handle.Init.Period = 65535; / 自动重装载值 / HAL_TIM_IC_Init(&g_timx_cnt_chy_handle);
gpio_init_struct.Pin = GTIM_TIMX_CNT_CHY_GPIO_PIN; / 输入捕获的GPIO口 / gpio_init_struct.Mode = GPIO_MODE_AF_PP; / 复用推挽输出 / gpio_init_struct.Pull = GPIO_PULLDOWN; / 下拉 / gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; / 高速 / gpio_init_struct.Alternate = GTIM_TIMX_CNT_CHY_GPIO_AF; / 复用为捕获TIMx的通道 / HAL_GPIO_Init(GTIM_TIMX_CNT_CHY_GPIO_PORT, &gpio_init_struct);
/ 从模式:外部触发模式1 / tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; / 从模式:外部触发模式1 / tim_slave_config.InputTrigger = TIM_TS_TI1FP1; / 输入触发:选择 TI1FP1(TIMX_CH1) 作为输入源 / tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; / 触发极性:上升沿 / tim_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; / 触发预分频:无 / tim_slave_config.TriggerFilter = 0x0; / 滤波:本例中不需要任何滤波 / HAL_TIM_SlaveConfigSynchronization(&g_timx_cnt_chy_handle, &tim_slave_config);
HAL_NVIC_SetPriority(GTIM_TIMX_CNT_IRQn, 1, 3); / 设置中断优先级,抢占优先级1,子优先级3 / HAL_NVIC_EnableIRQ(GTIM_TIMX_CNT_IRQn); / 开启ITMx中断 /
__HAL_TIM_ENABLE_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE); / 使能更新中断 / HAL_TIM_IC_Start(&g_timx_cnt_chy_handle, GTIM_TIMX_CNT_CHY); / 开始捕获TIMx的通道y / }
关于商丘开餐饮手撕发票-商丘本地宝
关于信阳开餐饮手撕发票-信阳本地宝
关于洛阳开餐饮手撕发票-洛阳本地宝
关于许昌开餐饮手撕发票-许昌本地宝
关于廊坊开餐饮手撕发票-廊坊本地宝
关于汕头开餐饮手撕发票-汕头本地宝
关于扬州开餐饮手撕发票-扬州本地宝
关于镇江开餐饮手撕发票-镇江本地宝
关于呼和浩特开餐饮手撕发票-呼和浩特本地宝
关于南昌开餐饮手撕发票-南昌本地宝
楼主配置成输出,容易引起电平冲突。
不妨改为输入试试,最终目的是将输入电平在有效范围内且不能损坏IO引脚
设置为输入,可以用做中断,但不能做定时器计数功能,设置成复用推挽输出,主要是用它的复用功能设置成定时器引脚,输入功能我也试过了,进不了定时器计数功能
你先保证给到测量脚的信号电平是合适的、可识别的;
如果要使用TIMER的话,不知你的相关配置是怎样的。
按照你目前的做法,感觉你是希望从外部引入TIMER的计数时钟,此时你要将TIMER配置
在外部时钟模式1,时钟从TIMER的通道1或通道2的管脚进来。
因你连最基本的芯片型号信息也没说,不知你说的PA0是否某个TIMER的通道1或通道2的一个复用脚。
芯片是STM32F407,引脚是PA0
定时器计数的初始化:
void gtim_timx_cnt_chy_init(uint16_t psc) { GPIO_InitTypeDef gpio_init_struct; TIM_SlaveConfigTypeDef tim_slave_config = {0}; GTIM_TIMX_CNT_CHY_CLK_ENABLE(); / 使能TIMx时钟 / GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE(); / 开启GPIOA时钟 /
g_timx_cnt_chy_handle.Instance = GTIM_TIMX_CNT; / 定时器x / g_timx_cnt_chy_handle.Init.Prescaler = psc; / 预分频系数 / g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; / 递增计数模式 / g_timx_cnt_chy_handle.Init.Period = 65535; / 自动重装载值 / HAL_TIM_IC_Init(&g_timx_cnt_chy_handle);
gpio_init_struct.Pin = GTIM_TIMX_CNT_CHY_GPIO_PIN; / 输入捕获的GPIO口 / gpio_init_struct.Mode = GPIO_MODE_AF_PP; / 复用推挽输出 / gpio_init_struct.Pull = GPIO_PULLDOWN; / 下拉 / gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; / 高速 / gpio_init_struct.Alternate = GTIM_TIMX_CNT_CHY_GPIO_AF; / 复用为捕获TIMx的通道 / HAL_GPIO_Init(GTIM_TIMX_CNT_CHY_GPIO_PORT, &gpio_init_struct);
/ 从模式:外部触发模式1 / tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; / 从模式:外部触发模式1 / tim_slave_config.InputTrigger = TIM_TS_TI1FP1; / 输入触发:选择 TI1FP1(TIMX_CH1) 作为输入源 / tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; / 触发极性:上升沿 / tim_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; / 触发预分频:无 / tim_slave_config.TriggerFilter = 0x0; / 滤波:本例中不需要任何滤波 / HAL_TIM_SlaveConfigSynchronization(&g_timx_cnt_chy_handle, &tim_slave_config);
HAL_NVIC_SetPriority(GTIM_TIMX_CNT_IRQn, 1, 3); / 设置中断优先级,抢占优先级1,子优先级3 / HAL_NVIC_EnableIRQ(GTIM_TIMX_CNT_IRQn); / 开启ITMx中断 /
__HAL_TIM_ENABLE_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE); / 使能更新中断 / HAL_TIM_IC_Start(&g_timx_cnt_chy_handle, GTIM_TIMX_CNT_CHY); / 开始捕获TIMx的通道y / }
芯片是STM32F407,引脚是PA0
定时器计数的初始化:
void gtim_timx_cnt_chy_init(uint16_t psc) { GPIO_InitTypeDef gpio_init_struct; TIM_SlaveConfigTypeDef tim_slave_config = {0}; GTIM_TIMX_CNT_CHY_CLK_ENABLE(); / 使能TIMx时钟 / GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE(); / 开启GPIOA时钟 /
g_timx_cnt_chy_handle.Instance = GTIM_TIMX_CNT; / 定时器x / g_timx_cnt_chy_handle.Init.Prescaler = psc; / 预分频系数 / g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; / 递增计数模式 / g_timx_cnt_chy_handle.Init.Period = 65535; / 自动重装载值 / HAL_TIM_IC_Init(&g_timx_cnt_chy_handle);
gpio_init_struct.Pin = GTIM_TIMX_CNT_CHY_GPIO_PIN; / 输入捕获的GPIO口 / gpio_init_struct.Mode = GPIO_MODE_AF_PP; / 复用推挽输出 / gpio_init_struct.Pull = GPIO_PULLDOWN; / 下拉 / gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; / 高速 / gpio_init_struct.Alternate = GTIM_TIMX_CNT_CHY_GPIO_AF; / 复用为捕获TIMx的通道 / HAL_GPIO_Init(GTIM_TIMX_CNT_CHY_GPIO_PORT, &gpio_init_struct);
/ 从模式:外部触发模式1 / tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; / 从模式:外部触发模式1 / tim_slave_config.InputTrigger = TIM_TS_TI1FP1; / 输入触发:选择 TI1FP1(TIMX_CH1) 作为输入源 / tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; / 触发极性:上升沿 / tim_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; / 触发预分频:无 / tim_slave_config.TriggerFilter = 0x0; / 滤波:本例中不需要任何滤波 / HAL_TIM_SlaveConfigSynchronization(&g_timx_cnt_chy_handle, &tim_slave_config);
HAL_NVIC_SetPriority(GTIM_TIMX_CNT_IRQn, 1, 3); / 设置中断优先级,抢占优先级1,子优先级3 / HAL_NVIC_EnableIRQ(GTIM_TIMX_CNT_IRQn); / 开启ITMx中断 /
__HAL_TIM_ENABLE_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE); / 使能更新中断 / HAL_TIM_IC_Start(&g_timx_cnt_chy_handle, GTIM_TIMX_CNT_CHY); / 开始捕获TIMx的通道y / }
你的确配置了定时器的时钟模式1,从CH1过来的信号。
我看你配置捕获功能,被捕获的信号还是你说的CH1-PA0吗?如果PA0作为TIMER的外部时钟输入脚,
它是不能再作为捕获脚的。我看你启动了针对通道y的捕获,如果不是PA0所对应的脚倒没关系。
还有,不知你启动TIMER的计数功能没有,库函数的话就是__HAL_TIM_ENABLE(&htim),实质就是
将TIM->CR1的CEN置位。它置位后,每当外部时钟脚出现信号时就会自动进行计数。