基于EVM_MSPM0L1306开发板实现简易PWM发生器
该项目使用了EVM_MSPM0L1306电赛训练开发板,实现了简易PWM发生器的设计,它的主要功能为:使用MSPM0L1306的定时器,生成2路重复频率1Hz~1MHz的PWM信号,每一路的重复频率和占空比都可独立调节。 其中,PWM重复频率在1Hz~10KHz内连续可调,通过按键切换至100KHz和1MHz。 PWM重复频率越高,占空比分辨率降低(主时钟32MHz为例)。
标签
嵌入式系统
crimsonsnow
更新2024-07-22
中国传媒大学
43

1,项目介绍

我做的项目是简易PWM发生器。任务要求是

  • 使用MSPM0L1306的定时器,生成2路重复频率1Hz~1MHzPWM信号,每一路的重复频率和占空比都可独立调节,调节方式为使用按钮或者拨码开关。并且用按键控制输出的开关。
  • 其中,PWM重复频率在1Hz~10KHz内连续可调,通过按键切换至100KHz1MHz
  • 使用32MHz的主时钟
  • OLED屏幕上面显示两路PWM分别输出的引脚,频率和占空比
  • PWM参数(频率,占空比,通道工作情况)按照1s的周期通过串口发送到上位机(使用UART功能)

 image.png


2.使用平台

本次任务要求使用的平台是EVM_MSPM0L1306电赛训练开发板

使用的核心芯片是MSPM0L1306,这是TI科技的一款高性能的微控制器,适用于多种嵌入式应用,满足电赛中对高性能处理能力的需求;

该扩展板有板载DAP调试器,调试方便。

配有OLED屏幕,在本次项目中用来显示数据。

开发板配备了多种外设和接口,本次使用到的功能有UARTPWM

核心板采用Type-C接口供给5V电源,通过LDO转为3.3VMCU供电,核心板上提供外置参考源接口,也可以通过跳帽选择板上3.3V参考源。底板也采用Type-C接口供给5V电源,同时为核心板提供电源,并可向外输出5V3.3V电源电压。

image.png

image.png


3 设计思路

为了完成本次任务,首先要生成PWM信号,然后要发送到OLED显示,还要用矩阵键盘来控制信号,最后串口输出到上位机。

1PWM的生成

sysconfig中的TIMER_PWM生成PWM波。通过DL_TimerG_setLoadValue()函数修改PWM波的频率,通过DL_TimerG_setCaptureCompareValue()函数修改PWM波的占空比。

2OLED的显示

如例程OLED_SPI · Pansamic/MSPM0-DevKit - 码云 - 开源中国 (gitee.com)SPI控制OLED显示。

3)键盘控制PWM波参数

如例程矩阵键盘所示:Pansamic/MSPM0-DevKit - 码云 - 开源中国 (gitee.com)似乎没有放出,在群里的包里放出了

通过按键的终端来判断按下的按钮,执行对应的功能。

4UART串口与上位机通信

sysconfig中初始化UART,用DL_UART_Main_transmitData()函数上传。

4 硬件系统框图

image.png

MSPM0单片机控制两个定时器,一个OLED屏幕,一块矩阵键盘,一个UART串口,其中矩阵键盘通过中断回调控制着定时器,所以发出不同的PWM波形

5 软件流程框图

image.png

6 实现过程

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

PWM的频率是指一秒钟内信号从高电平到低电平再回到高电平的次数,也就是说一秒钟PWM有多少个周期,而PWM的周期是频率的倒数。占空比是一个周期时间内,高电平的手机占整个周期时间的比例。

M0总共有四个定时器,每一个定时器有2PWM通道,每一个通道对应单片机的一个管脚,可以在sysconfig进行配置

1)配置PWM

按照教程在keil里面sysconfig文件显示在最上层的时候打开syconfig

我参考了某个CSDN教程里面的配置教程,水印右下角

image.png



题目要求我们达到的频率精度是1赫兹到1兆赫兹,所以在分频的时候大概先选1分频

