STM32 学习笔记-代码库(HAL版本)

收集总结代码库

1. LED

设置

image-20240821231951653 image-20240821232139717

驱动程序

led.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
// Created by Titan on 24-8-17.
//

#ifndef LED_H
#define LED_H

#include "stm32f1xx_hal.h" //HAL库文件声明
#include "main.h" //IO定义与初始化函数在main.c文件中,必须引用

void LED_1(uint8_t a);//LED1独立控制函数(0为熄灭,其他值为点亮)
void LED_2(uint8_t a);//LED2独立控制函数(0为熄灭,其他值为点亮)
void LED_ALL(uint8_t a);//LED1~4整组操作函数(低4位的1/0状态对应4个LED亮灭,最低位对应LED1)
void LED_1_Contrary(void);//LED1状态取反
void LED_2_Contrary(void);//LED2状态取反

#endif //LED_H

led.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//
// Created by Titan on 24-8-17.
//

#include "led.h"

void LED_1(uint8_t a)//LED1独立控制函数(0为熄灭,其他值为点亮)
{
if(a)HAL_GPIO_WritePin(GPIOB,LED1_Pin,GPIO_PIN_SET);
else HAL_GPIO_WritePin(GPIOB,LED1_Pin,GPIO_PIN_RESET);
}
void LED_2(uint8_t a)//LED2独立控制函数(0为熄灭,其他值为点亮)
{
if(a)HAL_GPIO_WritePin(GPIOB,LED2_Pin,GPIO_PIN_SET);
else HAL_GPIO_WritePin(GPIOB,LED2_Pin,GPIO_PIN_RESET);
}
void LED_ALL(uint8_t a)//LED1~2整组操作函数(低2位的1/0状态对应2个LED亮灭,最低位对应LED1)
{
if(a&0x01)HAL_GPIO_WritePin(GPIOB,LED1_Pin,GPIO_PIN_SET);
else HAL_GPIO_WritePin(GPIOB,LED1_Pin,GPIO_PIN_RESET);
if(a&0x02)HAL_GPIO_WritePin(GPIOB,LED2_Pin,GPIO_PIN_SET);
else HAL_GPIO_WritePin(GPIOB,LED2_Pin,GPIO_PIN_RESET);
}
void LED_1_Contrary(void){
HAL_GPIO_WritePin(GPIOB,LED1_Pin,1-HAL_GPIO_ReadPin(GPIOB,LED1_Pin));
}
void LED_2_Contrary(void){
HAL_GPIO_WritePin(GPIOB,LED2_Pin,1-HAL_GPIO_ReadPin(GPIOB,LED2_Pin));
}

主程序

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* USER CODE BEGIN Includes */
#include "../../icode/led/led.h"
/* USER CODE END Includes */

while (1)
{

LED_1(1);
HAL_Delay(100);
LED_1(0);
HAL_Delay(100);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}

2. 无源蜂鸣器

设置

驱动程序

buzzer.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// Created by Titan on 24-8-17.
//

#ifndef BUZZER_H
#define BUZZER_H

#include "stm32f1xx_hal.h" //HAL库文件声明
#include "main.h"
#include "../delay/delay.h"

void BUZZER_SOLO1(void);
void BUZZER_SOLO2(void);

#endif //BUZZER_H

buzzer.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//
// Created by Titan on 24-8-17.
//

#include "buzzer.h"

#define time1 50 //单音的时长
#define hz1 1 //单音的音调(单位毫秒)
void BUZZER_SOLO1(void){//蜂鸣器输出单音的报警音(样式1:HAL库的精准延时函数)
uint16_t i;
for(i=0;i<time1;i++){//循环次数决定单音的时长
HAL_GPIO_WritePin(BEEP1_GPIO_Port,BEEP1_Pin,GPIO_PIN_RESET); //蜂鸣器接口输出低电平0
HAL_Delay(hz1); //延时(毫秒级延时最小1微秒,实现的单调较低,因不需要额外编写微秒级延时函数所以最简单实用)
HAL_GPIO_WritePin(BEEP1_GPIO_Port,BEEP1_Pin,GPIO_PIN_SET); //蜂鸣器接口输出高电平1
HAL_Delay(hz1); //延时
}
}
#define time2 200 //单音的时长
#define hz2 500 //单音的音调(单位微秒)
void BUZZER_SOLO2(void){//蜂鸣器输出单音的报警音(样式2:CPU微秒级延时)
uint16_t i;
for(i=0;i<time2;i++){//循环次数决定单音的时长
HAL_GPIO_WritePin(BEEP1_GPIO_Port,BEEP1_Pin,GPIO_PIN_RESET); //蜂鸣器接口输出低电平0
delay_us(hz2); //延时
HAL_GPIO_WritePin(BEEP1_GPIO_Port,BEEP1_Pin,GPIO_PIN_SET); //蜂鸣器接口输出高电平1
delay_us(hz2); //延时
}
}

