MSP432学习笔记9:定时器A-----捕获

news/2025/2/21 5:29:34/

今日得以继续我的MSP432电赛速通之旅~~~

目录

基础知识:

相关库函数:

一般配置步骤:

首先定义一个初始化函数:

1.复用引脚:

2.配置连续计数结构体:

3.初始化定时器连续计数:

4.配置捕获结构体:

5.初始化定时器为捕获:

6.选择模式开始计数:

7.清除中断标志位:

8.开启定时器端口中断:

9.开启总中断:

10.编写 TIMA ISR:

11.主函数捕获的编写:

硬件电路的连接:

实验结果:


基础知识:

MSP432捕获模式是一种可编程的寄存器配置,

在此模式下,MSP432可以在外部事件确切发生的瞬时刻捕获一个定时器的值。

捕获模式可以用于许多应用,例如测量某个事件的时间间隔或周期,

以及检测输入脉冲的上升边、下降边或两种边缘的时间。

在MSP432上,捕获模式与定时器结合使用。

MSP432中的每个定时器都有多个捕获/比较通道可以使用,

每个通道可以独立配置为捕获模式。

在捕获模式下,每个通道可以在定时器上的不同时间点捕获一个定时器的值。

并将其存储在一个捕获寄存器中。

在定时器捕获中,我们只需关心连续计数模式就好了:

连续计数模式就是从零开始计数

直到65535,然后又从0开始计数,如此往复循环。

此处先列出定时器与通道对应引脚

相关库函数:

以下1~7,都定义在库 timer_a.h中:

1.初始化定时器为连续计数模式:

Timer_A_configureContinuousMode(TIMER_Ax,&continuousModeConfig);

2.配置定时器的捕获模式:

Timer_A_initCapture(TIMER_Ax_BASE,&captureModeConfig);

3.选择模式开始计数:

Timer_A_startCounter(TIMER_Ax_BASE,TIMER_A_CONTINUOUS_MODE);

4.清除定时器溢出中断标志位:

Timer_A_clearInterruptFlag(TIMER_Ax_BASE);

5.清除定时器捕获中断标志位:

Timer_A_clearCaptureCompareInterrupt(TIMER_Ax,REGISTER_N);

6.获取定时器溢出中断状态:

Timer_A_getEnabledInterruptStatus(TIMER_Ax_BASE);

7.获取定时器捕获中断状态:

Timer_A_getCaptureCompareEnabledInterruptStatus(TIMER_Ax,REGISTER_N);

8.获取定时器捕获电平状态:

Timer_A_getSynchronizedCaptureCompareInput(TIMER_Ax,REGISTER_N,Setting);

返回值:

TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW

TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH

以下9~10,定义在了interrupt.h中:

9.开启定时器A端口中断:

Interrupt_enableInterrupt(INT_TAx_N);

10.开启总中断:

Interrupt_enableMaster(void);

一般配置步骤:

0.配置时钟

1.复用引脚

2.配置连续计数结构体

3.初始化定时器连续计数

4.配置捕获结构体

5.初始化定时器为捕获

6.选择模式开始计数

7.清除中断标志位

8.开启定时器端口中断

9.开启总中断

10.编写 TIMA ISR

本次配置TA2 通道1捕获并测量高电平持续时间为实验目标:

对应引脚为P5.6

首先定义一个初始化函数:

用来封装初始化的语句:

void Timer2_Cap_Inint()
{}

1.复用引脚:

 Tip:   定时器捕获是复用输入,定时器PWM是复用输出:

//1.复用引脚GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN6,GPIO_PRIMARY_MODULE_FUNCTION);

2.配置连续计数结构体:

首先在timer_a.h中找到结构体:

 复制内容粘贴在初始化函数中:

 做以下修改:

	//2.配置连续计数结构体Timer_A_ContinuousModeConfig continuousModeConfig={TIMER_A_CLOCKSOURCE_SMCLK,      //时钟源TIMER_A_CLOCKSOURCE_DIVIDER_48, //时钟分频48  分辨力为1usTIMER_A_TAIE_INTERRUPT_ENABLE,  //开启定时器溢出中断TIMER_A_SKIP_CLEAR              //Skip Clear Counter };

定时器溢出中断要使能开启,因为如果高电平持续时间过长

恰好到定时器溢出中断了才结束,此时的捕获寄存器刚好清零

读取到的捕获值就是0了,算出来的高电平持续时间就是0了

所以要开启溢出中断,每溢出一次就中断记录一次,

最后计算的时候,在把溢出的时间加回去

3.初始化定时器连续计数:

