简介

hardware monitor:一个显示 PC 运行状态监测的站台,通过上位机将 PC 端的 CPU 温度、CPU 占用率、内存占用率、GPU 温度和实时网速等信息采集后下发到MCU,MCU通过 OLED 将其显示出来。

此项目在vscode中进行开发编译,使用rt-thread操作系统。

PCB:

1

经过简化打的PCB

2

驱动代码:

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
static uint8_t led_enable = 0;
static uint16_t pwm = 2001;
static uint8_t flag = 0;

static rt_uint8_t led_breath_thread_stack[154];
static struct rt_thread led_breath_thread;
void led_breath_entry(void *parameter);

void led_init()
{
rt_err_t ret = RT_ERROR;
config_t config = get_config();

led_control(config.led_enable);

ret = rt_thread_init(&led_breath_thread,
"led",
led_breath_entry,
RT_NULL,
&led_breath_thread_stack[0],
sizeof(led_breath_thread_stack),
5,
20);
if (ret == RT_EOK)
rt_thread_startup(&led_breath_thread);
}

led.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef __LED_H
#define __LED_H

#include "stm32f1xx_hal.h"

void led_init();

void led_control(uint8_t en);

#endif

spi.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
void SPI1_Init()
{
/* SPI1 Config -------------------------------------------------------------*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_1LINE;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
rt_kprintf("SPI1_Init_Fail\r\n");
while (1)
;
}
else
{
rt_kprintf("SPI1_Init_OK\r\n");
}
}

spi.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
#ifndef __SPI_H
#define __SPI_H

#include "stm32f1xx_hal.h"

SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;

void SPI1_Init(void);
void SPI2_Init(void);
uint8_t SPI2_ReadWriteByte(uint8_t TxData);

inline void SPI1_DMA_Enable(uint8_t *pData, uint16_t Size)
{
HAL_SPI_Transmit_DMA(&hspi1, pData, Size);
}

inline void SPI1_WriteByte(uint8_t TxData)
{
HAL_SPI_Transmit(&hspi1, &TxData, 1, 1000);
}


#endif

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
void oled_init(void)
{
config_t oled_config;
oled_config = get_config();

rt_sem_init(&sem_oled_dma_TxCplt, "dmatxcplt", 0, RT_IPC_FLAG_FIFO);
rt_mutex_init(&mutex_oled_lock, "oled_lock", RT_IPC_FLAG_FIFO);

rt_thread_init(&oled_send_thread, //OLED线程初始化
"oled_spi",
oled_send_entry,
RT_NULL,
&oled_send_thread_stack[0],
sizeof(oled_send_thread_stack),
2,
20);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); //复位
rt_thread_mdelay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET); //开启SSD1306片选

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET); //写入命令

SPI1_WriteByte(0xAE); //关闭屏幕
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET); //关闭SSD1306片选
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET); //开启SSD1306片选

SPI1_WriteByte(0x02); //设置列地址低位
SPI1_WriteByte(0x10); //设置列地址高位

SPI1_WriteByte(0x40); //设置显示起始线 40H-7FH --set start line address Set Mapping RAM Display Start Line (0x00~0x3F)

SPI1_WriteByte(0x81); //设置对比度
SPI1_WriteByte(oled_config.oled_light); // 00H-FFH

if (oled_config.oled_direction)
{
SPI1_WriteByte(0xA0); //设置段重映射--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
SPI1_WriteByte(0xC0); //--Set Common Output Scan Direction 0xc0上下反置 0xc8正常
}
else
{
SPI1_WriteByte(0xA1); //设置段重映射--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
SPI1_WriteByte(0xC8); //--Set Common Output Scan Direction 0xc0上下反置 0xc8正常
}

SPI1_WriteByte(0xA8); //--set multiplex ratio(1 to 64)
SPI1_WriteByte(0x3F); //--1/64 duty 00H-3FH

SPI1_WriteByte(0xD3); //设置显示偏移--set display offset Shift Mapping RAM Counter (0x00~0x3F)
SPI1_WriteByte(0x00); //--not offset

SPI1_WriteByte(0xD5); //--set display clock divide ratio/oscillator frequency
SPI1_WriteByte(0x80); //--set divide ratio, Set Clock as 100 Frames/Sec 00H-FFH

SPI1_WriteByte(0xD9); //--set pre-charge period
SPI1_WriteByte(0x22); //--Set Pre-Charge as 15 Clocks & Discharge as 1 Clock F1

SPI1_WriteByte(0xDA); //--set com pins hardware configuration
SPI1_WriteByte(0x12); //02H-12H

SPI1_WriteByte(0xDB); //--set vcomh 00H-FFH
SPI1_WriteByte(0x35); //--Set VCOM Deselect Level

SPI1_WriteByte(0xAD); //Set DC-DC OFF/ON
SPI1_WriteByte(0x8B); //8AH-8BH

SPI1_WriteByte(0x32); //设置电荷泵电压

SPI1_WriteByte(0xA4); //--Disable Entire Display On (0xa4/0xa5)
SPI1_WriteByte(0xA6); //--Disable Inverse Display On (0xa6/a7)

// SPI1_WriteByte(0xAF); //开启屏幕

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET); //关闭SSD1306片选

rt_thread_startup(&oled_send_thread); // 开启oled进程
}
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
void oled_show_init()
{
rt_err_t ret = RT_ERROR;

config_t config = get_config();
idle_mode_show_logo_flag = config.logo_show;

gui_init();

// logo
gui_bitmap_init(&logo_bitmap, &logo_bitmap_att);
gui_bitmap_set_localtion(&logo_bitmap, 0, 0);
gui_bitmap_set_size(&logo_bitmap, 0, 64);
gui_bitmap_set_bitmap(&logo_bitmap, (uint8_t *)LOGO_BMP_ADDRESS, 128, 64);
gui_screen_layer_add_obj(&logo_bitmap, 0);

gui_cube_init(&cube_anim, &cube_anim_att);
gui_cube_set_localtion(&cube_anim, 0, 0);
gui_cube_set_size(&cube_anim, 0, 64);
gui_screen_layer_add_obj(&cube_anim, 0);

gui_anim_init(&idle_mode_anim);
gui_anim_add(&idle_mode_anim);
gui_anim_set_start(&idle_mode_anim, 0);
gui_anim_set_end(&idle_mode_anim, 64);
gui_anim_set_time(&idle_mode_anim, 500);
gui_anim_set_path_cb(&idle_mode_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&idle_mode_anim, &logo_bitmap, gui_anim_set_obj_x1_x2_cb);
gui_anim_start(&idle_mode_anim, 0);

idle_mode_show_logo(idle_mode_show_logo_flag);

// cpu
gui_label_init(&cpu_label, &cpu_label_att);
gui_label_set_localtion(&cpu_label, 0, -13);
gui_label_set_size(&cpu_label, 128, 12);
gui_label_set_font(&cpu_label, &font1608);
gui_label_set_text_offset(&cpu_label, 1, 0);
gui_label_set_text_by_string(&cpu_label, "CPU -.-% --\x83\x84");
gui_screen_layer_add_obj(&cpu_label, 1);

gui_anim_init(&cpu_label_anim);
gui_anim_add(&cpu_label_anim);
gui_anim_set_start(&cpu_label_anim, -13);
gui_anim_set_end(&cpu_label_anim, 0);
gui_anim_set_time(&cpu_label_anim, 500);
gui_anim_set_path_cb(&cpu_label_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&cpu_label_anim, &cpu_label, gui_label_set_y);

// cpu chart
gui_osc_init(&cpu_osc, &cpu_osc_att);
gui_osc_set_localtion(&cpu_osc, -65, 14);
gui_osc_set_size(&cpu_osc, 65, 37);
gui_osc_add_points(&cpu_osc, cpu_osc_points, 33);
gui_osc_points_init(&cpu_osc);
gui_osc_set_div(&cpu_osc, 2);
gui_screen_layer_add_obj(&cpu_osc, 1);

gui_anim_init(&cpu_osc_anim);
gui_anim_add(&cpu_osc_anim);
gui_anim_set_start(&cpu_osc_anim, -65);
gui_anim_set_end(&cpu_osc_anim, 0);
gui_anim_set_time(&cpu_osc_anim, 500);
gui_anim_set_path_cb(&cpu_osc_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&cpu_osc_anim, &cpu_osc, gui_obj_set_x);

// mem
gui_label_init(&mem_label, &mem_label_att);
gui_label_set_localtion(&mem_label, 65, 18);
gui_label_set_size(&mem_label, 63, 16);
gui_label_set_font(&mem_label, &font1608);
gui_label_set_text_offset(&mem_label, 19, 0);
gui_label_set_text_by_string(&mem_label, "MEM");

gui_label_init(&mem_act_label, &mem_act_label_att);
gui_label_set_localtion(&mem_act_label, 65, 37);
gui_label_set_size(&mem_act_label, 28, 12);
gui_label_set_font(&mem_act_label, &font1206);
gui_label_set_text_offset(&mem_act_label, 2, 0);
gui_label_set_text_by_string(&mem_act_label, " --%");

gui_label_init(&mem_used_label, &mem_used_label_att);
gui_label_set_localtion(&mem_used_label, 94, 37);
gui_label_set_size(&mem_used_label, 32, 12);
gui_label_set_font(&mem_used_label, &font1206);
gui_label_set_text_offset(&mem_used_label, 0, 0);
gui_label_set_text_by_string(&mem_used_label, " -.-G");

// gpu
gui_label_init(&gpu_label, &gpu_label_att);
gui_label_set_localtion(&gpu_label, 65 + 63, 18);
gui_label_set_size(&gpu_label, 63, 16);
gui_label_set_font(&gpu_label, &font1608);
gui_label_set_text_offset(&gpu_label, 19, 0);
gui_label_set_text_by_string(&gpu_label, "GPU");

gui_label_init(&gpu_act_label, &gpu_act_label_att);
gui_label_set_localtion(&gpu_act_label, 65 + 63, 37);
gui_label_set_size(&gpu_act_label, 28, 12);
gui_label_set_font(&gpu_act_label, &font1206);
gui_label_set_text_offset(&gpu_act_label, 2, 0);
gui_label_set_text_by_string(&gpu_act_label, " --%");

gui_label_init(&gpu_temp_label, &gpu_temp_label_att);
gui_label_set_localtion(&gpu_temp_label, 94 + 63, 37);
gui_label_set_size(&gpu_temp_label, 32, 12);
gui_label_set_font(&gpu_temp_label, &font1206);
gui_label_set_text_offset(&gpu_temp_label, 4, 0);
gui_label_set_text_by_string(&gpu_temp_label, " --\x83\x84");

gui_container_init(&mem_gpu_cont, &mem_gpu_cont_att);
gui_container_set_localtion(&mem_gpu_cont, 64, 14);
gui_container_set_size(&mem_gpu_cont, 64, 37);
gui_container_set_edge_style(&mem_gpu_cont, 1);
gui_container_add_obj(&mem_gpu_cont, &mem_label);
gui_container_add_obj(&mem_gpu_cont, &mem_act_label);
gui_container_add_obj(&mem_gpu_cont, &mem_used_label);
gui_container_add_obj(&mem_gpu_cont, &gpu_label);
gui_container_add_obj(&mem_gpu_cont, &gpu_act_label);
gui_container_add_obj(&mem_gpu_cont, &gpu_temp_label);
gui_container_set_localtion(&mem_gpu_cont, 128, 14); // 隐藏
gui_screen_layer_add_obj(&mem_gpu_cont, 1);

gui_anim_init(&mem_gpu_cont_anim);
gui_anim_add(&mem_gpu_cont_anim);
gui_anim_set_start(&mem_gpu_cont_anim, 128);
gui_anim_set_end(&mem_gpu_cont_anim, 64);
gui_anim_set_time(&mem_gpu_cont_anim, 500);
gui_anim_set_path_cb(&mem_gpu_cont_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&mem_gpu_cont_anim, &mem_gpu_cont, gui_container_set_x);

gui_anim_init(&mem_gpu_cont_switch_anim);
gui_anim_add(&mem_gpu_cont_switch_anim);
gui_anim_set_start(&mem_gpu_cont_switch_anim, 0);
gui_anim_set_end(&mem_gpu_cont_switch_anim, -63);
gui_anim_set_time(&mem_gpu_cont_switch_anim, 400);
gui_anim_set_control_obj(&mem_gpu_cont_switch_anim, &mem_gpu_cont, gui_anim_set_mem_gpu_label_offset);
gui_anim_set_path_cb(&mem_gpu_cont_switch_anim, gui_anim_path_ease_in_out);
gui_anim_set_paly_back_mode(&mem_gpu_cont_switch_anim, 3000, 1);
gui_anim_set_loop_mode(&mem_gpu_cont_switch_anim, 1);
gui_anim_start(&mem_gpu_cont_switch_anim, 3000);

// nic
gui_label_init(&nic_label, &nic_label_att);
gui_label_set_localtion(&nic_label, 0, 51);
gui_label_set_size(&nic_label, 12, 12);
gui_label_set_font(&nic_label, &font1206);
gui_label_set_text_offset(&nic_label, 0, 1);
gui_label_set_text_by_string(&nic_label, "\x85\x86");

gui_label_init(&nic_download_label, &nic_download_att);
gui_label_set_localtion(&nic_download_label, 15, 51);
gui_label_set_size(&nic_download_label, 55, 16);
gui_label_set_font(&nic_download_label, &font1206);
gui_label_set_text_offset(&nic_download_label, 0, 3);
gui_label_set_text_by_string(&nic_download_label, " -.-K/s");

gui_label_init(&nic_upload_label, &nic_upload_att);
gui_label_set_localtion(&nic_upload_label, 72, 51);
gui_label_set_size(&nic_upload_label, 64, 16);
gui_label_set_font(&nic_upload_label, &font1206);
gui_label_set_text_offset(&nic_upload_label, 0, 3);
gui_label_set_text_by_string(&nic_upload_label, " -.-K/s");

gui_container_init(&nic_cont, &nic_cont_att);
gui_container_set_localtion(&nic_cont, 0, 51);
gui_container_set_size(&nic_cont, 128, 12);
gui_container_add_obj(&nic_cont, &nic_label);
gui_container_add_obj(&nic_cont, &nic_download_label);
gui_container_add_obj(&nic_cont, &nic_upload_label);
gui_container_set_localtion(&nic_cont, 0, 64); // 隐藏
gui_screen_layer_add_obj(&nic_cont, 1);

gui_anim_init(&nic_cont_anim);
gui_anim_add(&nic_cont_anim);
gui_anim_set_start(&nic_cont_anim, 75);
gui_anim_set_end(&nic_cont_anim, 51);
gui_anim_set_time(&nic_cont_anim, 500);
gui_anim_set_path_cb(&nic_cont_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&nic_cont_anim, &nic_cont, gui_container_set_y);

// 频谱
gui_spectrum_init(&spectrum, &spectrum_att);
gui_spectrum_set_localtion(&spectrum, 0, 0);
gui_spectrum_set_size(&spectrum, 0, 64);
gui_screen_layer_add_obj(&spectrum, 2);

gui_anim_init(&spectrum_anim);
gui_anim_add(&spectrum_anim);
gui_anim_set_start(&spectrum_anim, 128);
gui_anim_set_end(&spectrum_anim, 0);
gui_anim_set_time(&spectrum_anim, 500);
gui_anim_set_path_cb(&spectrum_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&spectrum_anim, &spectrum, gui_anim_set_obj_x1_x2_cb);

// gif显示模式
gui_bitmap_init(&gif_frame1_bitmap, &gif_frame1_bitmap_att);
gui_bitmap_set_localtion(&gif_frame1_bitmap, 0, 0);
gui_bitmap_set_size(&gif_frame1_bitmap, 0, 64);
gui_bitmap_set_bitmap(&gif_frame1_bitmap, gif_frame1_buffer, 128, 64);
gui_screen_layer_add_obj(&gif_frame1_bitmap, 3);

gui_bitmap_init(&gif_frame2_bitmap, &gif_frame2_bitmap_att);
gui_bitmap_set_localtion(&gif_frame2_bitmap, 0, 0);
gui_bitmap_set_size(&gif_frame2_bitmap, 0, 64);
gui_bitmap_set_bitmap(&gif_frame2_bitmap, gif_frame2_buffer, 128, 64);
gui_obj_set_hide(&gif_frame2_bitmap, 1);
gui_screen_layer_add_obj(&gif_frame2_bitmap, 3);

gui_anim_init(&gif_page_anim);
gui_anim_add(&gif_page_anim);
gui_anim_set_start(&gif_page_anim, 64);
gui_anim_set_time(&gif_page_anim, 500);
gui_anim_set_path_cb(&gif_page_anim, gui_anim_path_ease_in_out);
gui_anim_set_control_obj(&gif_page_anim, NULL, gui_anim_set_gif_page_x1_x2_cb);

ret = rt_thread_init(&oled_draw_thread,
"oled_draw",
oled_draw_entry,
RT_NULL,
&oled_draw_thread_stack[0],
sizeof(oled_draw_thread_stack),
4,
20);
if (ret == RT_EOK)
rt_thread_startup(&oled_draw_thread);
}

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
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
#ifndef __OLED_H
#define __OLED_H

#include "stm32f1xx_hal.h"
#include "spi.h"

#define FONT1206 0
#define FONT1608 1

#define BLACK 0 ///< Draw 'off' pixels
#define WHITE 1 ///< Draw 'on' pixels
#define INVERSE 2 ///< Invert pixels

#define SSD1306_MEMORYMODE 0x20 ///< See datasheet
#define SSD1306_COLUMNADDR 0x21 ///< See datasheet
#define SSD1306_PAGEADDR 0x22 ///< See datasheet
#define SSD1306_SETCONTRAST 0x81 ///< See datasheet
#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet
#define SSD1306_SEGREMAP 0xA0 ///< See datasheet
#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet
#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used
#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet
#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet
#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet
#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet
#define SSD1306_DISPLAYON 0xAF ///< See datasheet
#define SSD1306_COMSCANINC 0xC0 ///< Not currently used
#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet
#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet
#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet
#define SSD1306_SETCOMPINS 0xDA ///< See datasheet
#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet

#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used
#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used
#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet

#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V

#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 ///< Init rt scroll
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 ///< Init left scroll
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 ///< Init diag scroll
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A ///< Init diag scroll
#define SSD1306_DEACTIVATE_SCROLL 0x2E ///< Stop scroll
#define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range

#define OLED_CHANGE_LIGHT 0x00
#define OLED_CHANGE_DIRECTION 0x01
#define OLED_SET_POWERON 0x02
#define OLED_SET_POWEROFF 0x03

void oled_init(void);
void oled_set_light(uint8_t value);
void oled_set_power(uint8_t en);
void oled_set_direction(uint8_t direction);

void DMA1_channel7_Init(void);

#endif

ringbuffer.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void rt_ringbuffer_init(struct rt_ringbuffer *rb,
rt_uint8_t *pool,
rt_int16_t size)
{
RT_ASSERT(rb != RT_NULL);
RT_ASSERT(size > 0);

/* initialize read and write index */
rb->read_mirror = rb->read_index = 0;
rb->write_mirror = rb->write_index = 0;

/* set buffer pool and size */
rb->buffer_ptr = pool;
rb->buffer_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
}