主程序

1
2
3
4
5
#include "../../Drivers/icode/buzzer/buzzer.h"


# TODO 补充

3. DHT11(温湿度)

设置

image-20240821235755453 image-20240821235842673

驱动程序

dht11.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Created by Titan on 24-8-18.
//

#ifndef DHT11_H
#define DHT11_H

#include "stm32f1xx_hal.h"
#include "../delay/delay.h"

void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);

#endif //DHT11_H

dht11.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
// Created by Titan on 24-8-18.
//

#include "dht11.h"
#include "main.h"

void DHT11_IO_OUT (void){ //端口变为输出
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_IO_IN (void){ //端口变为输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
DHT11_IO_OUT();
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);
HAL_Delay(20); //拉低至少18ms
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);
delay_us(30); //主机拉高20~40us
}

uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
uint8_t retry=0;
DHT11_IO_IN();//IO到输入状态
while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1; else retry=0;
while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1;
return 0;
}

uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
uint8_t retry=0;
while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平
retry++;
delay_us(1);
}
retry=0;
while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平
retry++;
delay_us(1);
}
delay_us(40);//等待40us //用于判断高低电平,即数据1或0
if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}

uint8_t Dht11_ReadByte(void){ //从DHT11读取一个字节 返回值:读到的数据
uint8_t i,dat;
dat=0;
for (i=0;i<8;i++){
dat<<=1;
dat|=Dht11_ReadBit();
}
return dat;
}

uint8_t DHT11_Init (void){ //DHT11初始化
DHT11_RST();//DHT11端口复位,发出起始信号
return Dht11_Check(); //等待DHT11回应
}

uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
uint8_t buf[5];
uint8_t i;
DHT11_RST();//DHT11端口复位,发出起始信号
if(Dht11_Check()==0){ //等待DHT11回应
for(i=0;i<5;i++){//读取5位数据
buf[i]=Dht11_ReadByte(); //读出数据
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){ //数据校验
*h=buf[0]; //将湿度值放入指针1
h++;
*h=buf[2]; //将温度值放入指针2
}
}else return 1;
return 0;
}

主程序

main.c

1
2
3
4
5
6
7
/* USER CODE BEGIN 1 */
// uint16_t a1, a2;
// uint16_t dmaadc[2];

uint8_t DHT11_BUF[2] = {0};//用于存放DHT11数据

/* USER CODE END 1 */
1
2
3
4
5
/* USER CODE BEGIN 2 */
DHT11_Init();//传感器芯片初始化
HAL_Delay(1500);//毫秒延时
DHT11_ReadData(DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)
/* USER CODE END 2 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* USER CODE BEGIN WHILE */

DHT11_ReadData(DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)
char a[100];
sprintf(a, " RH: %d", DHT11_BUF[0]);

char b[100];
sprintf(b, "TEMP: %d", DHT11_BUF[1]);
// sprintf(a, "T:%02d% M:%02d℃\r\n",DHT11_BUF[0],DHT11_BUF[1]);
HAL_Delay(1500);//毫秒延时

OLED_DISPLAY_8x16_BUFFER(4, b); //显示字符串
OLED_DISPLAY_8x16_BUFFER(6, a); //显示字符串

/* USER CODE END WHILE */

4. OLED

设置

image-20240822000314744 image-20240822000355554

驱动程序

ASCII.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/*
* ASCII.h
*
* Created on: Jun 11, 2022
* Author: Administrator
*/

#ifndef OLED_ASCII_H_
#define OLED_ASCII_H_

