
开源协议
:CC BY 3.0
描述
1.视频链接:
2.项目简介
本项目是基于MSPM0G3507的简易PID项目,基本是在立创官方项目案例上的进一步简化,把天猛星换成地猛星,进一步压缩成本,元器件也尽量采用之前做项目剩下的材料,真正做到了白嫖。
3.项目功能
与官方案例无异,PID控制电机定速或定距转动,较大的改动是采用了经典的0.96寸IIC协议OLED屏幕,因而大幅度简化了UI界面
4.项目参数
- 本设计采用地猛星MSPM0G3507开发板,降本增效;
- 本设计采用0.96寸IIC协议OLED屏幕,一般学过STM32的都有这个模块,可以插拔和重复使用;
- 电阻电容等元器件全部采用常见的0603封装,最大化利用现有材料;
- 电机是淘宝买的带编码器直流电机
5.原理解析(硬件说明)

使用地猛星MSPM0G3507开发板,该板与天猛星是一样的MCU,区别是前者为48P引脚,后者为64引脚,但仅本次项目用到的引脚而言,大部分通用,无须大量修改代码。

电源部分使用6P的Type-C口,这个也是因为剩了比较多的材料。注意type-C的CC1口和CC2口需要挂载5.1K电阻接地,否则快充无法识别,之前出现了这个问题。二极管采用了SS32,这个也是因为之前做某个立创项目剩了很多,于是物尽其用,理论上也能满足该项目的需求。
像是其他的电路设计部分就没什么好说的,整体上比较简单清晰。
6.软件代码
由于把原本的LCD屏幕换成了IIC协议OLED屏幕,大量的代码需要修改,官方提供的项目源码中,把系统分成了hardware、middle、app三层,我们主要修改hardware和app两部分的代码。

硬件层移植OLED驱动代码,采用硬件IIC的方式驱动OLED屏幕。
注意,必须采用硬件IIC。 这是因为MSPM0G3507最多仅支持2个开漏输出引脚,而驱动电机已经占用了2个,所以在该项目中无法通过软件IIC来驱动屏幕,哪怕代码能运行和烧录,屏幕也是不能被点亮的。
由于立创的常见模块移植手册中,只提供了软件IIC驱动屏幕的源码,所以我一开始也使用软件IIC来尝试驱动屏幕,单独运行可以点亮屏幕,但在电机项目中不行,一开始还以为是移植的问题,但无论怎么修改代码都不能点亮屏幕,最后问DeepSeek才排查出这个原因。

I2C引脚的设置如上图所示,给PB2和PB3引脚设置为I2C引脚,采用400kHZ的快速模式,具体的硬件IIC驱动代码我是在B站找的,也是从别人那里移植过来。
移植的IIC驱动代码中包括了全部的英文和字符,但中文还需要自己用取模软件来取模,我用的是PCtoLCD2002,这个操作还是比较简单的,记得选项那里把格式设置为C51就行。