ringbuffer.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
#ifndef __RINGBUFFER_H
#define __RINGBUFFER_H

#include "stm32f1xx_hal.h"
#include <rtthread.h>

#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb))

struct rt_ringbuffer
{
rt_uint8_t *buffer_ptr;

rt_uint16_t read_mirror : 1;
rt_uint16_t read_index : 15;
rt_uint16_t write_mirror : 1;
rt_uint16_t write_index : 15;

rt_int16_t buffer_size;
};

enum rt_ringbuffer_state
{
RT_RINGBUFFER_EMPTY,
RT_RINGBUFFER_FULL,
/* half full is neither full nor empty */
RT_RINGBUFFER_HALFFULL,
};

/**
* RingBuffer for DeviceDriver
*
* Please note that the ring buffer implementation of RT-Thread
* has no thread wait or resume feature.
*/
void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int16_t size);
void rt_ringbuffer_reset(struct rt_ringbuffer *rb);
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length);
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint16_t length);
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length);
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);

#ifdef RT_USING_HEAP
struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t length);
void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
#endif

rt_inline rt_uint16_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb)
{
RT_ASSERT(rb != RT_NULL);
return rb->buffer_size;
}

/** return the size of empty space in rb */
#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb))




#define N 1024
typedef struct
{
uint8_t buffer[N]; //buffer
volatile uint16_t w_ptr; //
volatile uint16_t r_ptr; //
volatile uint16_t cap; //
} fifo_buffer;