// ------------------ ASCII字模的数据表 ------------------------ //
// 码表从0x20~0x7e //
// 字库: 纵向取模下高位// (调用时要减512)
// -------------------------------------------------------------- //
const uint8_t ASCII_8x16[] = { // ASCII
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // - -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x38,0xFC,0xFC,0x38,0x00,0x00, // -!-
0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00,

0x00,0x0E,0x1E,0x00,0x00,0x1E,0x0E,0x00, // -"-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x20,0xF8,0xF8,0x20,0xF8,0xF8,0x20,0x00, // -#-
0x02,0x0F,0x0F,0x02,0x0F,0x0F,0x02,0x00,

0x38,0x7C,0x44,0x47,0x47,0xCC,0x98,0x00, // -$-
0x03,0x06,0x04,0x1C,0x1C,0x07,0x03,0x00,

0x30,0x30,0x00,0x80,0xC0,0x60,0x30,0x00, // -%-
0x0C,0x06,0x03,0x01,0x00,0x0C,0x0C,0x00,

0x80,0xD8,0x7C,0xE4,0xBC,0xD8,0x40,0x00, // -&-
0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,0x00, // -'-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0xF0,0xF8,0x0C,0x04,0x00,0x00, // -(-
0x00,0x00,0x03,0x07,0x0C,0x08,0x00,0x00,

0x00,0x00,0x04,0x0C,0xF8,0xF0,0x00,0x00, // -)-
0x00,0x00,0x08,0x0C,0x07,0x03,0x00,0x00,

0x80,0xA0,0xE0,0xC0,0xC0,0xE0,0xA0,0x80, // -*-
0x00,0x02,0x03,0x01,0x01,0x03,0x02,0x00,

0x00,0x80,0x80,0xE0,0xE0,0x80,0x80,0x00, // -+-
0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -,-
0x00,0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,

0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, // ---
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -.-
0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,

0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x00, // -/-
0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,

0xF8,0xFC,0x04,0xC4,0x24,0xFC,0xF8,0x00, // -0-
0x07,0x0F,0x09,0x08,0x08,0x0F,0x07,0x00,

0x00,0x10,0x18,0xFC,0xFC,0x00,0x00,0x00, // -1-
0x00,0x08,0x08,0x0F,0x0F,0x08,0x08,0x00,

0x08,0x0C,0x84,0xC4,0x64,0x3C,0x18,0x00, // -2-
0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0C,0x00,

0x08,0x0C,0x44,0x44,0x44,0xFC,0xB8,0x00, // -3-
0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,

0xC0,0xE0,0xB0,0x98,0xFC,0xFC,0x80,0x00, // -4-
0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,

0x7C,0x7C,0x44,0x44,0xC4,0xC4,0x84,0x00, // -5-
0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,

0xF0,0xF8,0x4C,0x44,0x44,0xC0,0x80,0x00, // -6-
0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

0x0C,0x0C,0x04,0x84,0xC4,0x7C,0x3C,0x00, // -7-
0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,

0xB8,0xFC,0x44,0x44,0x44,0xFC,0xB8,0x00, // -8-
0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

0x38,0x7C,0x44,0x44,0x44,0xFC,0xF8,0x00, // -9-
0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00,

0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, // -:-
0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,

0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, // -;-
0x00,0x00,0x08,0x0E,0x06,0x00,0x00,0x00,

0x00,0x80,0xC0,0x60,0x30,0x18,0x08,0x00, // -<-
0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x00,

0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, // -=-
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,

0x00,0x08,0x18,0x30,0x60,0xC0,0x80,0x00, // ->-
0x00,0x08,0x0C,0x06,0x03,0x01,0x00,0x00,

0x18,0x1C,0x04,0xC4,0xE4,0x3C,0x18,0x00, // -?-
0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00,

0xF0,0xF8,0x08,0xC8,0xC8,0xF8,0xF0,0x00, // -@-
0x07,0x0F,0x08,0x0B,0x0B,0x0B,0x01,0x00,

0xE0,0xF0,0x98,0x8C,0x98,0xF0,0xE0,0x00, // -A-
0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

0x04,0xFC,0xFC,0x44,0x44,0xFC,0xB8,0x00, // -B-
0x08,0x0F,0x0F,0x08,0x08,0x0F,0x07,0x00,

0xF0,0xF8,0x0C,0x04,0x04,0x0C,0x18,0x00, // -C-
0x03,0x07,0x0C,0x08,0x08,0x0C,0x06,0x00,

0x04,0xFC,0xFC,0x04,0x0C,0xF8,0xF0,0x00, // -D-
0x08,0x0F,0x0F,0x08,0x0C,0x07,0x03,0x00,

0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00, // -E-
0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00,

0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00, // -F-
0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

0xF0,0xF8,0x0C,0x84,0x84,0x8C,0x98,0x00, // -G-
0x03,0x07,0x0C,0x08,0x08,0x07,0x0F,0x00,

0xFC,0xFC,0x40,0x40,0x40,0xFC,0xFC,0x00, // -H-
0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x00, // -I-
0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

0x00,0x00,0x00,0x04,0xFC,0xFC,0x04,0x00, // -J-
0x07,0x0F,0x08,0x08,0x0F,0x07,0x00,0x00,

0x04,0xFC,0xFC,0xC0,0xF0,0x3C,0x0C,0x00, // -K-
0x08,0x0F,0x0F,0x00,0x01,0x0F,0x0E,0x00,

0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x00, // -L-
0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00,

0xFC,0xFC,0x38,0x70,0x38,0xFC,0xFC,0x00, // -M-
0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

0xFC,0xFC,0x38,0x70,0xE0,0xFC,0xFC,0x00, // -N-
0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

0xF0,0xF8,0x0C,0x04,0x0C,0xF8,0xF0,0x00, // -O-
0x03,0x07,0x0C,0x08,0x0C,0x07,0x03,0x00,

0x04,0xFC,0xFC,0x44,0x44,0x7C,0x38,0x00, // -P-
0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

0xF8,0xFC,0x04,0x04,0x04,0xFC,0xF8,0x00, // -Q-
0x07,0x0F,0x08,0x0E,0x3C,0x3F,0x27,0x00,

0x04,0xFC,0xFC,0x44,0xC4,0xFC,0x38,0x00, // -R-
0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

0x18,0x3C,0x64,0x44,0xC4,0x9C,0x18,0x00, // -S-
0x06,0x0E,0x08,0x08,0x08,0x0F,0x07,0x00,

0x00,0x1C,0x0C,0xFC,0xFC,0x0C,0x1C,0x00, // -T-
0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00, // -U-
0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00, // -V-
0x01,0x03,0x06,0x0C,0x06,0x03,0x01,0x00,

0xFC,0xFC,0x00,0x80,0x00,0xFC,0xFC,0x00, // -W-
0x03,0x0F,0x0E,0x03,0x0E,0x0F,0x03,0x00,

0x0C,0x3C,0xF0,0xC0,0xF0,0x3C,0x0C,0x00, // -X-
0x0C,0x0F,0x03,0x00,0x03,0x0F,0x0C,0x00,

0x00,0x3C,0x7C,0xC0,0xC0,0x7C,0x3C,0x00, // -Y-
0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

0x1C,0x0C,0x84,0xC4,0x64,0x3C,0x1C,0x00, // -Z-
0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0E,0x00,

0x00,0x00,0xFC,0xFC,0x04,0x04,0x00,0x00, // -[-
0x00,0x00,0x0F,0x0F,0x08,0x08,0x00,0x00,

0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00, // -\-
0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x00,

0x00,0x00,0x04,0x04,0xFC,0xFC,0x00,0x00, // -]-
0x00,0x00,0x08,0x08,0x0F,0x0F,0x00,0x00,

0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00, // -^-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -_-
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00, // -`-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0xA0,0xA0,0xA0,0xE0,0xC0,0x00,0x00, // -a-
0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

0x04,0xFC,0xFC,0x20,0x60,0xC0,0x80,0x00, // -b-
0x08,0x0F,0x07,0x08,0x08,0x0F,0x07,0x00,

0xC0,0xE0,0x20,0x20,0x20,0x60,0x40,0x00, // -c-
0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00,

0x80,0xC0,0x60,0x24,0xFC,0xFC,0x00,0x00, // -d-
0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

0xC0,0xE0,0xA0,0xA0,0xA0,0xE0,0xC0,0x00, // -e-
0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00,

0x40,0xF8,0xFC,0x44,0x0C,0x18,0x00,0x00, // -f-
0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00, // -g-
0x27,0x6F,0x48,0x48,0x7F,0x3F,0x00,0x00,

0x04,0xFC,0xFC,0x40,0x20,0xE0,0xC0,0x00, // -h-
0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x00, // -i-
0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

0x00,0x00,0x00,0x00,0x20,0xEC,0xEC,0x00, // -j-
0x00,0x30,0x70,0x40,0x40,0x7F,0x3F,0x00,

0x04,0xFC,0xFC,0x80,0xC0,0x60,0x20,0x00, // -k-
0x08,0x0F,0x0F,0x01,0x03,0x0E,0x0C,0x00,

0x00,0x00,0x04,0xFC,0xFC,0x00,0x00,0x00, // -l-
0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

0xE0,0xE0,0x60,0xC0,0x60,0xE0,0xC0,0x00, // -m-
0x0F,0x0F,0x00,0x0F,0x00,0x0F,0x0F,0x00,

0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00, // -n-
0x00,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

0xC0,0xE0,0x20,0x20,0x20,0xE0,0xC0,0x00, // -o-
0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00, // -p-
0x40,0x7F,0x7F,0x48,0x08,0x0F,0x07,0x00,

0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00, // -q-
0x07,0x0F,0x08,0x48,0x7F,0x7F,0x40,0x00,

0x20,0xE0,0xC0,0x60,0x20,0x60,0xC0,0x00, // -r-
0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

0x40,0xE0,0xA0,0x20,0x20,0x60,0x40,0x00, // -s-
0x04,0x0C,0x09,0x09,0x0B,0x0E,0x04,0x00,

0x20,0x20,0xF8,0xFC,0x20,0x20,0x00,0x00, // -t-
0x00,0x00,0x07,0x0F,0x08,0x0C,0x04,0x00,

0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00, // -u-
0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00, // -v-
0x00,0x03,0x07,0x0C,0x0C,0x07,0x03,0x00,

0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00, // -w-
0x07,0x0F,0x0C,0x07,0x0C,0x0F,0x07,0x00,

0x20,0x60,0xC0,0x80,0xC0,0x60,0x20,0x00, // -x-
0x08,0x0C,0x07,0x03,0x07,0x0C,0x08,0x00,

0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00, // -y-
0x47,0x4F,0x48,0x48,0x68,0x3F,0x1F,0x00,

0x60,0x60,0x20,0xA0,0xE0,0x60,0x20,0x00, // -z-
0x0C,0x0E,0x0B,0x09,0x08,0x0C,0x0C,0x00,

0x00,0x40,0x40,0xF8,0xBC,0x04,0x04,0x00, // -{-
0x00,0x00,0x00,0x07,0x0F,0x08,0x08,0x00,

0x00,0x00,0x00,0xBC,0xBC,0x00,0x00,0x00, // -|-
0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,

0x00,0x04,0x04,0xBC,0xF8,0x40,0x40,0x00, // -}-
0x00,0x08,0x08,0x0F,0x07,0x00,0x00,0x00,

0x08,0x0C,0x04,0x0C,0x08,0x0C,0x04,0x00, // -~-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x80,0xC0,0x60,0x30,0x60,0xC0,0x80,0x00, // --
0x07,0x07,0x04,0x04,0x04,0x07,0x07,0x00,
};

