背景6 U; m3 m7 o+ N
本文用于记录平衡自行车的制作过程,及制作中遇到的问题;总体方案如下:采用采用STM32F103C8T6作为主控单元、MPU-6050作为位姿采集单元、0.96寸OLED显示位姿、无刷电机带动动量轮调节小车平衡、1S锂电池配合5V和12V升压模块作为电源、蓝牙模块用于和微信小程序进行无线通讯和PID调试、舵机用于控制行驶方向和支撑小车。
9 a1 J' ~4 E8 s: N6 a1 XOLED规格及参数简介我用的是四针脚IIC通讯的OLED,0.96寸,像素是128*64的,如下所示: 0 _, I; h+ C. A ?
: P! ]1 L1 ~; @0 S OLED显示MPU-6050位姿数据 在上一篇专栏建立工程()的基础上,添加OLED驱动函数到iCode文件中,步骤参考上一篇专栏。 6 D3 Y, z# I% A, o2 [
# t& e0 Q' e X2 N/ g
 在main函数中添加OLED初始化函数,如下所示: - /* USER CODE BEGIN 2 */
& W* y1 K$ c. g( ^! s( h8 P, J, C
?8 i6 b! v) a. y& v# W6 [- /* ************0.96寸OLED初始化设置************* */
* Y. G! K. _. ~8 v2 V4 c( x - char buffer[16];//float转换成char[]
/ r) f% @9 y x! ]* F* ~# m, B - OLED_Init();. N" G2 y6 P, C8 J+ A0 T+ e
- OLED_ON();0 F/ Q2 p& o7 H6 z1 C. \$ f* y
- OLED_Clear();
1 b5 d% @$ r5 ~* B) V1 g) G' `: v - OLED_ShowStr(25,0,"DIY",2);
$ g# x0 f4 f5 |, b/ G5 R - OLED_ShowCN(49, 0, 0);//攻
; e V9 O5 `* P1 p - OLED_ShowCN(65, 0, 1);//城1 E2 D$ D2 o9 b1 r0 t
- OLED_ShowCN(81, 0, 2);//狮
' Q8 q/ w4 E) @$ i - OLED_ShowStr(10,2,"Temp:",2);
8 ?% N d2 o ?: {( x8 j - OLED_ShowStr(10,4,"Pitch:",2);
2 T1 o& ]1 G# J1 r$ g0 |! `- |! `/ @
) f9 z0 ?; h0 H! h4 o+ h' y, N9 M- /* ************MPU-6050初始化设置************* */: g' P: h0 [1 L
- while (MPU_Init()){ //如果初始化失败,继续初始�?
2 ^# K/ O3 y/ h2 d - printf("MPU_Init_Fail...");% V6 ~$ n# y( U9 c7 F: |
- }
& ~5 W6 P4 k- i- I9 O2 T) W - ; d E( D% x: l+ m: r6 S
- /* USER CODE END 2 */+ a( t( R( A: s+ t' A
- 0 b7 l# v+ {7 Q( Z) f
- /* Infinite loop */
& r2 ] h: I# e X& y - /* USER CODE BEGIN WHILE */' w% B/ Y" z' {' [* W
- while (1)8 G `$ a; U! H- j! t9 [
- {
0 l$ `# z8 {( H8 l- k/ A - /* ************获取和显示温度************* */1 Q# r$ y7 b) \: O. v% @
- float temp = MPU_Get_Temperature()/100.0;
* ?8 i) v1 D4 N1 D- I' k% b$ f - sprintf(buffer, "%.1f", temp);//float转换成char[]
: K# L+ s* R: L2 E+ [. r3 [ - OLED_ShowStr(68,2,buffer,2);
7 I. j) o8 ^/ C2 \1 O) }/ }2 Z - . Z- F& m2 Y6 N8 ^: x, K% `9 S! [% x
- /* **********获取和显示MPU-6050位姿*********** */4 W' z1 ]6 X0 R* n0 {# a% r
- GetAngle();
4 `0 f% P1 l: A9 S+ M4 @ - sprintf(buffer, "%.2f", Pitch);//float转换成char[]7 T$ c- O* i9 F& a) R5 P
- if (Pitch>=0){
+ Q2 a# `1 a+ t7 A9 g9 m - OLED_ShowStr(60,4," ",2);
" F3 V( L8 d$ J9 t$ ^% q- N' g2 e - OLED_ShowStr(100,4," ",2);
/ G# @& M* h! b3 f# F( \ j - OLED_ShowStr(68,4,(unsigned char*)buffer,2);
E2 s- ^/ i$ u/ Q7 A! _. d- i - }: P7 k+ O4 e5 g, o V9 f1 a
- else
! q6 m" B5 X* T& d' E! i7 L$ v u - {
9 D7 ^. c& `/ \. h" {8 b - OLED_ShowStr(100,4," ",2);
" A7 _8 u/ R4 ]3 d. k9 U - OLED_ShowStr(60,4,(unsigned char*)buffer,2);
' V' T* ]8 c' O4 |; m2 t& W* S - }
# g% z7 c F3 j* T9 T! l2 v& j$ ~: c - /* USER CODE END WHILE */6 l5 B* u" y* h H
- - ^' O" q ~- p4 H" [
- /* USER CODE BEGIN 3 */
4 h/ X* ^: _8 Z; g6 L& y6 r9 L - }
复制代码
2 T5 q9 ?6 ?0 c7 D( U) Y. d# n% o + k* F; K+ Q# j$ t; I' G* `* b$ n
( @# |4 I0 G2 V. H8 e# i2 [4 Q
/* 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 */ }- {( q+ J" L; ^9 F! z- H& N; D
显示效果如下: , W7 J& e/ ~& k0 H9 u
$ D; r2 p9 n7 h3 \/ O0 o9 L7 t. t 创建中文字库 打开字体取模软件PCtoLCD2002.exe,点击【模式】,选择字符模式。
/ C |5 x. `" A- [- f! M1 S0 p% [
+ e. V# I1 b% @8 @- k0 h* r$ b( F 点击【选项】进行如下设置,定义每个汉字的显示大小为16×16像素:
' P% F" _2 e$ f0 r
+ j+ z. E$ J1 I% T0 B 输入要取模的文字,点击【生成文字】。
0 O/ V- z7 u: ~5 K9 ~: r1 l
& v0 d, e" D0 ~* B" o
/ C5 w$ v% B. e! v; Y 将复制的内容粘贴到驱动函数库中 FONT.h 中 unsigned char F16x16[]数组中: - unsigned char F16x16[] =7 I# }# X. d, M! z$ y
- {3 B5 P' b9 E G& v9 p! |; C2 Y9 m
- 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*/* R8 t$ a# \5 q5 d
- /* (16 X 16 , 宋体 )*/* F. w- e0 W; t8 g
- 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*/
7 ^$ U& b+ W1 \* e& D5 B - /* (16 X 16 , 宋体 )*/
% E% m [% M; C - 0x22,0x14,0x08,0xF4,0x02,0xF8,0x00,0xFF,0x02,0xF2,0x12,0xFE,0x12,0xF2,0x02,0x00,
# T0 _) a, b s2 @/ E6 U - 0x44,0x82,0x41,0x3F,0x80,0x47,0x30,0x0F,0x00,0x1F,0x00,0xFF,0x10,0x1F,0x00,0x00,/*"狮",2*/0 s/ w- ?/ w2 U
- /* (16 X 16 , 宋体 )*/7 Z* e' y0 \% o; |( {2 g( _, T
- };
复制代码
* ^ w9 L2 M! m, X% r- L HOLED_ShowStr(25,0," DIY",2); OLED_ShowCN(41,0,0);//攻 OLED_ShowCN(57,0,1);//城 OLED_ShowCN(73,0,2);//狮
/ a) A/ W+ C8 I$ \显示效果如下: # q8 H3 A- U6 K( D/ c
9 c d& M. \9 I" d3 `' E
9 n7 @, W: Y7 h3 [作者:DIY攻城狮
2 A8 z, W6 d. u7 z8 P* G% \$ @
; l# R. Q: J5 g7 Y! i9 e |