基于MSPM0L1306实现简易PWM发生器
该项目使用了MSPM0L1306,实现了简易PWM发生器的设计,它的主要功能为:生成两路独立且可调节的PWM信号,每路信号的重复频率范围从1Hz到1MHz,其中在1Hz到10kHz范围内,用户可以实现连续的频率调节;在1Hz至10kHz的频率范围内,PWM信号的占空比精度不低于1/10000。而在100kHz和1MHz的高频模式下,占空比精度会自动调整;OLED屏幕实时显示当前PWM信号的状态,包括所使用的通道、频率和占空比等参数。每隔大约1秒,该系统会通过串口通信将所有PWM参数(包括两路信号的频率、占空比以及是否正在工作)发送至上位机,以便于监控和记录。。
标签
嵌入式系统
MPU
PWM
TI
1306
Samaritan
更新2024-10-28
北京交通大学
102

基于MSPM0L1306实现简易PWM发生器

1 项目需求

  • 使用MSPM0L1306的定时器,生成2路重复频率1Hz~1MHz的PWM信号,每一路的重复频率和占空比都可独立调节。
  • 其中,PWM重复频率在1Hz~10KHz内连续可调,通过按键切换至100KHz和1MHz。
  • PWM重复频率越高,占空比分辨率降低。
  • PWM重复频率在1Hz~10KHz时,占空比的精度不低于1/1000。
  • 使用按键或拨码开关组合调节输出频率、占空比,并由按键控制每一路PWM信号的输出。
  • 能在OLED屏幕上显示基础信息,当前使用引脚示意、引脚相应的PWM参数。
  • 将PWM参数(包括两个通道的频率占空比、及通道工作与否)按照1s左右的周期,通过串口发送到上位机。

2 完成的功能及达到的性能

(1)两路独立可调频率和占空比PWM信号,范围1Hz~1MHz;

(2)占空比调节精度可达:1MHz 1/10;100KHz 1/100;10KHz 1/1,000;1KHz 1/10,000;100Hz 1/10,000;1Hz 1/10,000;

(3)实用的OLED屏幕显示,可显示输出通道及对应的PWM参数,其中,CH1和CH2分别对应对应PA26和PA21引脚;


f7cde9eb3b8b506deee7ba734228c55.jpg


(4)串口通信上位机显示PWM相关参数(通道开启与否,占空比及频率)

image.png

3 实现思路

初始化:

  • 初始化设备、OLED屏幕、计时器及启用中断。

主循环:

  • 持续读取按键值。
  • 根据按键值计算并更新频率和占空比。
  • 更新OLED显示。

按键值计算

  • 处理不同按键值的功能,如数字输入、确认、删除、切换通道、频率/占空比、启用/禁用通道等。

更新频率与占空比:

  • 根据按键输入计算新的PWM频率和占空比。
  • 设置对应的PWM参数。

OLED显示:

  • 更新OLED显示,显示当前通道、频率、占空比及通道启用状态。

中断处理:

  • 在TIMER0中断服务程序中,通过串口打印当前频率和占空比。

4 实现过程

image.png

 4.1 键值计算功能

if (key_value > 0 && key_value <= 16)
{
if (key_num[key_value - 1] >= 0 && key_num[key_value - 1] <= 9)
{
if (temp_num[6] == 0)
{
// 首先检查是否整数部分已经达到了最大可能的长度(8位数字),
// 如果是,则停止处理并返回,避免溢出。
if (temp_num[0] >= 10000000)
{
return;
}
// 如果整数部分未达到最大长度,将当前键值对应的数字添加到整数部分。
// 这里使用乘以10然后加上的方式来构建整数。
temp_num[0] = temp_num[0] * 10 + key_num[key_value - 1];
temp_num[2]++;
// 更新浮点数表示,以保持与整数部分的一致性。
temp_float = temp_num[0];
}
// 如果整数部分已满,开始处理小数部分。
// 初始化浮点数因子为1,这将用于计算小数点后的位数。
else
{
float FloatFactor = 1;
// 增加小数部分的位数计数。
temp_num[2]++;
for (int x = 0; x < temp_num[2]; x++)
{
FloatFactor = FloatFactor * 10; // 计算小数点后需要移动的小数位数。
}
// 根据计算出的小数位数,将当前键值对应的浮点数添加到总和中。
if (temp_num[2] >= 1)
{
temp_float = temp_float + key_float[key_value - 1] / FloatFactor;
}
}
}

此代码段负责根据一系列键值构建一个可能包含整数和小数部分的数值。它首先检查当前键值对应的数字是否在0至9的有效范围内。如果是,则根据当前数值构建状态,将该数字添加到整数或小数部分。如果整数部分尚未开始填充(由temp_num[6]标记),并且整数部分尚未达到8位的最大长度,则将当前键值数字添加到整数部分,并更新整数位数计数器temp_num[2]以及浮点数表示temp_float。一旦整数部分达到最大长度或开始处理小数部分,代码将计算一个小数点后位数的因子(FloatFactor),并使用这个因子将键值对应的小数部分加入到总和中。整个过程确保数值的构建既不会导致整数溢出,又能正确地处理小数点后的精度。

4.2 分频PWM时钟功能

if (PWM_Freq[0] > 500)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate1);
PWM1_CLK = 32000000;
}
else if (PWM_Freq[0] > 180 && PWM_Freq[0] <= 500)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate2);
PWM1_CLK = 10666667;
}
else if (PWM_Freq[0] > 65 && PWM_Freq[0] <= 180)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate3);
PWM1_CLK = 4000000;
}
else if (PWM_Freq[0] > 32 && PWM_Freq[0] <= 65)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate4);
PWM1_CLK = 1333333;
}
else if (PWM_Freq[0] > 10 && PWM_Freq[0] <= 32)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate5);
PWM1_CLK = 500000;
}
else if (PWM_Freq[0] > 4 && PWM_Freq[0] <= 10)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate6);
PWM1_CLK = 250000;
}
else //(PWM_Freq[0]<=3)
{
DL_TimerG_setClockConfig(PWM_0_INST, (DL_TimerG_ClockConfig *)&gPWM_ClockConfigUpdate7);
PWM1_CLK = 62500;
}

