目录
定时器A
讲解:
MSP432有4个定时器A,每个定时器A有5个通道
特性:
有三种计数模式:连续计数、增计数、增减计数模式
连续计数:是从零计数到2^16(65535)之后从新从0开始计数
增计数模式:要设置CCR0(比较寄存器)也就是自动重装载值>>定时器周期
定时器中断周期计算公式:
时钟分频乘计数值除时钟频率
增计数模式
对应的函数:
timer_a.h
1.初始化定时器模块
MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upConfig);
以增计数模式初始化定时器模块
参数:对应的定时器、配置好的结构体地址
2.选择模式开始计数
MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
参数:对应的定时、计数模式
3.清除比较中断标志
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
参数:对应定时器、对应的定时器通道
interrupt.h
4.开启定时器A端口中断
MAP_Interrupt_enableInterrupt(INT_TAX_0);
5开启总中断
MAP_Interrupt_enableMaster();
定时器中断的一般配置
0.配置时钟
SysInit();
1.配置结构体
增计数模式初始化
Timer_A_UpModeConfig upConfig;
upConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源
upConfig.clockSourceDivider = psc; //时钟分频 范围1-64
upConfig.timerPeriod = ccr0; //自动重装载值(ARR)
upConfig.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; //禁用 tim溢出中断
upConfig.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE; //启用 ccr0更新中断
upConfig.timerClear = TIMER_A_DO_CLEAR; // Clear value
在移植STM32的时候,注意时钟分频
2.初始化定时器A
MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upConfig);
调用的函数为初始化定时器为增计数模式
3.选择模式开始计数
MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
4.清除比较中断标志位
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
参数:定时器与通道
5.开启定时器端口中断
MAP_Interrupt_enableInterrupt(INT_TA0_0);
6、开启总中断
7.编写定时器中断函数(TIMA ISR)
void TA0_0_IRQHandler(void)
{
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
/*开始填充用户代码*/
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
/*结束填充用户代码*/
}
这里给大家讲一下:TA0_0 与 TA0_N区别
TA0_0
表示 Timer_A0 的第一个通道,也可以称为 Capture/Compare Register 0 (CCR0)。而 TA0_N
则表示 Timer_A0 的第 N 个通道,也可以称为 Capture/Compare Register N (CCR N),其中 N 可以是 1、2、3 等。
PWM
定时器A有7种输出模式
常用的模式就只有两种:模式2和模式6
增计数模式的输出模式
CCR0确定了定时器的周期
定时器A的各个引脚
相关函数
timer_a.h
1.初始化定时器为PWM模式
MAP_Timer_A_generatePWM(TIMER_A1_BASE, &TimA1_PWMConfig);
参数:对应的定时器和配置好的结构体地址
2.改变比较值(占空比/周期)
Timer_A_setCompareValue(TIMER_AX,COMPARE_REGISTER_X,CCR);
参数:定时器A几、通道几、CCR数值
PWM的一般配置
0.配置时钟
SysInit();
1.配置GPIO复用(复用输出)
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
2.配置结构体
Timer_A_PWMConfig TimA1_PWMConfig;
/*定时器PWM初始化*/
TimA1_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源
TimA1_PWMConfig.clockSourceDivider = psc; //时钟分频 范围1-64
TimA1_PWMConfig.timerPeriod = ccr0; //自动重装载值(ARR)
TimA1_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; //通道一 (引脚定义)
TimA1_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET; //输出模式
TimA1_PWMConfig.dutyCycle = ccr0; //这里是改变占空比的地方 默认100%
3.初始化定时器
MAP_Timer_A_generatePWM(TIMER_A1_BASE, &TimA1_PWMConfig); /* 初始化比较寄存器以产生 PWM1 */
定时器A捕获
连续计数模式:上升沿和下降沿两种捕获
相关函数
timer_a.h
1.初始化定时器为连续计数模式
MAP_Timer_A_configureContinuousMode(TIMER_AX_BASE, &continuousModeConfig);
2.配置定时器的捕获模式
MAP_Timer_A_initCapture(TIMER_AX_BASE, &captureModeConfig_TA2);
3.选择模式开始计数
MAP_Timer_A_startCounter(TIMER_AX_BASE, TIMER_A_CONTINUOUS_MODE);
4.清除定时器溢出中断标志位
MAP_Timer_A_clearInterruptFlag(TIMER_AX_BASE);
5.清除定时器捕获中断标志位
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_AX_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1);
6.获取定时器溢出中断状态
MAP_Timer_A_getEnabledInterruptStatus(CAP_TIMA_SELECTION)
7.获取定时器捕获中断状态
MAP_Timer_A_getCaptureCompareEnabledInterruptStatus(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION)
8.获取定时器捕获电平状态
MAP_Timer_A_getSynchronizedCaptureCompareInput(TIMER_A2_BASE,REGISTER_N,Setting);
返回值TIMER_A_CAPTURECOMPARE_INPUT_LOW(捕获低电平)
TIMER_A_CAPTURECOMPARE_INPUT_HIGH(捕获高电平)
9.开启定时器A端口中断
10.开启总中断
定时器捕获一般配置步骤:
0.配置时钟
1.复用引脚(复用输入)
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(CAP_PORT_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
2.配置连续计数结构体
Timer_A_ContinuousModeConfig continuousModeConfig = {
TIMER_A_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
TIMER_A_CLOCKSOURCE_DIVIDER_48, // SMCLK/48 = 1MHz
TIMER_A_TAIE_INTERRUPT_ENABLE, // 开启定时器溢出中断
TIMER_A_DO_CLEAR // Clear Counter
};
3.初始化定时器连续计数
MAP_Timer_A_configureContinuousMode(CAP_TIMA_SELECTION, &continuousModeConfig);
4.配置捕获结构体
MAP_Timer_A_configureContinuousMode(CAP_TIMA_SELECTION, &continuousModeConfig);
5.初始化定时器为捕获
MAP_Timer_A_initCapture(CAP_TIMA_SELECTION, &captureModeConfig_TA2);
6.选择模式开始计数
MAP_Timer_A_startCounter(CAP_TIMA_SELECTION, TIMER_A_CONTINUOUS_MODE);
7.清除中断标志位
MAP_Timer_A_clearInterruptFlag(CAP_TIMA_SELECTION); //清除定时器溢出中断标志位
MAP_Timer_A_clearCaptureCompareInterrupt(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION);
8.开启定时器端口中断
MAP_Interrupt_enableInterrupt(INT_TA2_N); //开启定时器A2端口中断
9.开启总中断
10编写中断函数
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 ★ */
/* 这里UP忘记讲了,如果在未清除中断位值时,来了一次中断,COV会置位,需要软件复位,这里没有官方库函数。具体可以参考技术手册(slau356h.pdf) P790 */
BITBAND_PERI(TIMER_A_CMSIS(CAP_TIMA_SELECTION)->CCTL[CAP_CCR_NUM], TIMER_A_CCTLN_COV_OFS) = 0;
if (TIMA2_CAP_STA & 0X40) //已经捕获到高电平了 40H = 0x01000000
{
if ((TIMA2_CAP_STA & 0X3F) == 0X3F) //高电平太长了
{
TIMA2_CAP_STA |= 0X80; //强制标记成功捕获完高电平 80H = 0x10000000
TIMA2_CAP_VAL = 0XFFFF;
}
else
TIMA2_CAP_STA++; //溢出次数加1
}
}
if (MAP_Timer_A_getCaptureCompareEnabledInterruptStatus(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION)) //捕获中断
{
MAP_Timer_A_clearCaptureCompareInterrupt(CAP_TIMA_SELECTION, CAP_REGISTER_SELECTION); //清除 CCR1 更新中断标志位
//判断是否捕获到下降沿
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; //标记捕获到了上升沿
}
}
}
}
定时器32
讲解:
有两个定时器32:32_0和32_1
是一个递减的定时器
void Tim32_0_Int_Init(uint32_t aar, uint8_t psc)
{
MAP_Timer32_initModule(TIMER32_0_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);
MAP_Timer32_setCount(TIMER32_0_BASE, aar);
MAP_Timer32_enableInterrupt(TIMER32_0_BASE);
MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 false
MAP_Interrupt_enableInterrupt(INT_T32_INT1);
}
/* Timer32 ISR */
void T32_INT1_IRQHandler(void)
{
MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);
/*开始填充用户代码*/
/*结束填充用户代码*/
}
声明:本次学习参考UP主m_RNA