填上定时器A2和结构体地址就行了

//3.初始化定时器连续计数:
Timer_A_configureContinuousMode(TIMER_A2_BASE,&continuousModeConfig);

4.配置捕获结构体:

 

	//4.配置捕获结构体:const Timer_A_CaptureModeConfig continuousModeConfig_TA2={TIMER_A_CAPTURECOMPARE_REGISTER_1,             //此处改通道引脚	TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE,   //上升下降沿捕获TIMER_A_CAPTURE_INPUTSELECT_CCIxA,	//CCIxA:外部引脚输入(CCIxB:与内部ACLK连接)TIMER_A_CAPTURE_SYNCHRONOUS                    //同步捕获};

5.初始化定时器为捕获:

 

	//5.初始化定时器为捕获:Timer_A_initCapture(TIMER_A2_BASE,&continuousModeConfig_TA2);

6.选择模式开始计数:

	//6.选择模式开始计数:Timer_A_startCounter(TIMER_A2_BASE,TIMER_A_CONTINUOUS_MODE);

7.清除中断标志位:

	//7.清除中断标志位:Timer_A_clearInterruptFlag(TIMER_A2_BASE);Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);

8.开启定时器端口中断:

	//8.开启定时器端口中断:Interrupt_enableInterrupt(INT_TA2_N);

该函数参数的有效值可以去interrupt.h找到声明:

 我们用的是定时器A2 通道1中断,

通道1、2、3、4都是选择INT_TA2_N这个端口

              只有通道0是选择INT_TA2_0这个端口

9.开启总中断:

主函数初始化区域调用函数开启即可

 

10.编写 TIMA ISR:

中断服务函数,去启动文件寻找函数名并复制:

 粘贴,声明作为新的函数:

开始编写捕获处理:

#define CAP_TIMA_SELECTION TIMER_A2_BASE                         //在这里改定时器
#define CAP_REGISTER_SELECTION TIMER_A_CAPTURECOMPARE_REGISTER_1 //在这里改定时器通道
#define CAP_CCR_NUM 1                                            //在这里改定时器通道
#define CAP_PORT_PIN GPIO_PORT_P5, GPIO_PIN6                     //在这里改复用引脚uint16_t TIMA2_CAP_STA = 0;
uint16_t TIMA2_CAP_VAL = 0;//定时器A2 通道1 中断服务函数
void TA2_N_IRQHandler(void)
{//还未成功捕获if ((TIMA2_CAP_STA & 0X80) == 0){//溢出中断if (MAP_Timer_A_getEnabledInterruptStatus(CAP_TIMA_SELECTION)){//清除定时器溢出中断标志位MAP_Timer_A_clearInterruptFlag(CAP_TIMA_SELECTION);/*如果在未清除中断位值时,来了一次中断,COV会置位,需要软件复位,这里没有官方库函数。具体可以参考技术手册(slau356h.pdf) P790 */BITBAND_PERI(TIMER_A_CMSIS(CAP_TIMA_SELECTION)->CCTL[CAP_CCR_NUM], TIMER_A_CCTLN_COV_OFS) = 0;//已经捕获到高电平了 40H = 0x 0100 0000if (TIMA2_CAP_STA & 0X40){//高电平太长了if ((TIMA2_CAP_STA & 0X3F) == 0X3F){//强制标记成功捕获完高电平 80H = 0x1000 0000TIMA2_CAP_STA |= 0X80;TIMA2_CAP_VAL = 0XFFFF;}else//溢出次数加1{TIMA2_CAP_STA++; }}}//捕获中断if (MAP_Timer_A_getCaptureCompareEnabledInterruptStatus(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION)){//清除 CCR1 更新中断标志位MAP_Timer_A_clearCaptureCompareInterrupt(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION);//判断是否捕获到下降沿if (TIMA2_CAP_STA & 0X40 && (MAP_Timer_A_getSynchronizedCaptureCompareInput(CAP_TIMA_SELECTION,CAP_REGISTER_SELECTION,TIMER_A_READ_CAPTURE_COMPARE_INPUT) == TIMER_A_CAPTURECOMPARE_INPUT_LOW)){//标记成功捕获完高电平TIMA2_CAP_STA |= 0X80;TIMA2_CAP_VAL = Timer_A_getCaptureCompareCount(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION);}//还未开始,第一次捕获上升沿else {TIMA2_CAP_STA = 0;TIMA2_CAP_VAL = 0;MAP_Timer_A_clearTimer(CAP_TIMA_SELECTION); //清空定时器 重新从0计数TIMA2_CAP_STA |= 0X40;                      //标记捕获到了上升沿}}}
}

