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
void SendATCmd(char *cmd, int waitms) {// 发送AT指令
if (NULL != cmd) {
HAL_UART_Transmit_DMA(&huart6, (uint8_t *)cmd,
strlen(cmd));
osDelay(waitms); // 延时等待ESP01模块应答时间
}
}
void SendESP01Str(char *str) { // 发送字符串
if (NULL != str)
HAL_UART_Transmit_DMA(&huart6, (uint8_t *)str,
strlen(str));
}
osDelay(500);
printf("测试ESP01模块是否存在...\n"); SendATCmd("AT\r\n", 500);
printf("关闭模块回显\n"); SendATCmd("ATE0\r\n", 500);
printf("查看模块版本信息...\n"); SendATCmd("AT+GMR\r\n", 1000);
printf("开启AP模式\n"); SendATCmd("AT+CWMODE=2\r\n", 500);
printf("配置热点名称ESP01,无密码...\n"); SendATCmd("AT+CWSAP=\"ESP01\",\"\",11,0\r\n", 500);
printf("关闭透传模式\n"); SendATCmd("AT+CIPMODE=0\r\n", 500);
printf("设置多连接\n"); SendATCmd("AT+CIPMUX=1\r\n", 500);
printf("开启TCP服务器,端口666...\n"); SendATCmd("AT+CIPSERVER=1,666\r\n", 500);
for(;;) {
if (cid >= 0) { // 如果有客户端连接进来,每隔1秒向客户端发送一条数据
char cmd[30];
char str[] = "HELLO ESP01\r\n";
sprintf(cmd, "AT+CIPSEND=%d,%d\r\n", cid, strlen(str));
SendATCmd(cmd, 500);
SendESP01Str(str);
}
osDelay(1000);
}

for(;;) {
// 串口1接收数据处理
if (osMessageQueueGet(QueueUart1Handle, dat, NULL, 10) == osOK) {
printf("UART1: %s", dat); // 串口1打印回显
HAL_UART_Transmit_DMA(&huart6, dat, strlen((char *)dat)); // 转发串口6
}
// 串口6接收数据处理
if (osMessageQueueGet(QueueUart6Handle, dat, NULL, 10) == osOK) {
printf("UART6: %s", dat); // 串口1打印显示
char *str = (char *)dat;
if (strstr(str, "CONNECT") > str) cid = atoi(str); // 如果有客户端连接进来,取ID号
if (strstr(str, "CLOSED") > str) cid = -1; // 如果有客户端连接断开,关闭ID号
}
osDelay(1);
}

