谁知道谁这个什么作用具体是干嘛的,运行过程啊,我真的裂开,自学太nan
了,stm32
边沿检测用于检测信号的变化边界或转换点。一般来说,边沿可以分为上升沿和下降沿两种类型。上升沿表示信号从低电平到高电平的变化边界,而下降沿表示信号从高电平到低电平的变化边界。边沿检测可用于捕捉信号的突变和触发相应的处理逻辑。例如,在计数器中,可以使用上升沿边沿检测来触发计数操作。
极性选择用于确定所感兴趣的边沿类型,即选择要响应的边沿类型。常见的极性选择包括上升沿触发、下降沿触发和双边沿触发。上升沿触发表示只有在检测到上升沿时才会触发相应操作,下降沿触发则是只有在检测到下降沿时才触发,而双边沿触发表示在检测到上升沿和下降沿时都会触发操作。通过极性选择,我们可以根据具体需求对边沿进行筛选,以满足特定的应用要求。
边沿检测和极性选择在数字电路和信号处理中起着重要的作用,可以帮助我们捕捉感兴趣的信号变化并触发相应的处理逻辑。
如有帮助给个采纳 谢谢谢 !!!
作为一个从事底层软件开发的人,我认为还是有必要更加了解硬件的。用了库函数的缺点就是,代码量会增大,库函数会把所有情况都考虑到函数里面,有时会造成代码的冗余,在程序空间吃紧的时候,你还是得乖乖优化成寄存器的方式。对于一些实时性要求极其严格的场合,直接操作寄存器无疑是更好的选择。对于学习而言,打好寄存器的基础会让你使用库函数时事半功倍。
对于想要了解寄存器的读者,推荐大家下面几个文件,都是在学习寄存器时必不可少的文件。由于版权问题,不便直接上传文件,网上资源还是很好找的,大家随便找找都找的到。
关于边沿检测和极性选择的使用情况:
边沿检测和极性选择通常用于定时器输入捕获模式中,用来检测外部信号的上升沿或下降沿,并根据极性选择的设置来决定计数器计数的方向。
在进行这些操作时,需要注意以下问题:
1.在使用定时器捕获模式时,需要先配置定时器的基本参数,如PSC (分频因子)和ARR (自动重装载值),以确定定时器的计数范围和计数速度。
2.在使用输入捕获模式时,需要先配置GPIO口相关的参数,如输入引脚的模式和上下拉电阻状态,以确保可以正确读取外部信号。
3.在进行边沿检测时,需要注意外部信号的信号源是否有足够的稳定性和可靠性,避免读取到错误的信号。
4.在进行极性选择时,需要注意外部信号的电平方向,以确保计数器计数方向的正确性。
一个常见的示例是使用定时器捕获模式来测量PWM信号的占空比:
1.配置定时器的基本参数,如PSC和ARR,以设置定时器的计数范围和计数速度。
2.配置GPIO引脚,将PWM信号的输入引脚设置为输入模式,并启用上拉电阻。
3.配置定时器的输入捕获模式,并设置边沿检测模式和极性选择,使得可以准确地捕获PWM信号的上升沿和下降沿,并确定计数器计数的方向。
4.在捕获到PWM信号的两个边沿后,可以根据计数器的计数值计算出占空比,并将结果输出到串口或LCD等外设上。
代码示例:
// 配置定时器的基本参数
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 设置分频因子为72,计数周期为1us
TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 设置自动重装载寄存器的值为1000,计数周期为1ms
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 设置计数模式为向上计数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 设置时钟分频因子为1
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 配置GPIO口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 使用PB3引脚作为PWM信号输入口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置为输入模式,并开启下拉电阻
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置输入捕获器
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; // 使用CC4通道来捕获PWM信号
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 = 0; // 不进行输入滤波
TIM_ICInit(TIM2, &TIM_ICInitStructure);
// 启动定时器和输入捕获器
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);
NVIC_EnableIRQ(TIM2_IRQn);
// 在定时器中断中处理捕获到的PWM信号
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET) // 判断是否发生捕获事件
{
static uint32_t first_count = 0;
static uint32_t second_count = 0;
static uint32_t total_count = 0;
static uint8_t rising_edge = 1;
if (rising_edge) // 如果是上升沿
{
first_count = TIM_GetCapture4(TIM2); // 读取捕获寄存器的值
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // 设置为捕获下降沿
TIM_ICInit(TIM2, &TIM_ICInitStructure);
rising_edge = 0;
}
else // 如果是下降沿
{
second_count = TIM_GetCapture4(TIM2); // 读取捕获寄存器的值
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 设置为捕获上升沿
TIM_ICInit(TIM2, &TIM_ICInitStructure);
rising_edge = 1;
total_count = second_count - first_count;
uint32_t pulse_width = total_count * 100 / 1000; // 计算占空比(单位为0.01%)
char buffer[16];
sprintf(buffer, "Duty: %d%%", pulse_width);
USARTSendString(USART1, buffer); // 将占空比输出到串口
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4); // 清除中断标志位
}
}