MSP432学习笔记13:TIMER_32定时器的学习与使用

news/2024/10/30 13:32:34/

文章提供源码与工程,芯片型号MSP432P401R

在前些日子的学习里,我们深刻认识了具有强大功能的定时器A,这是一种广泛存在于各类现有 MSP430 器件的 16 位定时器。同 时,它也是灵活性最高的定时器,由于其可用于众多不同案例,因而堪称“瑞士军刀”级的定时器。

今日学习使用MSP432的另一个定时器:   Timer_32 定时器~

目录

Timer_32 定时器的基础概念:

Timer_32 定时器相关初始化函数介绍:

 1.Timer_32 定时器初始化函数:

2.设定自动重载值:

3.设定计数模式:

4.开启定时器中断:

5.清除中断标志位:

Timer_32 定时器实战使用编写:

程序下载测试截图:

完整代码贴出:


Timer_32 定时器的基础概念:

首先我们将数据手册(1053页的那本)翻阅到765页,看到Timer_32的介绍:

当然~这开头的手册贴图它只是个玩笑,这充满了英文,我怎么可能看得懂~~

所以我将其翻译了:

通过下段介绍,我们知道Timer32有俩个定时器,俩个定时器可以被编程为32或者16位,使用时需要将它选择的时钟进行预分频处理

18.1介绍
Timer32是一款符合AMBA标准的外设,由Arm有限公司开发、测试和授权。的
Timer32由两个可编程的32位或16位下行计数器组成,可以在计数达到零时产生中断。


Timer32的主要特性包括:
•两个独立的计数器,每个可配置为32位或16位计数器大小
•每个计数器支持三种不同的计时器模式
•将输入时钟分频除以1、16或256的预刻度单元
•来自每个计数器的独立中断,以及来自两个计数器的组合中断计数器

 通过下段介绍,我们知道了Timer32俩个定时器之间是相互独立的,他们有三种计时模式需要注意说明的是:前面俩种自由运行与周期计数模式是二选一的,第三个一次性定时模式是选择性开关的。

18.2功能介绍
Timer32中有两个独立的计时器。对于每个定时器,有以下操作模式是可用的:


•自由运行模式:

计数器在达到零值后轮回,并继续从最大值。这是默认设置的模式。


•周期定时器模式:

计数器以恒定的间隔产生中断,重新加载原始数据值。


•一次性定时器模式:

计数器产生一次中断。当计数器达到零时,它暂停,直到用户重新编程。这可以通过清除One Shot Count位来实现。在控制寄存器中,在这种情况下,计数根据自由运行或选择进行
周期模式,或通过向加载值寄存器写入一个新值。

 通过下段介绍,我们知道了Timer32俩个定时器在对于寄存器的操作上是相同的,也知道了俩种计数模式在计数中断,写入寄存器等操作后的不同状态,以及知道了它的时钟是MCLK的不同分频

 18.3操作
每个计时器都有一组相同的寄存器,每个计时器的操作也是相同的。计时器是通过写入加载寄存器进行加载,如果启用使能,则计数降至零。当一个计数器已经运行时,写入加载寄存器将导致计数器立即在新值处重新启动。写命令给后台负载值对当前计数没有影响。如果在周期模式,而不是选中一次性定时器模式:计数器继续递减到零,然后从新的重载值重新开始。


当达到零时,就会产生中断。可以通过写入clear寄存器来清除中断登记。如果选择“一次性定时器模式”,则计数器在达到零时停止,直到“一次性定时器模式”被取消选择,或者写入新的Load值。否则,在达到零计数后,如果计时器正在自由运行模式下,它从最大值继续递减。如果选择周期定时器模式,计时器从加载寄存器重新加载计数值并继续递减。在这种模式下
计数器有效地产生周期性中断。模式由定时器控制中的一个位来选择登记。在任何时候,都可以从当前值寄存器中读取当前计数器的值。通过T32CONTROLx寄存器中的ENABLE位使能。