if (huart == &huart1) { // 串口1接收空闲
rx1_buf[Size] = '\0'; // 末尾加字符串结束符
osMessageQueuePut(QueueUart1Handle, rx1_buf, NULL, 0); // 发送消息到队列1
__HAL_UNLOCK(huart); // 重启串口1的DMA接收
HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx1_buf, sizeof(rx1_buf));
}
if (huart == &huart6) { // 串口6接收空闲
rx6_buf[Size] = '\0'; // 末尾加字符串结束符
osMessageQueuePut(QueueUart6Handle, rx6_buf, NULL, 0); // 发送消息到队列6
// 重启串口6的DMA接收
__HAL_UNLOCK(huart);
HAL_UARTEx_ReceiveToIdle_IT(&huart6, rx6_buf, sizeof(rx6_buf));
}
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
char buf[10] = "     ";//四个空格
uint16_t r1, r2;
uint8_t keyCount = 0; // 按键计数器
uint8_t lastKeyState = GPIO_PIN_RESET; // 上一次按键状态
uint32_t currentKeyState; // 当前按键状态
while (1){
currentKeyState = ReadKey(); // 读取按键状态
if (currentKeyState != lastKeyState) {
if (currentKeyState>0)
{
keyCount=0;
keyCount++;
}
else
{
if (keyCount > 0)
{
keyCount--; // 按键计数器减1
}
}
}
lastKeyState = currentKeyState; // 更新上一次按键状态
if (keyCount > 0) sprintf(buf, "%04d", currentKeyState);
else sprintf(buf, " "); // 清空显示
DispSeg(buf);
}
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
// 单个数码管显示
void Write595(uint8_t sel, uint8_t num, uint8_t bdot){
// 共阴数码管,'0'~'9','A'~'F' 编码
static const uint8_t TAB[16] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
// 74HC138关数码管显示
HAL_GPIO_WritePin(A3_GPIO_Port, A3_Pin, GPIO_PIN_RESET);
uint8_t dat = TAB[num & 0x0F] | (bdot ? 0x80 : 0x00);
if (' ' == num) dat = 0; // 空格关闭显示
else if ('.' == num) dat = 0x80;// 单独小数点显示
else if ('-' == num) dat = 0x40;// 负号显示
else if (num > 0x0F) dat = num;// 其余数值按实际段码显示
// 595串行移位输入段码
for (uint8_t i = 0; i < 8; ++i) {
HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SER_GPIO_Port, SER_Pin, (dat & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
dat <<= 1;
HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, GPIO_PIN_SET);
}
// DISLK脉冲锁存8位输出
HAL_GPIO_WritePin(DISLK_GPIO_Port, DISLK_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DISLK_GPIO_Port, DISLK_Pin, GPIO_PIN_SET);
// 4位数码管片选
HAL_GPIO_WritePin(A0_GPIO_Port, A0_Pin, (sel & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(A1_GPIO_Port, A1_Pin, (sel & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(A2_GPIO_Port, A2_Pin, GPIO_PIN_RESET);
// 74HC138开数码管显示
HAL_GPIO_WritePin(A3_GPIO_Port, A3_Pin, GPIO_PIN_SET);
}
// 4位数码管动态扫描显示
void DispSeg(char dat[8]) {
uint8_t sel = 0; // 数码管位选
uint8_t bdot = 0; // 是否有小数点
for(uint8_t i = 0; i < 8; ++i) {
uint8_t num = dat[i];
if (dat[i] != '.') {
if (dat[i + 1] == '.')
bdot = 1; // 下一位小数点合并到当前位显示
}
else { // 小数点处理
if (bdot) {
bdot = 0;
continue; // 跳过已经合并显示的小数点
}
}
// 十六进制字符显示支持
if (num >= '0' && num <= '9') num -= '0';
else if (num >= 'A' && num <= 'F')
num = num - 'A' + 10;
else if (num >= 'a' && num <= 'f')
num = num - 'a' + 10;
// 点亮对应数码管
Write595(sel++, num, bdot);
osDelay(3); // 延时3毫秒
if (sel >= 4) // 只显示4位数码管
break;
}

}

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
void UILogo(void) {
static uint32_t tick = 0; // 定义静态变量, 存储进入界面时的时间戳
if (0 == tick) tick = osKernelGetTickCount(); // 开始进入界面时, 记录时间戳
GUI_Clear(); // 屏幕内容清空
GUI_DrawBitmap(&bmLOGO,
(128 - bmLOGO.XSize) / 2, (64 - bmLOGO.YSize) / 2); // 居中显示校徽图片
GUI_Update(); // 刷新屏幕显示
if (osKernelGetTickCount() >= tick + 2000) { // 如果当前时间已经超过进入时间2秒
g_sta = GUI_MAIN; // 界面状态跳转到主菜单界面
tick = 0; // 时间戳清零, 以备再次进入
}
}
void UIMain(void) {
GUI_Clear(); // 屏幕内容清空
GUI_SetFont(&GUI_FontHZ_SimSun_16); // 设置文本字体为16号宋体
GUI_DispStringHCenterAt("主菜单", 64, 0); // 屏幕正上方居中显示标题
if (GUI_LED == g_sta_select) { // 如果待选界面为LED状态
GUI_DispStringHCenterAt("* LED状态", 64, 20);
GUI_DispStringHCenterAt("按键状态", 64, 40);
} else { // 如果待选界面为按键状态
GUI_DispStringHCenterAt("LED状态", 64, 20);
GUI_DispStringHCenterAt("* 按键状态", 64, 40);
}
GUI_Update(); // 刷新屏幕显示
}
void UILeds(void) {
GPIO_TypeDef* LED_Ports[8] = { // 定义LED灯端口数组, 如果8个灯都是一个Port, 可以不用
L1_GPIO_Port, L2_GPIO_Port, L3_GPIO_Port, L4_GPIO_Port,
L5_GPIO_Port, L6_GPIO_Port, L7_GPIO_Port, L8_GPIO_Port};
uint16_t LED_Pin[8] = {L1_Pin, L2_Pin, L3_Pin, L4_Pin, L5_Pin, L6_Pin, L7_Pin, L8_Pin}; // 引脚数组
GUI_Clear(); // 屏幕内容清空
GUI_SetFont(&GUI_FontHZ_SimSun_16); // 设置文本字体为16号宋体
GUI_DispStringHCenterAt("LED状态", 64, 0); // 屏幕正上方居中显示标题
int tx, ty; // 定义绘图临时变量
tx = ty = 12;
for (int i = 0; i < 8; ++i) { // 循环遍历8个LED灯
GUI_DrawRect(16 * i + 1, 20, 16 * i + tx, 20 + ty); // 绘制边框
if (HAL_GPIO_ReadPin(LED_Ports[i], LED_Pin[i]) == GPIO_PIN_RESET) // 读取端口电平
GUI_FillRect(16 * i + 1, 20, 16 * i + tx, 20 + ty); // 如果亮灯则填充矩形
}
GUI_Update(); // 刷新屏幕显示
}
void UIKeys(void) {
GUI_Clear(); // 屏幕内容清空
GUI_SetFont(&GUI_FontHZ_SimSun_16); // 设置文本字体为16号宋体
GUI_DispStringHCenterAt("按键状态", 64, 0);// 屏幕正上方居中显示标题
GPIO_PinState ps = HAL_GPIO_ReadPin(K1_GPIO_Port, K1_Pin);// 定义变量, 读取K1按键电平
GUI_DispStringAt(GPIO_PIN_RESET == ps ? "●" : "○", 26, 20); // 绘制不同符号表示按键按压状态
ps = HAL_GPIO_ReadPin(K4_GPIO_Port, K4_Pin); // K4按键
GUI_DispStringAt(GPIO_PIN_RESET == ps ? "●" : "○", 26, 48);
ps = HAL_GPIO_ReadPin(K2_GPIO_Port, K2_Pin); // K2按键
GUI_DispStringAt(GPIO_PIN_RESET == ps ? "●" : "○", 6, 34);
ps = HAL_GPIO_ReadPin(K3_GPIO_Port, K3_Pin); // K3按键
GUI_DispStringAt(GPIO_PIN_RESET == ps ? "●" : "○", 46, 34);
ps = HAL_GPIO_ReadPin(K5_GPIO_Port, K5_Pin); // K5按键
GUI_DispStringAt(GPIO_PIN_SET == ps ? "●" : "○", 86, 34); // 注意电平方式和前4个按键不同
ps = HAL_GPIO_ReadPin(K6_GPIO_Port, K6_Pin); // K6按键
GUI_DispStringAt(GPIO_PIN_SET == ps ? "●" : "○", 106, 34);
GUI_Update(); // 刷新屏幕显示
}