uint8_t ring_readbyte(fifo_buffer *p);

void ring_writebyte(fifo_buffer *p, uint8_t data);

void ring_readdata(fifo_buffer *p, uint8_t *data, uint16_t len);

void ring_writedata(fifo_buffer *p, uint8_t *data, uint16_t len);

#endif

usart.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
uint8_t usart1_rx_temp = 0;
uint8_t usart1_rx_buffer[16] = {0};
struct rt_ringbuffer usart1_rx_rb;
struct rt_semaphore sem_usart1_rx;
struct rt_semaphore sem_usart1_tx_cplt;

UART_HandleTypeDef huart1;
void USART1_Init(uint32_t bound)
{
rt_ringbuffer_init(&usart1_rx_rb, usart1_rx_buffer, 16);
rt_sem_init(&sem_usart1_rx, "sem_usart1_rx", 0, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_usart1_tx_cplt, "sem_usart1_tx_cplt", 0, RT_IPC_FLAG_FIFO);

huart1.Instance = USART1;
huart1.Init.BaudRate = bound;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;

if (HAL_UART_Init(&huart1) != HAL_OK)
{
while (1)
;
}

__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);

// HAL_UART_Receive_IT(&huart1, &usart1_rx_temp, 1);
}

void USART1_IRQHandler()
{
int ch = -1;

/* enter interrupt */
rt_interrupt_enter(); //在中断中一定要调用这对函数,进入中断

if ((__HAL_UART_GET_FLAG(&(huart1), UART_FLAG_RXNE) != RESET) &&
(__HAL_UART_GET_IT_SOURCE(&(huart1), UART_IT_RXNE) != RESET))
{
while (1)
{
ch = -1;
if (__HAL_UART_GET_FLAG(&(huart1), UART_FLAG_RXNE) != RESET)
{
ch = huart1.Instance->DR & 0xff;
}
if (ch == -1)
{
break;
}
/* 读取到数据,将数据存入 ringbuffer */
rt_ringbuffer_putchar(&usart1_rx_rb, ch);
}
rt_sem_release(&sem_usart1_rx);
}

/* leave interrupt */
rt_interrupt_leave(); //在中断中一定要调用这对函数,离开中断
}