然后他出来的频率范围是488.28HZ16MHz

这个PO主不建议勾选start timer的原因是怕PWM初始化之后点击误操作,可以在软件中通过DL_TimerG_startCounter()进行启动,我是想要勾选的,但是因为任务要求有一个通过按键来控制这个PWM的使能的要求,所以我们理论上是不能自动开上这个东西,要通过按键来控制他

继续配置

image.png

用两个不同的定时器,配置完成

 

2PWM波形生成

启动定时器

    DL_TimerG_startCounter(PWM_CH1_INST);//定时器启动,生成PWM波形
DL_TimerG_startCounter(PWM_CH2_INST);

3)串口通信

通过先做好的同学的项目的指导,说这玩意可以用GPT帮忙生成,之前做stm那个任务的时候,也听群里的同学说AI写上位机挺好的,只可惜我还是没摸到窍门,卡在了这一关,不过AI写上位机确实是能跑起来的,比我强多了。

据说用好了AI可以事半功倍,我希望以后还是能有多一点,最好是常驻的这种用AI的课程,感觉真的是有肥肉在面前都不知道吃啊。

另外,AI不会用函数库提供的函数,所以在这部份要自己修改调整,我们用的函数是

DL_UART_Main_transmitDataBlocking(UART_0_INST, str[i]);

具体步骤包括初始化串口参数,如波特率、数据位、停止位和校验方式,确保与接收端配置匹配;构造包含关键信息的格式化字符串,例如PWM参数或通道状态;最后,利用串口的写操作函数,将字符串转化为字节流并发送。

 void print(char* str) //串口函数
{
size_t len = strlen(str); // 计算字符串长度

for(size_t i = 0; i < len; ++i) {
DL_UART_Main_transmitDataBlocking(UART_0_INST, str[i]); // 发送单个字符
}
}
// 因为PWM获取的数据形式是整数,要经过整数转字符串的函数才能传到串口
void intToString(int num, char* str) {
int i = 0;
int isNegative = 0;

if (num == 0) {
str[i++] = '0';
} else {
if (num < 0) {
isNegative = 1;
num = -num;
}

while (num != 0) {
str[i++] = num % 10 + '0';
num /= 10;
}

if (isNegative) {
str[i++] = '-';
}
}
str[i] = '\0'; // 添加字符串结束符
// 反转字符串
int start = 0;
int end = i - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}

}

用串口函数写上去

然后运行的时候,就可以用串口软件接收到数据了

image.png

4OLED显示

首先有一个初始化界面

		OLED_Init();		//初始化OLED  
OLED_Clear() ;
OLED_ShowString(14,0,"SUCCESS");//如果输出中文OLED没办法直接显示,要另外做处理,自己编写字库?
delay_cycles(32000000);
OLED_Clear() ;
//OLED_ShowString(14,0,"PWM Generator");//前面的数字是一个定位坐标的作用
OLED_ShowString(8,2,"CH1 OFF");
OLED_ShowString(70,2,"CH2 OFF");

//此处是PWM参数的具体显示
CH1_freq[0] = '>'; // 在数组最开始插入 '#'
CH1_freq[1] = '0';CH1_freq[2]='0';CH1_freq[3]='0';
CH1_freq[4]='0';CH1_freq[5]='0';CH1_freq[6]='0';
CH1_freq[7]='0';
CH1_freq[8]='.';CH1_freq[9]='0';
CH1_freq[10]='(';CH1_freq[11]='0';CH1_freq[12]='5';
CH1_freq[13]='0';
CH1_freq[14]='%';CH1_freq[15]=')';

CH2_freq[0] = ' '; // 在数组最开始插入 '>'
CH2_freq[1] = '0';CH2_freq[2]='0';CH2_freq[3]='0';
CH2_freq[4]='0';CH2_freq[5]='0';CH2_freq[6]='0';
CH2_freq[7]='0';
CH2_freq[8]='.';CH2_freq[9]='0';
CH2_freq[10]='(';CH2_freq[11]='0';CH2_freq[12]='5';
CH2_freq[13]='0';
CH2_freq[14]='%';CH2_freq[15]=')';
update_PWM_CH1(0, 0);
update_PWM_CH2(0, 0);

