完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
本章教程为大家讲解高分辨率定时器HRTIM的PWM实现。
64.1 初学者重要提示
64.2 HRTIM的PWM驱动设计
64.3 HRTIM板级支持包(bsp_tim_pwm.c)
64.4 HRTIM驱动移植和使用
64.5 实验例程设计框架
64.6 实验例程说明(MDK)
64.7 实验例程说明(IAR)
64.8 总结
HRTIM的PWM实现相对比较简单,只是涉及到的API比较多。
HRTIM支持两种时钟源,一个是来自CPU主频时钟,另一个是来自通用定时器。大家可以通过函数HAL_RCCEx_PeriphCLKConfig来设置使用那个时钟。具体实现代码如下:
1. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
2.
3. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_HRTIM1;
4. PeriphClkInitStruct.Hrtim1ClockSelection = RCC_HRTIM1CLK_CPUCLK;
5. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
6. {
7. Error_Handler(__FILE__, __LINE__);
8. }
这里把几个关键的地方再阐释下:
HRTIM的涉及到的输入输出引脚如下:
FTL = FAULT INPUT Lines
PA15 HRTIM_FLT1
PC11 HRTIM_FLT2
PD4 HRTIM_FLT3
PB3 HRTIM_FLT4
PG10 HRTIM_FLT5
EEV = EXTERN EVENT Lines
PG13 HRTIM_EEV10
PB7 HRTIM_EEV9
PB6 HRTIM_EEV8
PB5 HRTIM_EEV7
PB4 HRTIM_EEV6
PG12 HRTIM_EEV5
PG11 HRTIM_EEV4
PD5 HRTIM_EEV3
PC12 HRTIM_EEV2
PC10 HRTIM_EEV1
PC6 HRTIM_CHA1
PC7 HRTIM_CHA2
PC8 HRTIM_CHB1
PA8 HRTIM_CHB2
PA9 HRTIM_CHC1
PA10 HRTIM_CHC2
PA11 HRTIM_CHD1
PA12 HRTIM_CHD2
PG6 HRTIM_CHE1
PG7 HRTIM_CHE2
PE0 HRTIM_SCIN
PE1 HRTIM_SCOUT
PB10 HRTIM_SCOUT
PB11 HRTIM_SCIN
当前程序里面使用的Timer D的HRTIM_CHD1和HRTIM_CHD2,即PA11和PA12引脚输出PWM。程序配置如下:
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_HRTIM1;
GPIO_InitStruct.Pin = GPIO_PIN_11;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Alternate = GPIO_AF2_HRTIM1;
GPIO_InitStruct.Pin = GPIO_PIN_12;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HRTIM的初始化和时基配置如下:
1. /*##- 初始化HRTIM ###################################################*/
2. HrtimHandle.Instance = HRTIM1; /* 例化,使用的HRTIM1 */
3. HrtimHandle.Init.HRTIMInterruptResquests = HRTIM_IT_NONE;/* 用于配置支持的中断请求,当前配置无中断 */
4. HrtimHandle.Init.SyncOptions = HRTIM_SYNCOPTION_NONE; /* 配置HRTIM作为Master,发送同步信号,或者作
5. 为Slave,接收同步信号,当前配置没有做同步功能 */
6.
7. HAL_HRTIM_Init(&HrtimHandle);
8.
9. /*##- 配置HRTIM的TIMER D 时基 #########################################*/
10. sConfig_time_base.Mode = HRTIM_MODE_CONTINUOUS; /* 连续工作模式 */
11. sConfig_time_base.Period = HRTIM_TIMD_PERIOD; /* 设置周期 */
12. sConfig_time_base.PrescalerRatio = HRTIM_PRESCALERRATIO_DIV1; /* 设置HRTIM分频,当前设置的1分频,也就
13. 是不分频 */
14. sConfig_time_base.RepetitionCounter = 0; /* 设置重复计数器为0,即不做重复计数 */
15.
16. HAL_HRTIM_TimeBaseConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, &sConfig_time_base);
这里把几个关键的地方再阐释下:
比如HRTIM主频是400MHz,HRTIM_TIMD_PERIOD = 4000,那么Timer D的输出频率如下:
PWM的频率 = 400MHz / HRTIM_TIMD_PERIOD
= 400000000 / 4000
= 100KHz
#define HRTIM_PRESCALERRATIO_MUL32 (0x00000000U)
#define HRTIM_PRESCALERRATIO_MUL16 (0x00000001U)
#define HRTIM_PRESCALERRATIO_MUL8 (0x00000002U)
#define HRTIM_PRESCALERRATIO_MUL4 (0x00000003U)
#define HRTIM_PRESCALERRATIO_MUL2 (0x00000004U)
#define HRTIM_PRESCALERRATIO_DIV1 (0x00000005U)
#define HRTIM_PRESCALERRATIO_DIV2 (0x00000006U)
#define HRTIM_PRESCALERRATIO_DIV4 (0x00000007U)
Timer D的配置成员非常多,对于PWM输出功能来说,这些成员的功能有个了解即可:
HRTIM_TimerCfgTypeDef sConfig_timerD;
sConfig_timerD.DMARequests = HRTIM_TIM_DMA_NONE; /* 不使用DMA */
sConfig_timerD.HalfModeEnable = HRTIM_HALFMODE_DISABLED;/* 关闭HALF模式 */
sConfig_timerD.StartOnSync = HRTIM_SYNCSTART_DISABLED; /* 设置同步输入端接收到上升沿信号后,不启动定时器 */
sConfig_timerD.ResetOnSync = HRTIM_SYNCRESET_DISABLED; /* 设置同步输入端接收到上升沿信号后,不复位定时器 */
sConfig_timerD.DACSynchro = HRTIM_DACSYNC_NONE; /* 不使用DAC同步事件 */
sConfig_timerD.PreloadEnable = HRTIM_PRELOAD_ENABLED; /* 使能寄存器预加载 */
sConfig_timerD.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT; /* 独立更新,与DMA突发传输完成无关 */
sConfig_timerD.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK; /* 在突发模式下,定时器正常运行 */
sConfig_timerD.RepetitionUpdate = HRTIM_UPDATEONREPETITION_ENABLED;/* 设置重计数器事件可以触发寄存器更新 */
/* 当HRTIM TIMER的计数器复位时或者计数回滚到0时,不触发寄存器更新 */
sConfig_timerD.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED;
sConfig_timerD.InterruptRequests = HRTIM_TIM_IT_NONE; /* 不使用中断 */
sConfig_timerD.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED; /* 不开启推挽模式 */
sConfig_timerD.FaultEnable = HRTIM_TIMFAULTENABLE_NONE; /* 不使用HRTIM TIMER的Fault通道 */
sConfig_timerD.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE; /* 不开启HRTIM TIMER的异常使能状态写保护 */
sConfig_timerD.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_DISABLED;/* 不开启死区时间插入 */
/* 不开启HRTIM TIMER的延迟保护模式 */
sConfig_timerD.DelayedProtectionMode = HRTIM_TIMER_D_E_DELAYEDPROTECTION_DISABLED;
/* Master或TIMER(A到E)更新时,不同步更新寄存器 */
sConfig_timerD.UpdateTrigger= HRTIM_TIMUPDATETRIGGER_NONE;
sConfig_timerD.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE; /* 无复位触发 */
HAL_HRTIM_WaveformTimerConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, &sConfig_timerD);
注意,如果HRTIM_TimerCfgTypeDef sConfig_timerD做局部变量,务必记得清零。
HRTIM用于PWM功能时,比较输出用于设置PWM占空比:
HRTIM_CompareCfgTypeDef sConfig_compare;
sConfig_compare.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR; /* 这里使用标准模式,即未使用自动延迟 */
sConfig_compare.AutoDelayedTimeout = 0; /* 由于前面的参数未使用自动延迟模式,此参数无作用 */
/*
设置定时器比较单元的比较值:
最小值要大于等于3个HRTIM时钟周期。
最大值要小于等于0xFFFF – 1
*/
sConfig_compare.CompareValue = HRTIM_TIMD_PERIOD / 2; /* 占空比50% */
HAL_HRTIM_WaveformCompareConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_1,
&sConfig_compare);
sConfig_compare.CompareValue = HRTIM_TIMD_PERIOD / 4; /* 占空比25% */
HAL_HRTIM_WaveformCompareConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_2,
&sConfig_compare);
注意事项:
这部分的实现代码如下:
1. HRTIM_OutputCfgTypeDef sConfig_output_config;
2.
3. sConfig_output_config.Polarity = HRTIM_OUTPUTPOLARITY_LOW; /* 设置定时器输出极性 */
4. sConfig_output_config.SetSource = HRTIM_OUTPUTRESET_TIMCMP1; /* 定时器比较事件1可以将输出置位 */
5. sConfig_output_config.ResetSource = HRTIM_OUTPUTSET_TIMPER; /* 定时器周期性更新事件可以将输出清零 */
6. sConfig_output_config.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE; /* 输出不受突发模式影响 */
7. sConfig_output_config.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE; /* 设置空闲状态输出低电平 */
8. sConfig_output_config.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_NONE; /* 输出不受异常输入影响 */
9. sConfig_output_config.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED; /* 关闭Chopper模式 */
10. sConfig_output_config.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR; /* 设置从突发模式切换
11. 到空闲模式,不插入死区时间 */
12.
13. HAL_HRTIM_WaveformOutputConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD1,
14. &sConfig_output_config);
15.
16. sConfig_output_config.SetSource = HRTIM_OUTPUTRESET_TIMCMP2; /* 定时器比较事件2可以将输出置位 */
17. HAL_HRTIM_WaveformOutputConfig(&HrtimHandle, HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD2,
18. &sConfig_output_config);
19.
20. /*##-9- 启动PWM输出 #############################################*/
21. if (HAL_HRTIM_WaveformOutputStart(&HrtimHandle, HRTIM_OUTPUT_TD1 + HRTIM_OUTPUT_TD2) != HAL_OK)
22. {
23. Error_Handler(__FILE__, __LINE__);
24. }
25.
26. /*##-10- 启动计数器 #############################################*/
27. if (HAL_HRTIM_WaveformCounterStart(&HrtimHandle, HRTIM_TIMERID_TIMER_D) != HAL_OK)
28. {
29. Error_Handler(__FILE__, __LINE__);
30. }
这里把几个关键的地方再阐释下:
通过第4行和第5行,就实现了Timer D中通道1的高低电平输出方式,
定时器驱动文件bsp_hrtim_pwm.c主要实现了如下一个API供用户调用:
函数原型:
void bsp_SetHRTIMOutPWM(void)
函数描述:
这个函数的源码实现在本章64.2小节里面已经进行了详细说明。
当前这个函数通过配置HRTIM的TIMER D输出两路PWM,周期都是100KHz,PA11引脚输出占空比50%,PA12引脚输出的占空比25%。
定时器的移植比较简单:
通过程序设计框架,让大家先对配套例程有一个全面的认识,然后再理解细节,本次实验例程的设计框架如下:
第1阶段,上电启动阶段:
第2阶段,进入main函数:
配套例子:
V7-045_高分辨率定时器HRTIM实现PWM输出
实验目的:
实验内容:
PWM输出引脚PA11和PA12位置:
上电后串口打印的信息:
波特率 115200,数据位 8,奇偶校验位无,停止位 1
程序设计:
系统栈大小分配:
RAM空间用的DTCM:
硬件外设初始化
硬件外设的初始化是在 bsp.c 文件实现:
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config();
/* 使能L1 Cache */
CPU_CACHE_Enable();
/*
STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
- 设置NVIV优先级分组为4。
*/
HAL_Init();
/*
配置系统时钟到400MHz
- 切换使用HSE。
- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config();
/*
Event Recorder:
- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif
bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
bsp_InitTimer(); /* 初始化滴答定时器 */
bsp_InitUart(); /* 初始化串口 */
bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
bsp_InitLed(); /* 初始化LED */
}
MPU配置和Cache配置:
数据Cache和指令Cache都开启。配置了AXI SRAM区(本例子未用到AXI SRAM)和FMC的扩展IO区。
/*
*********************************************************************************************************
* 函 数 名: MPU_Config
* 功能说明: 配置MPU
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* 禁止 MPU */
HAL_MPU_Disable();
/* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/*
*********************************************************************************************************
* 函 数 名: CPU_CACHE_Enable
* 功能说明: 使能L1 Cache
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
/* 使能 I-Cache */
SCB_EnableICache();
/* 使能 D-Cache */
SCB_EnableDCache();
}
主功能:
主程序实现如下操作:
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参: 无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
uint8_t ucKeyCode; /* 按键代码 */
bsp_Init(); /* 硬件初始化 */
PrintfLogo(); /* 打印例程名称和版本等信息 */
PrintfHelp(); /* 打印操作提示 */
bsp_SetHRTIMOutPWM();
bsp_StartAutoTimer(0, 100); /* 启动1个100ms的自动重装的定时器 */
while (1)
{
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
/* 判断定时器超时时间 */
if (bsp_CheckTimer(0))
{
/* 每隔100ms 进来一次 */
bsp_LedToggle(2);
}
/* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
case KEY_DOWN_K1: /* K1键按下 */
break;
default:
/* 其它的键值不处理 */
break;
}
}
}
}
配套例子:
V7-045_高分辨率定时器HRTIM实现PWM输出
实验目的:
实验内容:
PWM输出引脚PA11和PA12位置:
上电后串口打印的信息:
波特率 115200,数据位 8,奇偶校验位无,停止位 1
程序设计:
系统栈大小分配:
RAM空间用的DTCM:
硬件外设初始化
硬件外设的初始化是在 bsp.c 文件实现:
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config();
/* 使能L1 Cache */
CPU_CACHE_Enable();
/*
STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
- 设置NVIV优先级分组为4。
*/
HAL_Init();
/*
配置系统时钟到400MHz
- 切换使用HSE。
- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config();
/*
Event Recorder:
- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif
bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
bsp_InitTimer(); /* 初始化滴答定时器 */
bsp_InitUart(); /* 初始化串口 */
bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
bsp_InitLed(); /* 初始化LED */
}
MPU配置和Cache配置:
数据Cache和指令Cache都开启。配置了AXI SRAM区(本例子未用到AXI SRAM)和FMC的扩展IO区。
/*
*********************************************************************************************************
* 函 数 名: MPU_Config
* 功能说明: 配置MPU
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* 禁止 MPU */
HAL_MPU_Disable();
/* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/*
*********************************************************************************************************
* 函 数 名: CPU_CACHE_Enable
* 功能说明: 使能L1 Cache
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
/* 使能 I-Cache */
SCB_EnableICache();
/* 使能 D-Cache */
SCB_EnableDCache();
}
主功能:
主程序实现如下操作:
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参: 无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
uint8_t ucKeyCode; /* 按键代码 */
bsp_Init(); /* 硬件初始化 */
PrintfLogo(); /* 打印例程名称和版本等信息 */
PrintfHelp(); /* 打印操作提示 */
bsp_SetHRTIMOutPWM();
bsp_StartAutoTimer(0, 100); /* 启动1个100ms的自动重装的定时器 */
while (1)
{
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
/* 判断定时器超时时间 */
if (bsp_CheckTimer(0))
{
/* 每隔100ms 进来一次 */
bsp_LedToggle(2);
}
/* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
case KEY_DOWN_K1: /* K1键按下 */
break;
default:
/* 其它的键值不处理 */
break;
}
}
}
}
本章节就为大家讲解这么多,PWM是HRTIM里面相对比较容易掌握,还有一些高级玩法,后续章节为大家做介绍。