usart.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef __USART_H
#define __USART_H
#include "stm32f1xx_hal.h"

void USART1_Init(uint32_t bound);
void USART1_DMA_Enable(uint8_t *buffer, uint16_t sendlen);

void USART3_Init(uint32_t bound);

#endif

gui 库

核心代码

core.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void gui_init()
{
screen.area.x1 = 0;
screen.area.x2 = 127;
screen.area.y1 = 0;
screen.area.y2 = 63;

screen.active_layer_index = 0;
screen.sys_layer = NULL;

rt_thread_init(&gui_thread, //gui线程初始化
"gui",
gui_entry,
RT_NULL,
&gui_thread_stack[0],
sizeof(gui_thread_stack),
1,
20);
rt_thread_startup(&gui_thread);
}

core.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
#ifndef __GUI_CORE_H
#define __GUI_CORE_H
#include "stm32f1xx_hal.h"
#include "rtthread.h"
#include "area.h"
#include "font.h"

#define SHOW_FPS 0
#define LAYER_NUM_MAX 5 // 界面数量

struct _gui_obj_t;

typedef void (*gui_obj_draw_cb_t)(struct _gui_obj_t *obj, gui_area_t *area); // 控件绘制回调

typedef struct _gui_obj_t
{
struct _gui_obj_t *per;
struct _gui_obj_t *next;

uint8_t hide;
gui_area_t area;

gui_obj_draw_cb_t draw_cb;

void *attribute;
} gui_obj_t;

