目录

输入捕获实验

实验目的

1. 了解输入捕获;
2. 学会配置输入捕获。

实验内容

用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽,通过串口打印高电平脉宽时间。

实验说明

main.c
/*******************************************************************************
*
--------------------------------------------------------------------------------
* 实 验 名      : 输入捕获实验
* 实验说明      : 按键k_up是在定时器5通道1上,通过配置好定时器5输入捕获通道,
                 按下按键k_up或者连接脉冲发生器即可在串口上打印输出捕获高电平的时间,
                 在串口助手上显示其输出 ,按下复位开关重新运行
                 见文件内截图 ,程序设计中所有中断函数都放在中断stm32f10x_it.c文件
* 连接方式      : 
* 注    意      : 所用函数在头文件.c文件内
*******************************************************************************/
#include "public.h"
#include "printf.h"
#include "systick.h"
#include "input.h"
#include "key.h"
/****************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/
int main()
{
    u32 temp;
    key_init(); // 按键初始化
    input_init(); // 输入捕获初始化
    printf_init(); // printf初始化
    while(1)
    {
        if((TIM5CH1_CAPTURE_STA&0x80)) // 成功捕获到了一次完整的高电平
        {
            temp = TIM5CH1_CAPTURE_STA&0x3f; // 取出总共溢出的次数
            temp = temp*65536; // 计算溢出时间总和 = 溢出次数 * 每次溢出的计数值65536
            temp = temp + TIM5CH1_CAPTURE_VAL; // 得到总的高电平时间,TIM5CH1_CAPTURE_VAL为未溢出那一次的计数值
            printf("高电平持续时间为:%d us\r\n", temp);
            TIM5CH1_CAPTURE_STA = 0; // 开启下一次捕获	
        }
        delay_ms(10);
    }
}

input.c
#include "input.h"
u8 TIM5CH1_CAPTURE_STA; // 输入捕获状态(全局变量)
u16 TIM5CH1_CAPTURE_VAL; // 输入捕获值(全局变量)
/*******************************************************************************
* 函 数 名      : input_init
* 函数功能      : 输入捕获配置初始化,定时器5通道1输入捕获配置 
* 输    入      : 无
* 输    出      : 无
*******************************************************************************/
void input_init()
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; // 声明一个结构体变量,用来初始化定时器
    TIM_ICInitTypeDef TIM5_ICInitStructure;
 
    NVIC_InitTypeDef NVIC_InitStructure;
 
    /* 开启定时器5时钟 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); // 使能TIM5时钟
 
    TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC1); // 清除中断和捕获标志位
 
    TIM_TimeBaseInitStructure.TIM_Period = 0xffff; // 设定计数器自动重装值 	
    TIM_TimeBaseInitStructure.TIM_Prescaler = 71;  // 以1Mhz的频率计数 一次即是1us
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
    TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);// 根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
    TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; // 选择输入端 IC1映射到TI1上 
    TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿捕获 
    TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 映射到TI1上 
    TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 配置输入分频,不分频 
    TIM5_ICInitStructure.TIM_ICFilter = 0x00; // IC1F=0000 配置输入滤波器:不滤波 
    TIM_ICInit(TIM5, &TIM5_ICInitStructure); // 初始化TIM5输入捕获通道1	
 
    //中断分组初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn; // 打开TIM5的全局中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; // 抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级为1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 中断使能
    NVIC_Init(&NVIC_InitStructure);
 
    TIM_Cmd(TIM5,ENABLE); // 使能或者失能TIMx外设
    TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1, ENABLE ); // 使能或者失能指定的TIM中断
}

中断函数在 stm32f10x_it.c

中断函数.c
// 当边沿触发器检测到边沿时,进入定时器中断程序
void TIM5_IRQHandler() // 定时器5输入捕获中断函数
{
    if((TIM5CH1_CAPTURE_STA&0X80)==0) // 还未成功捕获一次完整的高电平(上升沿+下降沿)
    {
        if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) // 判断是否为更新中断
        {
            if(TIM5CH1_CAPTURE_STA&0X40) // 第6位为1:已经捕获到高电平了(上升沿)
            {
                if((TIM5CH1_CAPTURE_STA&0x3f)==0x3f) // 低5位全为1:高电平太长了
                {
                    TIM5CH1_CAPTURE_STA|=0x80; // 强制标记成功捕获了一次完整的高电平
                    TIM5CH1_CAPTURE_VAL=0xffff; 
                }
                else
                {
                    TIM5CH1_CAPTURE_STA++; // 否则让溢出次数加1
                }
            }
        }
    }
    if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) // 捕获1发生捕获事件
    {
        if(TIM5CH1_CAPTURE_STA&0X40) // 捕获到一个下降沿
        {
            TIM5CH1_CAPTURE_STA|=0X80; // 标记成功捕获到一次上升沿(本次捕获完毕)
            TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); // 获得TIM5输入捕获1的值
            TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); // 设置为上升沿捕获
        }
        else
        {
            TIM5CH1_CAPTURE_STA=0; // 清空 
            TIM5CH1_CAPTURE_VAL=0; 
            TIM_SetCounter(TIM5,0); 
            TIM5CH1_CAPTURE_STA|=0X40; // 标记捕获到了上升沿 
            TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); // 设置为下降沿捕获
        }
    }
    TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); // 清除中断标志位
}

注:以上用到的全局变量 TIM5CH1_CAPTURE_STA 功能描述如下 tablelayout

TIM5CH1_CAPTURE_STA
bit 7 bit 6 bit 5~bit 0
=1:捕获完成的标志 =1:捕获到边沿的标志 捕获指定电平后定时器溢出的次数,若=11111:溢出次数满,强制结束捕获

其中,捕获上升沿/下降沿,高电平/低电平,具体取决于极性的配置。


实验步骤

1. 使用1根1P杜邦线连接核心板PA0连接“自主脉冲发生”单元的J72;
2. 使用1根2P杜邦线连接核心板PA2连接“两路串行通信”单元的TXD1,PA3与RXD1连接;(printf输出定义在USART2上面)
3. “两路串行通信”单元中的卧式开关打在“串行”上,串口线DB1同电脑连接;
4. 在KEIL软件中调试运行“输入捕获”工程文件;
5. 实验现象:打开PC端串口调试助手选择连接串口,设置波特率为9600,字符串显示;
   调节脉冲调节电位器,查看不同的高电平时间。

实验任务

1. 按上述步骤调试出结果;
2. 改用独立按键发送高电平,按下按键后观察高电平持续时间的变化;
3. 将程序功能修改为捕获低电平及持续时间;
4. 通过调节自主脉冲发生器模组的占空比,观察并验证两次实验成功捕获的分别是高电平与低电平;
   试通过结果估算占空比的值。

任务解答

任务2:

1). 用1p杜邦线连接 PA0 和任意一个独立按键,如K8。
2). 按下按键发送高电平脉冲后被成功捕获,并且显示电平持续时间。
3). 每次按下显示高电平持续时间不一样,整体接近,个别持续时间很短。

任务3:

改为低电平捕获时只需要修改定时器TIM5通道1配置边沿检测的极性。即依次将 input_init()TIM5_IRQHandler() 中的

    TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; \\ 初始化上升沿捕获
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); \\ 设置为上升沿捕获
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); \\ 设置为下降沿捕获

改为

    TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; \\ 初始化下降沿捕获
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); \\ 设置为下降沿捕获
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); \\ 设置为上升沿捕获

任务4:

高电平捕获结果(自主脉冲发生器占空比调到最大)

高电平持续时间为:98816 us
高电平持续时间为:98738 us
高电平持续时间为:98826 us
高电平持续时间为:98774 us
高电平持续时间为:98818 us
高电平持续时间为:98776 us
高电平持续时间为:98836 us
高电平持续时间为:98785 us
高电平持续时间为:98792 us
高电平持续时间为:98812 us
高电平持续时间为:98332 us
高电平持续时间为:98809 us
高电平持续时间为:98773 us
高电平持续时间为:98834 us
高电平持续时间为:98736 us
高电平持续时间为:98790 us

低电平捕获结果(自主脉冲发生器占空比同上)

低电平持续时间为:450 us
低电平持续时间为:450 us
低电平持续时间为:449 us
低电平持续时间为:449 us
低电平持续时间为:449 us
低电平持续时间为:450 us
低电平持续时间为:450 us
低电平持续时间为:450 us
低电平持续时间为:450 us
低电平持续时间为:449 us
低电平持续时间为:449 us
低电平持续时间为:450 us
低电平持续时间为:449 us
低电平持续时间为:450 us
低电平持续时间为:449 us
低电平持续时间为:450 us

可以验证: \begin{align} \text{占空比 } = \frac{1580247}{1580247+7193} \approx 99.55\% \end{align}