背景$ o7 C' F/ c0 B- d- D
本文用于记录平衡自行车的制作过程,及制作中遇到的问题;总体方案如下:采用采用STM32F103C8T6作为主控单元、MPU-6050作为位姿采集单元、0.96寸OLED显示位姿、无刷电机带动动量轮调节小车平衡、1S锂电池配合5V和12V升压模块作为电源、蓝牙模块用于和微信小程序进行无线通讯和PID调试、舵机用于控制行驶方向和支撑小车。
8 f) A7 _; Z7 `2 Q6 Q H+ o: [OLED规格及参数简介我用的是四针脚IIC通讯的OLED,0.96寸,像素是128*64的,如下所示:
/ B4 A: B( M7 k
7 O+ s4 M6 T1 j2 y( `3 b OLED显示MPU-6050位姿数据 在上一篇专栏建立工程()的基础上,添加OLED驱动函数到iCode文件中,步骤参考上一篇专栏。
' ^( ^2 {' f* m
. o1 A- k, v0 Y2 G0 n% v# t& ?0 [ 在main函数中添加OLED初始化函数,如下所示: - /* USER CODE BEGIN 2 */# F6 `, R" g' ^) S; w" t
7 m1 G3 v7 ]0 s3 K) r$ a; s+ X- /* ************0.96寸OLED初始化设置************* */ |$ r) y. A8 S. e g! H
- char buffer[16];//float转换成char[]6 `# l' m3 Q; K' k
- OLED_Init();1 a- o1 i& `. _: V+ A, p
- OLED_ON();( X9 e6 W2 U0 P( n; M
- OLED_Clear();
+ @; z& t, u/ w; W; a - OLED_ShowStr(25,0,"DIY",2); M* x: |! O- x
- OLED_ShowCN(49, 0, 0);//攻0 x- r$ M+ z7 J. q4 n0 D
- OLED_ShowCN(65, 0, 1);//城6 y' f, W: t; m! ]% {( P
- OLED_ShowCN(81, 0, 2);//狮8 v6 V* a) R* [! e$ v, ^# L9 j
- OLED_ShowStr(10,2,"Temp:",2);1 I4 q) M9 k z2 p0 }! ~7 o! L. T
- OLED_ShowStr(10,4,"Pitch:",2);
- [8 q+ C3 {: X# ?$ b/ J
? |/ v& y! O* C& M% G- /* ************MPU-6050初始化设置************* */
$ n2 a# s ^ N( ?0 k& i9 ]% Y5 Z - while (MPU_Init()){ //如果初始化失败,继续初始�?
+ A( J' M' Y# {8 _ - printf("MPU_Init_Fail...");: a6 O4 S" x. ]/ Y
- }
. S% d) I5 q. r4 O0 d - ' J% \0 _" r1 e) }; W* r
- /* USER CODE END 2 */( I. L9 L; p' h" q0 [6 Z. ]7 y+ E& w
' N0 {% M1 a3 y" \* D- /* Infinite loop */$ L% L: O( H9 e4 x/ v
- /* USER CODE BEGIN WHILE */; i4 { T( s. ]* H) P5 J# M
- while (1)
, c' p6 l! g7 B' ^ - {
( C& ]; D& }! U+ s% r - /* ************获取和显示温度************* */, A2 X9 M/ b. p& e# ?3 o
- float temp = MPU_Get_Temperature()/100.0;
8 E+ g) a# Y0 h( o/ m4 U3 V - sprintf(buffer, "%.1f", temp);//float转换成char[]
1 [7 C9 }& C1 u* H4 l - OLED_ShowStr(68,2,buffer,2);" n% p/ X1 }/ g" i3 b; ~! |
4 x& v+ K/ \; B5 t- /* **********获取和显示MPU-6050位姿*********** */
1 E V9 d) ]1 w" J. z! ~ A$ o2 b - GetAngle();
" n, X: P3 }3 A - sprintf(buffer, "%.2f", Pitch);//float转换成char[]) p4 _2 j; Y1 M
- if (Pitch>=0){5 g* \" h' Y8 G- L4 Q
- OLED_ShowStr(60,4," ",2);
0 {# _$ g* v# e I# D; ? - OLED_ShowStr(100,4," ",2);
- B; K( K7 e/ o5 Y3 y - OLED_ShowStr(68,4,(unsigned char*)buffer,2);, X5 l9 w6 p- \2 J5 r
- }9 F+ \( T3 F2 Z p
- else# w- [8 B! m" `/ d, r
- {# b" S$ \1 j& t, @7 H
- OLED_ShowStr(100,4," ",2);" @/ Z& |/ w; z
- OLED_ShowStr(60,4,(unsigned char*)buffer,2);
$ i( X6 I0 Q N$ t - }
; h, R6 @( ~0 K9 j" A; S - /* USER CODE END WHILE */- g1 W+ O1 O$ f/ ^1 x! S
6 q; v3 E' j' C- /* USER CODE BEGIN 3 */
+ T/ r* [7 J, f& U" r - }
复制代码
6 k, |4 ~3 g+ ]! }+ X' A / l, N& F: Z" y, o( K& K+ e, K: h
% A" B3 T' ]. K5 Q, y8 k/* USER CODE BEGIN 2 */ /* ************0.96寸OLED初始化设置************* */ char buffer[16;//float转换成char[] OLED_Init(); OLED_ON(); OLED_Clear(); OLED_ShowStr(25,0,"DIY",2); OLED_ShowCN(49, 0, 0);//攻 OLED_ShowCN(65, 0, 1);//城 OLED_ShowCN(81, 0, 2);//狮 OLED_ShowStr(10,2,"Temp:",2); OLED_ShowStr(10,4,"Pitch:",2); /* ************MPU-6050初始化设置************* */ while (MPU_Init()){ //如果初始化失败,继续初始�? printf("MPU_Init_Fail..."); } /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* ************获取和显示温度************* */ float temp = MPU_Get_Temperature()/100.0; sprintf(buffer, "%.1f", temp);//float转换成char[] OLED_ShowStr(68,2,buffer,2); /* **********获取和显示MPU-6050位姿*********** */ GetAngle(); sprintf(buffer, "%.2f", Pitch);//float转换成char[] if (Pitch>=0){ OLED_ShowStr(60,4," ",2); OLED_ShowStr(100,4," ",2); OLED_ShowStr(68,4,(unsigned char*)buffer,2); } else { OLED_ShowStr(100,4," ",2); OLED_ShowStr(60,4,(unsigned char*)buffer,2); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }* E& j: ]3 }" @" J* s- C
显示效果如下:
4 X T; t; m+ P6 j$ C+ G# y6 Q/ v, o/ ]& W$ A) q6 d
 创建中文字库 打开字体取模软件PCtoLCD2002.exe,点击【模式】,选择字符模式。
. E1 e$ e! B: l* [; U' X8 d- t \. u' f" l5 C# X5 B1 R
 点击【选项】进行如下设置,定义每个汉字的显示大小为16×16像素:
! C) C$ b! X5 C* r1 E; _9 h8 j' m* H7 x+ p: G
 输入要取模的文字,点击【生成文字】。4 O5 j5 w( S9 \6 \. a1 l
1 d$ u) g5 e- `, C6 W5 V) V
( W4 a7 P) M: Q: Y' ` 将复制的内容粘贴到驱动函数库中 FONT.h 中 unsigned char F16x16[]数组中: - unsigned char F16x16[] =4 W! O* R$ ?9 C# n% U" H/ u; n
- {
( X6 G9 ]* [, L6 ]) d( j - 0x08,0x08,0x08,0xF8,0x08,0x08,0x48,0x20,0xD8,0x17,0x10,0x10,0xF0,0x10,0x10,0x00, 0x10,0x30,0x10,0x1F,0x08,0x08,0x88,0x40,0x21,0x16,0x08,0x16,0x21,0x40,0x80,0x00,/*"攻",0*/
5 l# n+ k/ L. p `+ Q3 X, V - /* (16 X 16 , 宋体 )*/4 J" { b: l4 n. o8 C$ S" E
- 0x20,0x20,0xFF,0x20,0x20,0xF8,0x88,0x88,0x88,0x08,0xFF,0x08,0x09,0xCA,0x08,0x00, 0x10,0x30,0x1F,0x88,0x68,0x1F,0x10,0x20,0x9F,0x40,0x27,0x18,0x26,0x41,0xF0,0x00,/*"城",1*/' e( O' z4 c' J$ _/ V
- /* (16 X 16 , 宋体 )*/# S# P, f3 }) {8 l
- 0x22,0x14,0x08,0xF4,0x02,0xF8,0x00,0xFF,0x02,0xF2,0x12,0xFE,0x12,0xF2,0x02,0x00,6 P# _9 [; o/ |
- 0x44,0x82,0x41,0x3F,0x80,0x47,0x30,0x0F,0x00,0x1F,0x00,0xFF,0x10,0x1F,0x00,0x00,/*"狮",2*/1 a; J$ F+ j# H5 {
- /* (16 X 16 , 宋体 )*/
. s9 ^; L7 P+ s2 L - };
复制代码
. i3 f5 a. ]/ c% G( q* YOLED_ShowStr(25,0," DIY",2); OLED_ShowCN(41,0,0);//攻 OLED_ShowCN(57,0,1);//城 OLED_ShowCN(73,0,2);//狮 . U, P* x+ [5 [/ u# i
显示效果如下: / C% p v. F1 L4 d6 B

) W7 H% L3 W j$ C6 s; S
# G, k. N2 x2 j* U作者:DIY攻城狮
/ Y0 G# X& L+ O; W/ Q, ?4 s* u: K( Z
2 C0 E/ d% Y) V- D! A |