// 计算周期和占空比,使用浮点运算以保持精度
period0 = (float)PWM1_CLK / PWM_Freq[0];
dutyCycle0 = period0 * (1 - PWM_Duty[0] / (float)100);

// 将结果转换为整数类型,以便于传递给硬件接口
if (enablechannel[0] == 0)
{
captureCompareValue0 = (uint32_t)period0;
loadValue0 = (uint32_t)dutyCycle0;
// printf("captureCompareValue=%d\n", (unsigned int)captureCompareValue0);
}


函数首先清除OLED屏幕,然后在屏幕上显示两个PWM通道的详细信息,包括频率、占空比和启用状态。同时,它还包含一个菜单区域,指示了当前选定的通道以及调整的参数(频率或占空比)。参数:

PWM1 uint32_t 类型的PWM1频率值。

PWM1_Duty float 类型的PWM1占空比值。

PWM2 uint32_t 类型的PWM2频率值。

PWM2_Duty float 类型的PWM2占空比值。

如果PWM频率为1000000 Hz,显示为"1M"。如果PWM频率为100000 Hz,显示为"100k"。根据temp_num数组中的值更新菜单选项的高亮显示。

5 实际实用

1Mhz

DS2_202471523223.png

100kHz


DS2_2024715232216.png

10kHz

DS2_202471523219.png

1kHz

DS2_2024715232027.png


100Hz


DS2_2024715232247.png

10Hz



DS2_2024715232259.png

1Hz

DS2_2024715232350.png

6 实物展示

366dadcfcca7dfd84b9c0a9a122312e.jpg

6.1 屏幕区域指示


image.png

①、③:频率状态指示(Freq);

②、④:占空比状态指示(Duty);

⑤、⑥:通道开启状态指示;

⑦:通道选择;

⑧:频率/占空比选择;

⑨:通道启停选择;

⑩:确认。

6.2 按键区域指示

image.png

注意:

1、小数点精度仅适用于占空比微调场景;对于频率参数而言,其值需为整数类型,系统在处理时将自动剔除任何小数部分。

2、当用户未选择特定通道时,程序将自动配置 CH1 作为默认操作通道。

3、若用户未指定频率或占空比的调整,系统将遵循以频率设定为首要操作的预置逻辑。

7 总结与展望

本次项目是我我首次系统性地接触TI的MCU。与先前所用的STM32相比,TI的MCU在RAM容量方面通常较小,但这并没有成为本次任务中的瓶颈,因为项目本身对RAM的需求量不大。

在项目编码的过程中,TI提供的SysConfig工具发挥了重要作用,它简化了初始化外部设备的复杂步骤。通过分析SysConfig生成的C语言文件,我能够快速掌握如何编写时钟分频的代码,这极大地提高了工作效率。

我想要特别感谢启是科技和武汉大学的团队,以及电子森林平台。他们不仅为我提供了一个实践的机会,还分享了一系列详实且易懂的示例工程,这对后续的开发工作起到了巨大作用。这次项目套件不仅对电赛有益,同样适用于单片机相关的课程和自学,其价值远远超出了预期。



附件下载
6.0.zip
keil代码
团队介绍
北京交通大学
团队成员
Samaritan
评论
0 / 100
查看更多
猜你喜欢
用MSPM0L1306实现简易PWM发生器用MSPM0L1306实现简易PWM发生器,上位机程序实时显示PWM输出参数。移植了RT-Thread和MSH组件,实现了pwm自定义指令
bigzhu
302
基于MSPM0L1306实现简易PWM波发生器该项目使用了MSPM0L1306,实现了生成2路重复频率1Hz~1MHz的PWM信号,每一路的重复频率和占空比都可独立调节的设计,它的主要功能为:其中,PWM重复频率在1Hz~10KHz内连续可调,通过按键切换至100KHz和1MHz。 PWM重复频率越高,占空比分辨率降低(主时钟32MHz为例)。
sty
231
基于MSPM0L1306的简易PWM发生器该项目使用了EVM_MSPM0L1306,实现了简易PWM的设计,它的主要功能为:使用MSPM0L1306的定时器,生成2路重复频率1Hz~1MHz的PWM信号,每一路的重复频率和占空比都可独立调节。 其中,PWM重复频率在1Hz~10KHz内连续可调,通过按键切换至100KHz和1MHz。 PWM重复频率越高,占空比分辨率降低(主时钟32MHz为例) 重复频率 占空比调节精度 1MHz 1/10 100KHz 1/100 10KHz 1/1,000 1KHz 1/10,000 100Hz 1/10,000 1Hz 1/10,000 PWM重复频率在1Hz~10KHz时,占空比的精度不低于1/1000,100Khz和1Mhz的占空比精度按照表格即可。 使用按键或拨码开关组合调节输出频率、占空比,并由按键控制每一路PWM信号的输出。 能在OLED屏幕上显示基础信息,当前使用引脚示意、引脚相应的PWM参数。 将PWM参数(包括两个通道的频率占空比、及通道工作与否)按照1s左右的周期,通过串口发送到上位机。。
冲向天空的猪
218
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号