5)键盘控制

左上角9*9的方格作为常见的九宫格键盘,右边最上1,2个分别是切换通道一通道二使能的开关,右一列3,是切换通道调节频率的光标

最下方行,中间的两个是调节频率时候向左移位和向右移位的游标

1 2 3 10(CH1)

4 5 6 11(CH2)

7 8 9 12(SW_CH)

0 13 14 15(MUTE)

13: LEFT, 14: RIGHT


并且做消抖延迟

uint8_t Key()
{
uint8_t key_num = 0; // 按键值1-16,默认为0
static uint8_t key_flag = 0; // 按下按键标志

if (key_flag)
{
delay_ms(300); // 300ms延迟,防止按下一次按键却被认为按下了多次按键,导致得到了多个相同的按键值
key_flag = 0; // 按下按键标志清零
}

// 行扫描
// ROW 0111
// 0111-1011-1101-1110
DL_GPIO_clearPins(MAT_KEY_PORT, MAT_KEY_ROW0_PIN);
DL_GPIO_setPins(M

7 项目结果

本次项目使用evmmspm0l1306核心板以及拓展板,制作了一个两路输出,可以通过键盘分别独立两路输出调节频率和占空比的简易PWM生成器。

 <iframe src="//player.bilibili.com/player.html?isOutside=true&aid=112825032969410&bvid=BV1U982eEECu&cid=500001623490674&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>

8 查漏补缺

keil一定要538以上版本,以下装不了M0

编译器不知道为什么一定要用版本6,用版本5会出现不明报错

我一开始都不太知道怎么入手修改,从官方例程写了新函数都会出来一堆的问题,汗流浃背了,总感觉不像STM32,在main里面乱写新函数至少编译不会出问题,但是这边编译出问题了,我只看到提示error,却很难去定位

然后看了武大的网页这里有一个问题:在Ti官方给出的SDK的示例代码中链接了Driverlib的静态库,但是对于学生来说,直接链接静态库而不给出源代码会导致无法Debug到对应的代码,因此不便于学生调试,且已经编译好的静态库的编译选项可能与预期不同,导致一些无法预料的问题。

因此,建议使用源码编译。需要将<SDK_PATH>/source/ti/driverlib/文件夹导入Keil工程,并添加所有源文件到工程中,把ti文件夹的父文件夹纳入Include目录。

 

但是我也没太看懂,反正新建工程的时候就将TI的SDK driverlib导进去,也不知道解决了啥,具体步骤就是武大网页最后那一部分的从零开始新建的前面几段,我觉得看完这个跟着新建一个工程是很有必要的,非常有必要,建议不要上来稀里糊涂就直接在武大提供的源码入手改,不去熟悉一个工程结构,会有很多奇怪的问题

 

我发现我下载的SDK里是没有startup_mspm0L1306_u…version,这个文件的,只有一个L130X,不知道是不是同一个,以防万一我是复制了例程里面的进去的

我记得有个大神的帖子里面说这个板子其实不太适合新手上手,我觉得确实是这样的...比之前的stm32的开发难度还要高,即使是底层的开发也不是很容易。对于没有编程基础的同学更是难上加难了。

 

如果您不知道为什么要做一些操作,我觉得跟着这位前辈的经验入门会有一些帮助

2023电赛备战-MSPM0学习笔记(一)第一步配置-CSDN博客

他还解释了武大笔记里面为什么有一些操作是必要的

2023电赛备赛-MSPM0学习笔记(二)迁移工程-CSDN博客

还有迁移工程

有一个非常奇怪的事情是我在乱搞的时候有一段时间还提示syscfg文件找不到,但是编译可以正常编译,烧录也能烧录,后来从例程里面COPY了一个过来

 

 

附件下载
1_RGB.rar
团队介绍
个人
团队成员
crimsonsnow
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号