外观
八、综合案例
1 前言
桌面温湿度仪的综合案例其实就是将之前的各模块汇总起来,作为一个工程;默认采用两节7号电池进行供电,考虑到功耗问题,默认不开机,进入睡眠模式;
当有按键按下时,触发中断,此时结束睡眠模式,执行按键判断,获取温湿度并启动数码管进行显示;同时启动定时器中断,循环显示两次数据后再次进入睡眠,等待下次唤醒。
- 若想检测电池电压,可增加ADC相关代码;
- 若想进行定时读取,可以增加RTC实时时钟代码;
本项目代码均采用STM32CubeMX进行生成,默认会根据外设生成对应的文件,这里我建议大家不要修改整个工程结构(因为代码不多),直接在对应的外设文件中进行相关驱动代码编写即可。
最后,若没有学习过之前的案例工程,我建议去过一遍,特别是中断,STM32G0系列使用Arm Cortex M0+内核,是两级流水线的冯诺依曼结构,具有4位中断优先级。这些与STM32F103是不一致的。
2 代码编写
2.1 创建工程
2.2 设置参数
将SN74HC595引脚设置为推挽输出、快速模式,同时依据原理图对其进行重命名,方便后续代码编写; - 将按键引脚设置为上拉输入模式并对其进行重命名; - 将测试LED灯设置为推挽输出模式并对其进行重命名;注意打开ADC、定时器、IIC功能,否则无法正常使用这些外设;
配置时钟树,这里主晶振没有使用外部而是内部晶振,外部低速晶振暂时没有使用,先不需要配置;
最后填写输出工程的名称,选择工程输出路径以及适配的IDE;
生成相关文件的.c与.h文件;
选择HAL库;
创建工程,随后打开,这个Cubemx软件就可以关闭了;
2.3 编译配置工程
正常应该是0错误0警告;
点击魔术棒,选择debug,选择合适的下载器,并配置下载器选项;
2.4 编写测试代码
绝大部分代码在之前的案例中都介绍过,自行移植即可,重点介绍一下如何进入休眠模式以及定时器中断。
STM32G0系列有四种休眠模式;
- 低功耗运行模式(降低CPU频率,系统仍在运行)
- 睡眠模式(系统进入睡眠,任意中断/事件唤醒)
- 停止模式(系统进入停止,支持任意外部中断和RTC闹钟唤醒)
- 待机模式(系统进入待机,支持RTC闹钟唤醒,WKUP、NRST引脚唤醒以及IWDG复位唤醒,打开了LSI和LSE)
注
注意以上模式均不可进行Debuge调试,系统时钟已经关闭;且设置为低功耗模式后,无法下载代码,需要唤醒后才能进行下载;详细说明可以查看具体数据手册。
大家根据实际情况进行设置,综合代码设置为睡眠模式。
在Cubemx中设置了定时器14中断,代码中默认是不开启的,启动后自动开始计时。计时时间到来后进入溢出中断。
定时器溢出中断回调函数,由于计时时间较短,在回调函数中加入累加变量,表示数据显示时间,假设一1s为周期,前半秒显示温度数据,后半s显示湿度数据,显示完两次后进入休眠。
数码管优化,在前面的案例中,会看到数码管亮度不尽人意,这是因为此时主频太快导致显示过短;在原来的代码中,显示数据后立刻进行消影操作。此时CPU主频为64Mhz,执行速度较快,导致数据显示过暗。
在原有的基础上,加入一个us延时,数据显示出来后,延时一点点时间再消影,这样显示效果就好很多了。
C
//进入睡眠模式
HAL_SuspendTick(); //暂停滴答定时器,防止通过滴答定时器中断唤醒
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); /* 执行WFI指令, 进入睡眠模式 */
//退出睡眠模式,任意中断/事件退出
HAL_ResumeTick(); //恢复滴答定时器
1
2
3
4
5
6
2
3
4
5
6
C
HAL_TIM_Base_Start_IT(&htim14); //开始定时器
HAL_TIM_Base_Stop_IT(&htim14); //停止定时器
/*
函数内容:定时器溢出中断回调函数
函数参数:TIM_HandleTypeDef *htim--定时器句柄
返回值: 无
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM14)
{
HAL_TIM_Base_Stop_IT(&htim14);
updata_flag++;
if(updata_flag <= 5000)
{
ShowNum(1,1,(device_paramter.Temp/100));
ShowNum(1,2,(device_paramter.Temp / 10 % 10));
ShowNum(1,3,device_paramter.Temp%10);
}
else if(updata_flag <= 10000)
{
ShowNum(2,1,(device_paramter.Humi/100));
ShowNum(2,2,(device_paramter.Humi / 10 % 10));
ShowNum(2,3,device_paramter.Humi%10);
}
else
{
updata_flag = 0;
sleep_flag++;
}
__HAL_TIM_SetCounter(&htim14,0);
if(sleep_flag >= 2)
{
sleep_flag = 0;
device_paramter.sleepStatus = 1;
SN74HC595_Send_Data(SN_DIG,0xFF);
SN74HC595_Send_Data(SN_LED1,0x00);
SN74HC595_Send_Data(SN_LED2,0x00);
}
else{
HAL_TIM_Base_Start_IT(&htim14);
}
}
}
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
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
C
/* 64Mhz时钟时,当ulCount为1,函数耗时3个时钟,延时=3*1/64us */
__asm void SysCtlDelay(unsigned long ulCount)
{
SUBS r0,#1;
BNE SysCtlDelay;
BX lr;
}
/*
函数内容:数码管显示数据函数
函数参数:uint8_t row----行号
uint8_t column-列号
uint8_t value--显示数据
返回值:无
*/
void ShowNum(uint8_t row, uint8_t column, uint8_t value)
{
if(row == 1)
{
switch(column)
{
case 1: //如果是第一排第一个
SN74HC595_Send_Data(SN_DIG,0xFE);
SN74HC595_Send_Data(SN_LED1,sgh_value[value]);//显示值对应16进制数
break;
case 2:
SN74HC595_Send_Data(SN_DIG,0xFD);
SN74HC595_Send_Data(SN_LED1,(sgh_value[value]|0x80));
break;
case 3:
SN74HC595_Send_Data(SN_DIG,0xFB);
SN74HC595_Send_Data(SN_LED1,sgh_value[value]);
break;
default:
break;
}
SysCtlDelay(1000); //大致延时50us
SN74HC595_Send_Data(SN_LED1,0x00); //消影,防止错位
}
else
{
switch(column)
{
case 1:
SN74HC595_Send_Data(SN_DIG,0xF7);
SN74HC595_Send_Data(SN_LED2,sgh_value[value]);
break;
case 2:
SN74HC595_Send_Data(SN_DIG,0xEF);
SN74HC595_Send_Data(SN_LED2,(sgh_value[value]|0x80));
break;
case 3:
SN74HC595_Send_Data(SN_DIG,0xDF);
SN74HC595_Send_Data(SN_LED2,sgh_value[value]);
break;
default:
break;
}
SysCtlDelay(1000); //大致延时50us
SN74HC595_Send_Data(SN_LED2,0x00);
}
}
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
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