#endif /* OLED_ASCII_H_ */

CHS_16x16.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef __CHS_16x16_H
#define __CHS_16x16_H

const uint8_t GB_16[] = {
// 数据表
//"温",
0x10, 0x22, 0x64, 0x0C, 0x80, 0x00, 0xFE, 0x92,
0x92, 0x92, 0x92, 0x92, 0xFF, 0x02, 0x00, 0x00,
0x04, 0x04, 0xFE, 0x01, 0x40, 0x7E, 0x42, 0x42,
0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x00,
//"湿",
0x10, 0x22, 0x64, 0x0C, 0x80, 0xFE, 0x92, 0x92,
0x92, 0x92, 0x92, 0x92, 0xFF, 0x02, 0x00, 0x00,
0x04, 0x04, 0xFE, 0x41, 0x44, 0x48, 0x50, 0x7F,
0x40, 0x40, 0x7F, 0x50, 0x48, 0x64, 0x40, 0x00,
//"度",
0x00, 0x00, 0xFC, 0x24, 0x24, 0x24, 0xFC, 0xA5,
0xA6, 0xA4, 0xFC, 0x24, 0x34, 0x26, 0x04, 0x00,
0x40, 0x20, 0x9F, 0x80, 0x42, 0x42, 0x26, 0x2A,
0x12, 0x2A, 0x26, 0x42, 0x40, 0xC0, 0x40, 0x00,
//"计",
0x40, 0x40, 0x42, 0xCC, 0x00, 0x40, 0x40, 0x40,
0x40, 0xFF, 0x40, 0x40, 0x40, 0x60, 0x40, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x08, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

#endif

oled.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//
// Created by Titan on 24-8-17.
//

#ifndef OLED_H
#define OLED_H

#include "stm32f1xx_hal.h" //HAL库文件声明
#include "main.h" //IO定义与初始化函数在main.c文件中,必须引用

extern I2C_HandleTypeDef hi2c1;//声明USART1的HAL库结构体

#define OLED0561_ADD 0x78 // OLED的I2C地址(禁止修改)
#define COM 0x00 // OLED 指令(禁止修改)
#define DAT 0x40 // OLED 数据(禁止修改)

void OLED0561_Init(void);//初始化
void OLED_DISPLAY_ON (void);//OLED屏开显示
void OLED_DISPLAY_OFF (void);//OLED屏关显示
void OLED_DISPLAY_LIT (uint8_t x);//OLED屏亮度设置(0~255)
void OLED_DISPLAY_CLEAR(void);//清屏操作
void OLED_DISPLAY_8x16(uint8_t x,uint8_t y,uint16_t w);//显示8x16的单个字符
void OLED_DISPLAY_8x16_BUFFER(uint8_t row,uint8_t *str);//显示8x16的字符串
void OLED_DISPLAY_16x16(uint8_t x,uint8_t y,uint16_t w); //汉字显示

#endif //OLED_H

oled.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
// Created by Titan on 24-8-17.
//

#include "oled.h"
#include "ASCII.h"
#include "CHS_16x16.h"


void OLED0561_Init(void)
{
//OLED屏开显示初始化
OLED_DISPLAY_OFF(); //OLED关显示
OLED_DISPLAY_CLEAR(); //清空屏幕内容
OLED_DISPLAY_ON(); //OLED屏初始值设置并开显示
}

void OLED_DISPLAY_ON(void)
{
//OLED屏初始值设置并开显示
uint8_t buf[28] = {
0xae, //0xae:关显示,0xaf:开显示
0x00, 0x10, //开始地址(双字节)
0xd5, 0x80, //显示时钟频率?
0xa8, 0x3f, //复用率?
0xd3, 0x00, //显示偏移?
0XB0, //写入页位置(0xB0~7)
0x40, //显示开始线
0x8d, 0x14, //VCC电源
0xa1, //设置段重新映射?
0xc8, //COM输出方式?
0xda, 0x12, //COM输出方式?
0x81, 0xff, //对比度,指令:0x81,数据:0~255(255最高)
0xd9, 0xf1, //充电周期?
0xdb, 0x30, //VCC电压输出
0x20, 0x00, //水平寻址设置
0xa4, //0xa4:正常显示,0xa5:整体点亮
0xa6, //0xa6:正常显示,0xa7:反色显示
0xaf //0xae:关显示,0xaf:开显示
}; //
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, buf, 28, 1000);
}