11.主函数捕获的编写:

 此处按键K1   K2分别是为了将LED点亮和熄灭

点亮时是高电平,以此模拟捕获高电平时长

并将计算好的时长通过串口发送给上位机

#include "sysinit.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "tim32.h"
#include "key.h"#define CAP_TIMA_SELECTION TIMER_A2_BASE                         //在这里改定时器
#define CAP_REGISTER_SELECTION TIMER_A_CAPTURECOMPARE_REGISTER_1 //在这里改定时器通道
#define CAP_CCR_NUM 1                                            //在这里改定时器通道
#define CAP_PORT_PIN GPIO_PORT_P5, GPIO_PIN6                     //在这里改复用引脚uint16_t TIMA2_CAP_STA = 0;
uint16_t TIMA2_CAP_VAL = 0;void TimA2_Cap_Init(void);int main(void)
{uint8_t key;uint32_t temp;SysInit();         // 第3讲 时钟配置uart_init(115200); // 第7讲 串口配置delay_init();      // 第4讲 滴答延时LED_Init();        //第2讲 GPIO输出KEY_Init(0);       //第2讲 GPIO输入TimA2_Cap_Init();  //第8讲 定时器A 捕获printf("Hello,MSP432!\r\n");MAP_Interrupt_enableMaster(); // 开启总中断while (1){key = KEY_Scan(0);if (key == KEY1_PRES)LED_RED_On();else if (key == KEY2_PRES)LED_RED_Off();if (TIMA2_CAP_STA & 0X80) //成功捕获到了一次上升沿{temp = TIMA2_CAP_STA & 0X3F;temp *= 65536;                 //溢出时间总和temp += TIMA2_CAP_VAL;         //得到总的高电平时间printf("HIGH:%dus\r\n", temp); //打印总的高点平时间TIMA2_CAP_STA = 0;             //开启下一次捕获}}
}

硬件电路的连接:

别忘了将P1^0与P5^6用杜邦线相连,这样LED亮,

就送来高电平给引脚P5^6测量捕获

 

实验结果:

 

 


http://www.ppmy.cn/news/102249.html

相关文章

接口测试--apipost接口断言详解

在做接口测试的时候,会对接口进行断言,一个完整的接口测试,包括:请求->获取响应正文->断言。 一、apipost如何进行断言 apipost的断言设置实在后执行脚本中进行编写的。apipost本身提供了11中断言: apt.asser…

【一次调频】考虑储能电池参与一次调频技术经济模型的容量配置方法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

使用docker部署nginx的负载均衡

前言: nginx做负载均衡使用权重轮训方式,1号服务器提供转发服务,2号和3号服务器实际使用。 过程: 创建文件夹: mkdir -pv /lnmp/nginx/nginx_proxy/{data,conf/conf.d,logs} mkdir -pv /lnmp/nginx/nginx_one/{data,conf/conf.d,logs} mk…

Parasoft亮相上海国际嵌入式展

全球自动化软件测试解决方案的领导者Parasoft宣布参加6月14日至16日在上海举行的首届embedded world China上海国际嵌入式展,此次Parasoft联合检测认证领域的领导者-莱茵技术(上海)有限公司共同参展,为嵌入式行业提供符合功能安全…

数组的玩法比我以为的要多

数组是最基本的数据结构,关于数组的面试题也屡见不鲜,本文罗列了一些常见的面试题,仅供参考。目前有以下18道题目。 数组求和 求数组的最大值和最小值 求数组的最大值和次大值 求数组中出现次数超过一半的元素 求数组中元素的最短距离 求…

腾讯云3年轻量应用服务器和5年CVM云服务器限制说明

腾讯云轻量服务器2核2G4M带宽三年388元、2核4G5M带宽三年599元、CVM云服务器2核2G配置5年1728元、2核4G配置5年3550元、4核8G配置5年6437元,从性价比角度来看,还是轻量应用服务器比较划算,腾讯云百科分享阿里云3年轻量应用服务器和5年云服务器…

MySQL分库分表方案及sharding-spher(1)

一、数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值。在业务Service来看就是,可用数据库连接少甚至无连接可用。接下来就可以想象了吧(并发…

接口自动化测试,从常规到动态再到全局断言,Postman让你居家必备!

目录 引言: 常规断言 动态参数断言 全局断言 总结 引言: Postman是一款非常流行的API接口测试工具,它以其易用性和强大的功能得到了广泛的应用。其中Postman断言功能是我们进行接口自动化测试时非常关键的一个环节。在接口测试中&#…