生成的字模直接复制进oledfont.h这个文件里面,字模本质上是一个16进制的数组,用来表示像素点的亮灭。
就比如下面这个数组,
const unsigned char Hzk12[][24]={
{0x00,0x08,0x48,0x88,0x09,0x0A,0x08,0x08,0xE8,0x08,0x00,0x00,0x08,0x08,0x08,0x0B,0x08,0x08,0x0C,0x0B,0x08,0x08,0x08,0x00},/*"立",0*/
{0x08,0xF4,0x12,0x11,0x12,0xF4,0x08,0x00,0xFC,0x00,0xFF,0x00,0x00,0x07,0x08,0x09,0x09,0x08,0x0E,0x00,0x01,0x08,0x0F,0x00},/*"创",1*/
{0x40,0x42,0x42,0xFE,0x42,0x42,0x42,0xFE,0x42,0x42,0x40,0x00,0x00,0x08,0x06,0x01,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00},/*"开",2*/
{0x0E,0x08,0x88,0x78,0xCF,0x48,0x48,0x49,0xCA,0x08,0x08,0x00,0x04,0x02,0x09,0x08,0x04,0x05,0x02,0x05,0x04,0x08,0x08,0x00},/*"发",3*/
{0x88,0x68,0xFF,0x28,0x40,0xFE,0x12,0xF2,0x12,0x91,0x71,0x00,0x00,0x00,0x0F,0x08,0x04,0x03,0x08,0x05,0x02,0x05,0x08,0x00},/*"板",4*/
{0x2C,0x24,0xA4,0x24,0x25,0xE6,0x24,0x24,0x24,0x24,0x2C,0x00,0x08,0x04,0x03,0x04,0x08,0x0F,0x09,0x09,0x09,0x09,0x08,0x00},/*"定",5*/
{0x11,0xF2,0x00,0x7A,0x4A,0xCA,0xFF,0xCA,0x4A,0x7A,0x02,0x00,0x08,0x07,0x08,0x0A,0x09,0x08,0x0F,0x08,0x09,0x0A,0x08,0x00},/*"速",6*/
{0x00,0xFE,0x0A,0x8A,0xBE,0xAA,0xAB,0xAA,0xBE,0x8A,0x0A,0x00,0x08,0x07,0x00,0x08,0x09,0x0A,0x04,0x04,0x0A,0x09,0x08,0x00},/*"度",7*/
{0x00,0x9E,0x12,0xF2,0x9E,0x00,0xFE,0x12,0x12,0x12,0xF2,0x00,0x08,0x0F,0x08,0x07,0x04,0x00,0x0F,0x09,0x09,0x09,0x09,0x00},/*"距",8*/
{0x82,0xBA,0xA2,0xB6,0xAA,0xEB,0xAA,0xB6,0xA2,0xBA,0x82,0x00,0x0F,0x00,0x04,0x06,0x05,0x04,0x06,0x0C,0x00,0x08,0x0F,0x00},/*"离",9*/
{0x00,0xFC,0x04,0x04,0x04,0x05,0x06,0x04,0x04,0x04,0x04,0x00,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"广",10*/
{0x04,0x64,0x54,0x4C,0x47,0xF4,0x44,0x44,0x44,0x44,0x04,0x00,0x04,0x02,0x01,0x00,0x08,0x0F,0x00,0x00,0x01,0x02,0x04,0x00},/*"东",11*/
{0x00,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08,0x08,0x00},/*"工",12*/
{0x10,0x20,0x40,0xFF,0x00,0x00,0x00,0xFF,0x40,0x20,0x10,0x00,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x00},/*"业",13*/
{0x10,0x10,0x10,0x10,0xD0,0x3F,0xD0,0x10,0x10,0x10,0x10,0x00,0x08,0x08,0x04,0x03,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x00},/*"大",14*/
{0x8C,0x85,0x96,0x94,0x95,0x96,0xD4,0xB4,0x96,0x85,0x8C,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}/*"学",15*/
};
需要显示中文的时候只能一个字一个字的调用,具体的代码如下,因为目前只弄了12×12的中文字体,所以实际sizey只能输入12。
void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t no,uint8_t sizey)
{
uint16_t i,size1=(sizey/8+((sizey%8)?1:0))*sizey;
for(i=0;i<size1;i++)
{
if(i%sizey==0) OLED_Set_Pos(x,y++);
//if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号
if(sizey==12) OLED_WR_Byte(Hzk12[no][i],OLED_DATA);//12x12字号
// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号
else return;
}
}
对app层中的app_ui.c中的所有函数都进行修改,凡是调用了lcd的函数都改为调用OLED。
以下方的绘制首页界面代码为例,基本上删光了所有原本的LCD相关的代码,改为调用OLED函数
//绘制首页界面
void ui_home_page(void)
{
OLED_Clear();

//绘制任务一:PID定速
//OLED_ShowString(44,0,(uint8_t *)"Speed",16);
OLED_ShowChinese(48,0,5,12);//定
OLED_ShowChinese(72,0,6,12);//速
//绘制任务二:PID定距
//OLED_ShowString(32,6,(uint8_t *)"Distance",16);
OLED_ShowChinese(48,6,5,12);//定
OLED_ShowChinese(72,6,8,12);//距
OLED_ShowString(8,3,(uint8_t *)"**** ****",8);
OLED_ShowString(8,4,(uint8_t *)"**** ****",8);
for(int i=0;i<5;++i)//显示立创开发板logo
{
OLED_ShowChinese(36+12*i,3,i,12);
}
//根据首页当前选择内容 绘制选择框
switch( get_default_page_flag() )
{
case 0:
disp_select_box(36,0,36,16,1);
break;
case 1:
disp_select_box(36,6,36,16,1);
break;
}
//LCD_BLK_Set();//打开背光
}
像是定速页和定距页也是同理,除此之外,绘制PID波形的代码可以全部注释或删除,因为0.96寸屏幕上确实没多少空间来画波形图,干脆省略掉。将app_key_task.c中绘制波形的代码全部注释掉。
7.注意事项
- 6P的TypeC必须在CC1和CC2通过5.1k电阻接地
- 必须使用硬件IIC驱动OLED屏幕
- 注意电机的接口是否匹配
8.实物图

9.总结和感想
整体来说这个项目还是比较简单的,只有在移植OLED屏幕的代码时遇到了一点麻烦,花了半天时间才发现是软件IIC行不通,做这个项目总共花费的时间比较短。
本人在5月底搞完了毕业答辩,闲着没事干就打开了嘉立创参加活动,也要感谢嘉立创一直以来对培养中国工程师做出的努力,本人就是通过参加嘉立创的各种活动培养了硬件方面的能力和兴趣,最后在春招的末尾靠着硬件的知识找到了硬件工程师的工作(秋招一直找嵌软工作根本卷不过人家),从一个机械专业的硕士成功转成了硬件方向,也算是脱离苦海了。
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。