void OLED_DISPLAY_OFF(void)
{
//OLED屏关显示
uint8_t buf[3] = {
0xae, //0xae:关显示,0xaf:开显示
0x8d, 0x10, //VCC电源
}; //
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, buf, 3, 1000);
}

void OLED_DISPLAY_LIT(uint8_t x)
{
//OLED屏亮度设置(0~255)
uint8_t buf = 0x81;
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf, 1, 1000);
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &x, 1, 1000); //亮度值
}

void OLED_DISPLAY_CLEAR(void)
{
//清屏操作
uint8_t j, t;
uint8_t buf[2] = {0x10, 0x00};
for (t = 0xB0; t < 0xB8; t++)
{
//设置起始页地址为0xB0
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &t, 1, 1000); //页地址(从0xB0到0xB7)
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[0], 1, 1000); //起始列地址的高4位
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[1], 1, 1000); //起始列地址的低4位
for (j = 0; j < 132; j++)
{
//整页内容填充
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT, &buf[1], 1, 1000);
}
}
}

//显示英文与数字8*16的ASCII码
//取模大小为16*16,取模方式为“从左到右从上到下”“纵向8点下高位”
void OLED_DISPLAY_8x16(uint8_t x, //显示汉字的页坐标(从0到7)(此处不可修改)
uint8_t y, //显示汉字的列坐标(从0到63)
uint16_t w)
{
//要显示汉字的编号
uint8_t j, t, c = 0;
uint8_t buf[4];
y = y + 2; //因OLED屏的内置驱动芯片是从0x02列作为屏上最左一列,所以要加上偏移量
for (t = 0; t < 2; t++)
{
buf[0] = 0xb0 + x;
buf[1] = y / 16 + 0x10;
buf[2] = y % 16;
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[0], 1, 1000); //页地址(从0xB0到0xB7)
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[1], 1, 1000); //起始列地址的高4位
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[2], 1, 1000); //起始列地址的低4位
for (j = 0; j < 8; j++)
{
//整页内容填充
buf[3] = ASCII_8x16[(w * 16) + c - 512];
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT, &buf[3], 1, 1000); //为了和ASII表对应要减512
c++;
}
x++; //页地址加1
}
}