typedef struct _gui_screen_t
{
gui_area_t area;

gui_obj_t *layers[LAYER_NUM_MAX];
uint8_t active_layer_index;

gui_obj_t *sys_layer;
} gui_screen_t;

void gui_init();

void gui_screen_layer_add_obj(gui_obj_t *obj, uint8_t active_layer_index);
void gui_screen_sys_layer_add_obj(gui_obj_t *obj);
void gui_screen_set_active_layer(uint8_t layer_index);

void gui_set_oled_protect_mode(uint8_t en);

uint8_t *gui_get_vdb();

void gui_obj_set_localtion(gui_obj_t *obj, int16_t x, int16_t y);
void gui_obj_set_size(gui_obj_t *obj, int16_t width, int16_t height);
void gui_obj_set_x(gui_obj_t *obj, int16_t x);
void gui_obj_set_y(gui_obj_t *obj, int16_t y);

inline void gui_obj_set_hide(gui_obj_t *obj, uint8_t en)
{
obj->hide = en;
}

void gui_clear_all_pixel(void);
void gui_fill_all_pixel(void);
void gui_draw_pixel(int16_t x, int16_t y, uint8_t color);
void gui_draw_pixel_in_area(gui_area_t *area, int16_t x, int16_t y, uint8_t color);
void gui_draw_char(gui_area_t *area, int16_t x, int16_t y, gui_font_t *font, char c);
void gui_draw_string(gui_area_t *area, int16_t x, int16_t y, gui_font_t *font, char *str, uint16_t size);
void gui_draw_bitmap(gui_area_t *area, int16_t x, int16_t y, uint8_t *bitmap, uint16_t width, uint16_t height);

void gui_draw_line(gui_area_t *area, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t color);

#endif

一些图形函数

1
2
3
4
5
6
7
8
9
10
#include "label.h"
#include "line.h"
#include "container.h"
#include "oscillograph.h"
#include "spectrum.h"
#include "bitmap.h"
#include "cube.h"
#include "anim.h"
// logo //cpu //gpu //mem ......

rt-thread

下载源码,按教程移植相应文件到工程项目中即可。

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void)
{
eeprom_init();

oled_init();
DMA1_channel7_Init();

MX_GPIO_Init();
rt_thread_mdelay(500);
MX_USB_DEVICE_Init();

led_init();

data_decode_init();

oled_show_init();

return 0;
}

hardware monitor

3

编译

4

5