在重置时,计数器被禁用,中断被清除,负载寄存器被设置为零。模式和预调值设置为自由运行,时钟分频分别为1。


定时器时钟使能是由一个预置单元产生的。然后计数器使用启用来创建一个时钟:具有下列时间之一的时钟:
•MCLK
•MCLK除以16,由4位预刻度生成
•MCLK除以256,由总共8位的预分频产生


图18-1显示了在预刻度单元中定时器时钟频率的选择。这使定时器能够他的时钟频率不同。

 

  通过下段介绍,我们知道了Timer32有三种中断

18.4中断生成。
当完整的32位计数器达到零时会生成中断,并且仅当。T32INTCLRx寄存器被写入值了。寄存器保存该值,直到中断被清除。最多的。计数器的有效进位位检测到计数器达到零。


通过将0写入T32CONTROLx寄存器中的中断使能位,可以屏蔽中断。无论是在原始中断状态,在掩蔽之前,和最终中断状态

可以读取屏蔽前的原始中断状态和屏蔽后的最终中断状态。状态寄存器。来自各个计数器的中断在屏蔽之后被逻辑地或进一个。组合中断TIMINTC提供来自定时器32外设的附加中断条件。因此,该模块总共支持三个中断-TIMINT1、TIMINT2和TIMINTC。

Timer_32 定时器相关初始化函数介绍:

 1.Timer_32 定时器初始化函数:

 此函数初始化设置 定时器预分频、32或16位计数、计数模式这四个参数

    MAP_Timer32_initModule(uint32_t timer,uint32_t preScaler,uint32_t resolution, uint32_t mode);

 #define ROM_Timer32_initModule                                                \
        ((void (*)(uint32_t timer,                                            \
                   uint32_t preScaler,                                        \
                   uint32_t resolution,                                       \
                   uint32_t mode))ROM_TIMER32TABLE[0])

 uint32_t timer ,可以选择以下定时器之一:

#define TIMER32_0_BASE   (uint32_t)TIMER32_1
#define TIMER32_1_BASE   (uint32_t)TIMER32_2

uint32_t preScaler:可以选择以下预分频之一( 1、16、256):

#define TIMER32_PRESCALER_1      0x00
#define TIMER32_PRESCALER_16     0x04
#define TIMER32_PRESCALER_256    0x08

uint32_t resolution:可以选择以下计数位数之一(16位或32位):

 这个设置影响的是最大重载值不同

#define TIMER32_16BIT            0x00
#define TIMER32_32BIT            0x01

uint32_t mode:可以选择以下计数模式之一:

自由运行模式、周期模式 ,一般使用周期模式

#define TIMER32_FREE_RUN_MODE   0x00
#define TIMER32_PERIODIC_MODE   0x01

2.设定自动重载值:

    MAP_Timer32_setCount(uint32_t timer, uint32_t count);

#define ROM_Timer32_setCount                                                  \
        ((void (*)(uint32_t timer,                                            \
                   uint32_t count))ROM_TIMER32TABLE[1])

uint32_t count 就是需要填入的自动重载值

3.设定计数模式:

    MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 false

#define ROM_Timer32_startTimer                                                \
        ((void (*)(uint32_t timer,                                            \
                   bool oneShot))ROM_TIMER32TABLE[4])

此处的计数模式选择参数用的是bool类型变量

4.开启定时器中断:

    MAP_Interrupt_enableInterrupt(INT_T32_INT1);

 这里的参数可以选择俩个中断,对应32定时器1和2的中断:

#define INT_T32_INT1                                    (41) /* T32_INT1 IRQ */
#define INT_T32_INT2                                    (42) /* T32_INT2 IRQ */

5.清除中断标志位:

    MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);

这个函数就是在中断服务函数中清除中断标志位的,必不可少~

Timer_32 定时器实战使用编写:

现在进入我们的实战使用环节:

 目标:

驱动Timer32定时器0,以1s为周期发送串口测试