//向LCM发送一个字符串,长度64字符之内。
//应用:OLED_DISPLAY_8_16_BUFFER(0," DoYoung Studio");
void OLED_DISPLAY_8x16_BUFFER(uint8_t row, uint8_t* str)
{
uint8_t r = 0;
while (*str != '\0')
{
OLED_DISPLAY_8x16(row, r * 8, *str++);
r++;
}
}

//----- 用于汉字显示的程序 ------//

//显示汉字16*16
//取模大小为16*16,取模方式为“从左到右从上到下”“纵向8点下高位”
void OLED_DISPLAY_16x16(uint8_t x, //显示汉字的页坐标(从0xB0到0xB7)
uint8_t y, //显示汉字的列坐标(从0到63)
uint16_t w) //要显示汉字的编号
{
//要显示汉字的编号
uint8_t j, t, c = 0;
uint8_t buf[4];
// y = y + 2; //因OLED屏的内置驱动芯片是从0x02列作为屏上最左一列,所以要加上偏移量
for (t = 0; t < 2; t++)
{
buf[0] = 0xb0 + x;
buf[1] = y / 16 + 0x10;
buf[2] = y % 16;
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[0], 1, 1000); //页地址(从0xB0到0xB7)
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[1], 1, 1000); //起始列地址的高4位
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, &buf[2], 1, 1000); //起始列地址的低4位

