主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "PWM.h"
//#include "Timer.h"
#include "IC.h"
#include "OLED.h"
#include "ICFMM.h"
#define TIM3_CNT (*(volatile uint32_t *)(TIM3_BASE + 0x24))
uint32_t frequency = 10;
static uint32_t current_count = 0;
int main(void)
{
GPIO_TIM3_Init();
TIM3_Counter_Init();
TIM4_Init();
PWM_Init();
OLED_Init();
/*显示静态字符串*/
OLED_ShowString(1, 1, "Freq:00000Hz"); //1行1列显示字符串Freq:00000Hz
OLED_ShowString(2, 1, "CNT3:00000Hz"); //1行1列显示字符串Freq:00000Hz
// OLED_ShowString(2, 1, "Duty:00%");
// TIM2_SetCompare(30);//PWM设置占空比
TIM2_SetPrescaler(360-1); //频率设置 72MHZ/(pres+1)/(ARR+1)
while(1)
{
OLED_ShowNum(1, 6,frequency , 5); //不断刷新显示输入捕获测得的频率
// OLED_ShowNum(2, 6, IC_GetDuty(), 2); //不断刷新显示输入捕获测得的频率
OLED_ShowNum(2, 6, current_count , 5);
}
}
void TIM4_IRQHandler(void)
{
static uint16_t k = 50000;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
// 读取TIM3的计数值
frequency = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
}
// 清除中断标志
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
··
#include "stm32f10x.h" // Device header
void GPIO_TIM3_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM3_Counter_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM_ICInitTypeDef TIM_ICInitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// 配置PA6为TIM3_CH1输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// TIM3基础配置
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 计数器最大值65535
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 无预分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// // 配置外部时钟模式1(TI1上升沿触发)
// TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
// TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
// TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
// TIM_ICInitStructure.TIM_ICFilter = 0x0;
// TIM_ICInit(TIM3, &TIM_ICInitStructure);
// 配置从模式为外部时钟模式1
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // TI1作为触发源
// 启动TIM3
TIM_Cmd(TIM3, ENABLE);
}
void TIM4_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
// TIM4配置为1秒中断(系统时钟72MHz)
TIM_TimeBaseStructure.TIM_Period = 10000 - 1; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1; // 预分频7200,得到10kHz时钟
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
// 使能TIM4更新中断
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
// 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 启动TIM2
TIM_Cmd(TIM4, ENABLE);
}
问题是前文给出的函数能正确获得PWM的频率2000HZ,
void TIM4_IRQHandler(void)
{
static uint16_t k = 50000;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
// 读取TIM3的计数值
Delay_ms(50);
frequency = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
}
// 清除中断标志
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
我在中断里加50ms依然能测得正确的值即CNT = 2000,液晶显示2000HZ
但是我在它们之间加延时语句,CNT的值就变成了1900即
void TIM4_IRQHandler(void)
{
static uint16_t k = 50000;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
// 读取TIM3的计数值
Delay_ms(50);
frequency = TIM_GetCounter(TIM3);
Delay_ms(50);
TIM_SetCounter(TIM3, 0);
}
// 清除中断标志
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
这是什么原因呢,函数的其它部分是江协科大的代码,好像TIM_SetCounter(TIM3, 0);执行到这句实话的CNT值才是正确的值,但是它又能无视前面的延时,自动得到一个正确的CNT值。 好奇怪问了deepseek,它也觉得不会发生这种情况