首先编写初始化函数,这相较于定时器A,Timer32的初始化十分简单:

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); //连续计数模式 falseMAP_Interrupt_enableInterrupt(INT_T32_INT1);
}

其次计算定时器周期,我们知道Timer32的时钟是MCLK,便可以提供以下公式进行计算:

/*
 * 定时器中断周期:
 *
 * T_timer_32 = CLKDIV * (ARR + 1) / MCLK
 *            = 1 * 48000000 / 48000000
 *            = 1s = 1Hz
 */

在这里我希望其周期是1S,因此我作以下初始化:

#define CLKDIV TIMER32_PRESCALER_1 // 时钟源分频
#define ARR 47999999               // 自动重装载值

最后编写中断服务函数:

/* Timer32 ISR */
void T32_INT1_IRQHandler(void)
{MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);static uint8_t timer_second = 0;//一般在频率较高的中断不常用 这个printf比较费时间 这里只是演示printf("timer_second=%d\r\n", ++timer_second);
}

程序下载测试截图:

 

完整代码、工程贴出:

完整工程下载地址:

https://download.csdn.net/download/qq_64257614/88041003?spm=1001.2014.3001.5503

移植此代码须知:

将原先RNA的库大部分移除了在复制,只留下截图中有的:

/*TIMER32定时器初始化与使用*/#include "main.h"/** 定时器中断周期:** T_timer_32 = CLKDIV * (ARR + 1) / MCLK *            = 1 * 48000000 / 48000000 *            = 1s = 1Hz*/#define CLKDIV TIMER32_PRESCALER_1 // 时钟源分频
#define ARR 47999999               // 自动重装载值int main(void)
{inint_all();   //初始化所有模块while (1){}
}//初始化所有模块
void inint_all(void)
{SysInit();                                  //时钟配置    delay_init();								 								//delay_ms函数配置		Tim32_0_Int_Init(ARR, CLKDIV); uart_init(115200);           						    //串口配置printf("Hello,MSP432!\r\n");								//串口打印测试字符MAP_Interrupt_enableMaster();               // 开启总中断
}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); //连续计数模式 falseMAP_Interrupt_enableInterrupt(INT_T32_INT1);
}/* Timer32 ISR */
void T32_INT1_IRQHandler(void)
{MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);static uint8_t timer_second = 0;//一般在频率较高的中断不常用 这个printf比较费时间 这里只是演示printf("timer_second=%d\r\n", ++timer_second);
}//串口A0初始化
void uart_init(uint32_t baudRate)
{//固件库v3_40_01_02//默认SMCLK 48MHz 比特率 115200const eUSCI_UART_ConfigV1 uartConfig ={EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source26,                                            // BRDIV = 260,                                             // UCxBRF = 0111,                                           // UCxBRS = 111EUSCI_A_UART_NO_PARITY,                        // No ParityEUSCI_A_UART_LSB_FIRST,                        // MSB FirstEUSCI_A_UART_ONE_STOP_BIT,                     // One stop bitEUSCI_A_UART_MODE,                             // UART modeEUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // OversamplingEUSCI_A_UART_8_BIT_LEN                         // 8 bit data length};eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, baudRate); //配置波特率MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);//初始化串口引脚MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);    //用配置好的结构体初始化串口MAP_UART_enableModule(EUSCI_A0_BASE);								//开启串口模块MAP_UART_enableInterrupt(EUSCI_A0_BASE,EUSCI_A_UART_RECEIVE_INTERRUPT);//开启串口中断MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
}//串口相关:
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{x = x;
}
#else
int fgetc(FILE *f)
{while (EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG !=UART_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG));return UART_receiveData(EUSCI_A0_BASE);
}
#endif//重定向Printf,可以切换printf函数对应的串口
int fputc(int ch, FILE *f)
{UART_transmitData(EUSCI_A0_BASE, ch & 0xFF);return ch;
}
#ifndef _main_h_
#define _main_h_#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "string.h"				   	//C标准库、字符串处理库
#include "sysinit.h"			   	//时钟配置
#include "delay.h"				   	//滴答定时器初始化(提供delay_ms延时)
#include "usart.h"           	//串口初始化库 
#include "baudrate_calculate.h"void inint_all(void);               //初始化所有模块
void Tim32_0_Int_Init(uint32_t aar, uint8_t psc);
void uart_init(uint32_t baudRate);#endif


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