// I2C_SAND_BYTE(OLED0561_ADD,COM, 0xb0 + x); //页地址(从0xB0到0xB7)
// I2C_SAND_BYTE(OLED0561_ADD,COM, y / 16 + 0x10); //起始列地址的高4位
// I2C_SAND_BYTE(OLED0561_ADD,COM, y % 16); //起始列地址的低4位

uint8_t buf1[1];
for (j = 0; j < 16; j++)
{
buf1[0] = GB_16[(w * 32) + c];
//整页内容填充
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT, &buf1[0], 1, 1000);
// I2C_SAND_BYTE(OLED0561_ADD,DAT, GB_16[(w * 32) + c]);
c++;
}
x++; //页地址加1
}
HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT, 0xAF, 1, 1000);
// I2C_SAND_BYTE(OLED0561_ADD,COM, 0xAF); //开显示
}

// void OLED_DISPLAY_PIC1(void){ //显示全屏图片
// u8 m,i;
// for(m=0;m<8;m++){//
// I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+m);
// I2C_SAND_BYTE(OLED0561_ADD,COM,0x10); //起始列地址的高4位
// I2C_SAND_BYTE(OLED0561_ADD,COM,0x02); //起始列地址的低4位
// for(i=0;i<128;i++){//送入128次图片显示内容
// I2C_SAND_BYTE(OLED0561_ADD,DAT,PIC1[i+m*128]);}
// }
// }