相关文章

格力电器提前批-软件开发两面面经

因为没有找到软件测试岗位&#xff0c;所以投的软件开发岗。 貌似被大数据中心捞了&#xff0c;但是面了两面就没消息了&#xff0c;两面只间隔了半个小时。 项目经历 有没有了解过数据存储、数据挖掘。我讲了一下我项目前期做的预处理&#xff0c;然后让我详细的讲了文本处理…

格力电器:向全体股东派发36.1亿 每10股派发现金6元

新浪科技讯 2月18日晚间消息&#xff0c;格力电器公布2018年半年度权益分派方案&#xff1a;按公司总股本6015730878股计&#xff0c;向全体股东每10股派发现金6元&#xff08;含税&#xff09;&#xff0c;共计派发现金36.1亿元&#xff0c;余额转入以后年度分配。

【格力电器秋招QA】 内推(ESBJ9S)

【格力电器秋招Q&A】 关注格力电器招聘公众号&#xff0c;现在收割心动offer&#xff01; 格力电器秋招Q&A&#xff0c;你想知道的都在这 格力校招 | 2023届校园招聘Q&A (qq.com) 【帮你内推】 想要解锁更多岗位详情&#xff0c; 请关注“格力电器招聘”微信…

Cloud一分钟 |格力电器营收比去年增长500亿元; 红黄蓝加盟停不下来;中美双方同意停止相互加征新的关税...

戳蓝字“CSDN云计算”关注我们哦&#xff01; Hello&#xff0c;everyone&#xff1a; 12月3日早&#xff0c;星期一 CSDN一分钟新闻时间&#xff1a; 董明珠&#xff1a;今年格力电器营收比去年增长500亿元 企业纳税越多&#xff0c;活得越好 …

2018开门红,格力电器1月大涨28.01%,怒送1个涨停

2018年1月&#xff0c;格力电器1月大涨28.01%&#xff0c;1月22日1个久违的涨停&#xff0c;爽歪歪。 一、格力电器-大涨28.01% 2018年1月&#xff0c;第1个交易日股价&#xff1a;43.7 2018年1月&#xff0c;最后1个交易日股价&#xff1a;55.94 1月涨幅&#xff1a;28.01% 20…

董明珠霸气:给格力电器全员加薪 总薪酬在10亿

雷帝网 乐天 1月9日报道 其他公司纷纷停止招聘或裁员之际&#xff0c;格力电器逆势而动。 格力电器日前下发文件&#xff0c;宣布经公司研究决定&#xff0c;自2019年元月起&#xff0c;根据不同岗位给予薪资调整&#xff0c;总共增加薪酬在10亿元以内。 具体实施方案&#xff…

【百家稷学】计算机视觉典型实践(珠海格力电器技术分享)

继续咱们百家稷学专题&#xff0c;本次是有三AI在珠海格力电器进行的深度学习技术培训&#xff0c;百家稷学的目标&#xff0c;是走进100所高校和企业进行学习和分享。 分享主题 本次分享是在珠海格力电器&#xff0c;主题为《计算机视觉与深度学习典型实践》&#xff0c;分享人…

鸿蒙系统有哪些电器,中兴、OPPO纷纷抵制鸿蒙系统后,终于有家电巨头支持华为了...

在中兴、OPPO等各个国内企业抛弃甚至贬低鸿蒙系统时&#xff0c;董明珠站起来了&#xff0c;格力将使用鸿蒙系统&#xff0c;支持华为&#xff0c;支持格力。一加科技&#xff0c;魅族也纷纷站队华为&#xff0c;支持使用鸿蒙系统。 为什么我们必须举全国之力来支持鸿蒙系统&am…