主程序

1
2
3
4
5
6
7
8
9
/* USER CODE BEGIN 2 */

OLED0561_Init(); //OLED初始化
OLED_DISPLAY_16x16(1, 2 * 16, 0);//汉字显示 温湿度计
OLED_DISPLAY_16x16(1, 3 * 16, 1);
OLED_DISPLAY_16x16(1, 4 * 16, 2);
OLED_DISPLAY_16x16(1, 5 * 16, 3);

/* USER CODE END 2 */
1
2
3
4
5
6
/* USER CODE BEGIN WHILE */

OLED_DISPLAY_8x16_BUFFER(4, "b"); //显示字符串
OLED_DISPLAY_8x16_BUFFER(6, "a"); //显示字符串

/* USER CODE END WHILE */

5. ADC

设置

image-20240822003331636 image-20240901165937074

驱动程序

主程序

6. DMA

基于上面的 ADC 功能

设置

驱动程序

主程序

main.c

1
2
/* USER CODE BEGIN 1 */
uint16_t dmaadc[1];
1
2
3
4
5
6
/* USER CODE BEGIN 2 */

HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&dmaadc, 1);

/* USER CODE END 2 */
1
2
3
4
5
6
7
8
char str[6]; // 足够存储最大的uint16_t值(65535)加上字符串结束符'\0'
uint16_t v = dmaadc[0];
// 使用snprintf以避免缓冲区溢出
snprintf(str, sizeof(str), "%5d\n", v);

// OLED_DISPLAY_8x16_BUFFER(3, a); //显示字符串
// OLED_DISPLAY_CLEAR();
OLED_DISPLAY_8x16_BUFFER(4, str); //显示字符串

7. 有源蜂鸣器

通过三极管(S8550)控制蜂鸣器开关

设置

image-20240901165137723 image-20240901165207878

驱动程序

buzzer1.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// Created by Titan on 24-8-20.
//

#ifndef BUZZER1_H
#define BUZZER1_H

#include "stm32f1xx_hal.h" //HAL库文件声明
#include "main.h"

void BUZZER_SOLO(uint8_t time, uint32_t Delay);

#endif //BUZZER1_H

buzzer1.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// Created by Titan on 24-8-20.
//

#include "buzzer1.h"

void BUZZER_SOLO(uint8_t time, uint32_t Delay){//蜂鸣器输出单音的报警音(样式1:HAL库的精准延时函数)
uint16_t i;
for(i=0;i<time;i++){
HAL_GPIO_WritePin(BEEP2_GPIO_Port,BEEP2_Pin,GPIO_PIN_RESET); //蜂鸣器接口输出低电平1
HAL_Delay(Delay); //延时
HAL_GPIO_WritePin(BEEP2_GPIO_Port,BEEP2_Pin,GPIO_PIN_SET); //蜂鸣器接口输出高电平0
HAL_Delay(Delay); //延时
}
}

主程序

1
BUZZER_SOLO(5, 500);

8. 外部中断

设置

image-20240901170920783

端口触发模式,解释:

  • 外部中断模式,上升沿触发(电平由低变高);
  • 外部中断模式,下降沿触发(电平由高变低);
  • 外部中断模式,高/低电平触发(无方向,高低变化就触发);
  • 外部事件模式,上升沿触发;
  • 外部事件模式,下降沿触发;
  • 外部事件模式,高/低电平触发;

端口上/下拉:

image-20240901171343967
  • 无上/下拉
  • 上拉
  • 下拉

驱动程序

主程序

HAL_Delay()函数无法用于中断函数

HAL_Delay函数是基于系统滴答定时器中断来累增计数产生延时效果。这表明如果该函数被调用在外设的中断处理函数里,系统滴答定时器的中断就必须比这个外设中断的优先级高,否则这个外设中断将被阻塞。

(系统时钟设置里给滴答定时器的抢占优先级为15,所以在中断里调用HAL_Delay会卡死,所以我们需要去调高滴答定时器的抢占优先级,调低中断的抢占优先级)

img

解决方案:可以声明一个全局变量(标志位),在中断函数中修改全局变量的值,在主函数中判断值,如果值满足变化就执行某些操作。

100. xxx

设置

驱动程序

主程序