外观
四、代码介绍
总体概述
项目使用STM32F407VET6作为主控芯片,代码使用HAL库、STM32Cubemx进行图形化配置+Keil5进行编译,用户仅需关注逻辑代码实现即可。
该项目代码并不复杂,使用功能仅有SPI、ADC、GPIO输入输出三个模块;处理的重点在屏幕数据的显示、按键交换和修改、adc数据的读取与校准;
屏幕数据显示
屏幕驱动不做介绍,移植厂商给的驱动即可。重点关注屏幕数据显示,我将屏幕数据显示分为三个部分,静态数据显示、动态数据显示、按键数据显示;
- 静态数据显示:指UI边框、提示标题等信息,这些信息后续不会修改,所以只需要操作一遍即可,不用反复刷新;
- 动态数据显示:指实时获取的电压值、电流值、电阻值、二极管值等信息,这些信息需要不断更新,这里我将该数据分为不同的任务,比如测电压任务、测电流任务等,然后在任务处理中进行实时更新;
- 按键数据显示:指通过按键交互从而发生改变的数据,比如万用表当前模式,没有按键交互时不会更新;
C
void TFT_ShowStaticUI(const struct KeyInfo info)
{
TFT_Fill(0,0,160,128,BLACK);
HAL_Delay(100);
TFT_ShowChinese(13,2,(uint8_t *)"简易万用表",GREEN,BLACK,16,0);
TFT_ShowChinese(108,4,(uint8_t *)"当前模式",WHITE,BLACK,12,0);
TFT_ShowChinese(108,44,(uint8_t *)"当前量程",WHITE,BLACK,12,0);
TFT_ShowChinese(108,84,(uint8_t *)"当前单位",WHITE,BLACK,12,0);
TFT_ShowString(14,101,(uint8_t *)"Max",WHITE,BLACK,12,0);
TFT_ShowString(66,101,(uint8_t *)"Min",WHITE,BLACK,12,0);
TFT_DrawLine(105,0,105,128,GREEN);
TFT_DrawLine(0,20,168,20,GREEN);
TFT_DrawLine(105,40,168,40,GREEN);
TFT_DrawLine(105,60,168,60,GREEN);
TFT_DrawLine(105,80,168,80,GREEN);
TFT_DrawLine(0,100,168,100,GREEN);
TFT_DrawLine(52,100,52,128,GREEN);
TFT_DrawLine(0,114,105,114,GREEN);
TFT_ShowCursor(info);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
C
void TFT_ShowCursor(const struct KeyInfo info)
{
char showData[32]={0};
if(info.mode == VOL_MODE){
sprintf(showData,"VOL"); //显示当前模式
TFT_ShowString(127,24,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"0-36V"); //显示当前量程
TFT_ShowString(118,64,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"V "); //显示采样次数
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
else if(info.mode == RES_MODE){
sprintf(showData,"RES"); //显示当前模式
TFT_ShowString(127,24,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"0-1MR"); //显示当前量程
TFT_ShowString(118,64,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData," R"); //显示采样次数
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
else if(info.mode == CUR_MODE){
sprintf(showData,"CUR"); //显示当前模式
TFT_ShowString(127,24,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"0-2A "); //显示当前量程
TFT_ShowString(118,64,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"mA"); //显示采样次数
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
else if(info.mode == DIODE_MODE){
sprintf(showData,"DIO"); //显示当前模式
TFT_ShowString(127,24,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData," "); //显示当前量程
TFT_ShowString(118,64,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"V "); //显示采样次数
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
else if(info.mode == BUZ_MODE){
sprintf(showData,"BUZ"); //显示当前模式
TFT_ShowString(127,24,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData," "); //显示当前量程
TFT_ShowString(118,64,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData," R"); //显示采样次数
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
}
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
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
按键处理
按键处理比较简单,此处仅需要进行任务切换,注意切换时需要进行对应红黑表笔的导通
C
/*
* 函数内容:按键处理
* 函数参数:
keyValue--按键值
struct KeyInfo *info--静态信息
* 返回值:无
*/
void key_handle(uint8_t keyValue,struct KeyInfo *info)
{
switch(keyValue)
{
case Key1Press:
break;
case Key1DoublePress:
break;
case Key1LongPress:
break;
case Key2Press:
break;
case Key2DoublePress:
break;
case Key2LongPress:
break;
case Key3Press:
break;
case Key3DoublePress:
{
info->mode++;
if(info->mode >= cur_max_index)
{
info->mode = 0;
}
Clear_TaskData(); //进行任务切换时清空任务数据
Mode_Switch(info->mode);
info->resistor_range = RES_0_100R; //进行任务切换后,电阻默认100R分压
TFT_Fill(4,40,100,72,BLACK); //将显示区域清空
TFT_ShowCursor(*info); //更新静态显示
}
break;
case Key3LongPress:
break;
default:
break;
}
}
/*
* 函数内容:模式切换所做处理
* 函数参数:
mode--模式
* 返回值:无
*/
void Mode_Switch(uint8_t mode)
{
switch(mode)
{
case VOL_MODE:
{
RES_VOL_Connect_VOL(); //继电器切换到电压测量端
DisCon_GND(); //黑表笔不导通到GND
}
break;
case RES_MODE:
{
RES_VOL_Connect_RES(); //继电器切换到电阻测量端
Connect_GND(); //黑表笔导通到GND
Resostor_Connect_100R(); //默认100R分压
}
break;
case CUR_MODE:
{
DisCon_GND(); //黑表笔不导通到GND
}
break;
case DIODE_MODE:
{
RES_VOL_Connect_RES(); //继电器切换到电阻测量端
Connect_GND(); //黑表笔导通到GND
Resostor_Connect_100R(); //默认100R分压
}
break;
case BUZ_MODE:
{
RES_VOL_Connect_RES(); //继电器切换到电阻测量端
Connect_GND(); //黑表笔导通到GND
Resostor_Connect_100R(); //默认100R分压
}
break;
default:
{
DisCon_GND(); //黑表笔不导通到GND
}
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
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
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
任务处理
这里将万用表各模式拆分开变成一个个的任务,电压任务中进行电压测量与显示,电流任务中进行电流测量与显示。
C
/*
* 函数内容:测电压任务
* 函数参数:无
* 返回值:无
*/
void Voltage_Task(void)
{
float TempVolValue = 0, Vol_Value = 0; //临时电压数据&实际电压值
float volMaxValue = 0, volMinValue = 9999; //最大电压值&最小电压值
char showData[32]={0}; //显示数据
uint16_t value_sum = 0,ref_vol_value = 0,i = 0; //采集电压平均值、参考电压平均值、计数下标
//设置通道为电压ADC引脚
Set_ADC_Channel(ADC_CHANNEL_12);
value_sum = Get_ADC_Average(200); //获取200次平均值
//设置通道为内部参考电压
Set_ADC_Channel(ADC_CHANNEL_VREFINT);
ref_vol_value = Get_ADC_Average(100); //获取100次平均值
TempVolValue = ((value_sum*1.0f) / ref_vol_value)*1.21f; //换算为真实电压值
sum_tempValue[tempNum] = TempVolValue; //记录每一个值
tempNum++;
if(tempNum >= 100)
{
bubble_sort(sum_tempValue,100); //冒泡排序
for(i=10;i<90;i++)
{
Vol_Value = Vol_Value + sum_tempValue[i];
}
Vol_Value = Vol_Value / 80.0f; //掐头去尾取100次平均值
if(Vol_Value > 1.65f)
{
//如果是红正黑负
volMaxValue = (492.0f * (sum_tempValue[89] - 1.660f)) / 22.0f; //计算区间内最大值
volMinValue = (492.0f * (sum_tempValue[10] - 1.660f)) / 22.0f; //计算区间内最小值
Vol_Value = (492.0f * (Vol_Value-1.660f)) / 22.0f; //计算真实电压值
//减去零点漂移,这个最开始需注释掉,观察未测量时电压值,然后进行处理
//volMaxValue = volMaxValue - 0.240f;
//volMinValue = volMinValue - 0.240f;
//Vol_Value = Vol_Value - 0.240f;
if(Vol_Value <= 0.1f){
Vol_Value = 0;
}
sprintf(showData," ");
TFT_ShowString(4,40,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
}
else
{
//如果是红负黑正
volMinValue = (492.0f * (1.660f - sum_tempValue[89])) / 22.0f; //计算区间内最大值
volMaxValue = (492.0f * (1.660f - sum_tempValue[10])) / 22.0f; //计算区间内最小值
Vol_Value = (492.0f * (1.660f - Vol_Value)) / 22.0f; //计算真实电压值
//减去零点漂移,这个最开始需注释掉,观察未测量时电压值,然后进行处理
//volMaxValue = volMaxValue - 0.240f;
//volMinValue = volMinValue - 0.240f;
//Vol_Value = Vol_Value - 0.240f;
if(Vol_Value <= 0.1f){
Vol_Value = 0;
}
sprintf(showData,"-");
TFT_ShowString(4,40,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
}
sprintf(showData,"%4.2f",Vol_Value); //显示实际电压值
TFT_ShowString(20,40,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%4.2f",volMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%4.2f",volMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
Clear_TaskData(); //清除任务数据
}
}
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
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
C
/*
* 函数内容:测电流任务
* 函数参数:无
* 返回值:无
*/
void Electricity_Task(void)
{
float TempVolValue = 0, Vol_Value = 0; //临时电压数据、实际电压值
char showData[32]={0}; //显示数据
//实际电流值、外部电流平均值、参考电压平均值、计数下标
uint16_t Electricity_Value = 0,value_sum = 0,ref_vol_value = 0,i = 0;
uint16_t Electricity_MaxValue = 0,Electricity_MinValue = 0;
//设置通道为电流ADC引脚
Set_ADC_Channel(ADC_CHANNEL_13);
value_sum = Get_ADC_Average(200); //获取200次平均值
//设置通道为内部参考电压
Set_ADC_Channel(ADC_CHANNEL_VREFINT);
ref_vol_value = Get_ADC_Average(100); //获取100次平均值
TempVolValue = ((value_sum*1.0f) / ref_vol_value)*1.21f; //换算为真实电压值
sum_tempValue[tempNum] = TempVolValue; //记录每一个值
tempNum++;
if(tempNum >= 100)
{
tempNum = 0;
bubble_sort(sum_tempValue,100); //冒泡排序
for(i=10;i<90;i++) //取中间80个
{
Vol_Value = Vol_Value + sum_tempValue[i];
}
Vol_Value = Vol_Value / 80.0f; //取80个的平均值
if(Vol_Value > 1.660f) //此处需要做校准,标准应该是1.65V,但是实际输入值可能会偏大或偏小,这里要先获取实际电压值来进行校准
{
Vol_Value = Vol_Value - 1.660f;
sum_tempValue[89] = sum_tempValue[89] - 1.660f;
sum_tempValue[10] = sum_tempValue[10] - 1.660f;
}
else
{
Vol_Value = 1.660f - Vol_Value;
sum_tempValue[89] = 1.660f - sum_tempValue[89];
sum_tempValue[10] = 1.660f - sum_tempValue[10];
}
Electricity_Value = (uint16_t)((Vol_Value / 50.0f / 0.01f * 1000));
Electricity_MaxValue = (uint16_t)((sum_tempValue[89] / 50.0f / 0.01f * 1000));
Electricity_MinValue = (uint16_t)((sum_tempValue[10] / 50.0f / 0.01f * 1000));
sprintf(showData,"%4d",Electricity_Value); //显示实际电流值
TFT_ShowString(18,40,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)Electricity_MaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)Electricity_MinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
Clear_TaskData();
}
}
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
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
C
/*
* 函数内容:测电阻任务
* 函数参数:无
* 返回值:无
*/
void Resistor_Task(struct KeyInfo *info)
{
float TempVolValue = 0, Vol_Value = 0;//临时电压数据、实际电压值
char showData[32]={0}; //显示数据
//外部电压平均值、参考电压平均值、计数下标
uint16_t value_sum = 0,ref_vol_value = 0,i = 0;
float Resistor_Value = 0,resMaxValue = 0, resMinValue = 0; //实际电阻值、最大电压值、最小电压值
//设置通道为电阻ADC引脚
Set_ADC_Channel(ADC_CHANNEL_9);
value_sum = Get_ADC_Average(200); //获取200次平均值
//设置通道为内部参考电压
Set_ADC_Channel(ADC_CHANNEL_VREFINT);
ref_vol_value = Get_ADC_Average(100); //获取100次平均值
TempVolValue = ((value_sum*1.0f) / ref_vol_value)*1.21f; //换算为真实电压值
sum_tempValue[tempNum] = TempVolValue; //记录每一个值
tempNum++;
if(tempNum >= 100)
{
tempNum = 0;
bubble_sort(sum_tempValue,100); //冒泡排序
for(i=10;i<90;i++)
{
//取中间80个
Vol_Value = Vol_Value + sum_tempValue[i];
}
Vol_Value = Vol_Value / 80.0f; //取80个的平均值
if(info->resistor_range == RES_0_100R) //使用100R分压电阻来测量外部0~300R电阻
{
if(Vol_Value > 2.5f)
{
Resostor_Connect_1K(); //如果是超量程了,切换到下一阻值进行测量
info->resistor_range = RES_100R_1K;
HAL_Delay(10);
}
else
{
Resistor_Value = (uint16_t)((100 * Vol_Value)/(3.287f-Vol_Value));
resMaxValue = (uint16_t)((100 * sum_tempValue[89])/(3.287f-sum_tempValue[89]));
resMinValue = (uint16_t)((100 * sum_tempValue[10])/(3.287f-sum_tempValue[10]));
Resistor_Value = Resistor_Value - 8; //减去误差值
resMaxValue = resMaxValue - 8;
resMinValue = resMinValue - 8;
if((Resistor_Value <= 1000) && (Resistor_Value >= 0))
{
//对阻值范围进行限制
sprintf(showData,"%5d",(uint16_t)Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData," R"); //显示单位
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
if((resMaxValue <= 1000) && (resMinValue <= 1000) && (resMaxValue >= 0) && (resMinValue >= 0))
{
sprintf(showData,"%5d",(uint16_t)resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
}
}
else if(info->resistor_range == RES_100R_1K) //使用1K分压电阻来测量外部300R~10K电阻
{
if(Vol_Value > 3.0f)
{
Resostor_Connect_10K();
info->resistor_range = RES_1K_10K;
HAL_Delay(10);
}
else
{
Resistor_Value = (uint16_t)((1000 * Vol_Value)/(3.287f-Vol_Value));
resMaxValue = ((1000 * sum_tempValue[89])/(3.287f-sum_tempValue[89]));
resMinValue = ((1000 * sum_tempValue[10])/(3.287f-sum_tempValue[10]));
Resistor_Value = Resistor_Value - 9;
resMaxValue = resMaxValue - 9;
resMinValue = resMinValue - 9;
if((Resistor_Value <= 10000) && (Resistor_Value >= 0))
{
//对阻值范围进行限制
sprintf(showData,"%5d",(uint16_t)Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData," R"); //显示单位
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
if((resMaxValue <= 10000) && (resMinValue <= 10000) && (resMaxValue >= 0) && (resMinValue >= 0))
{
sprintf(showData,"%5d",(uint16_t)resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
}
}
else if(info->resistor_range == RES_1K_10K) //使用外部10K分压电阻来测量10K~100K电阻
{
if(Vol_Value > 3.0f)
{
Resostor_Connect_100K();
info->resistor_range = RES_10K_100K;
HAL_Delay(10);
}
else
{
Resistor_Value = (10000 * Vol_Value)/(3.287f - Vol_Value);
resMaxValue = (10000 * sum_tempValue[89])/(3.287f - sum_tempValue[89]);
resMinValue = (10000 * sum_tempValue[10])/(3.287f - sum_tempValue[10]);
Resistor_Value = Resistor_Value - 24.7f; //减去误差值
resMaxValue = resMaxValue - 24.7f;
resMinValue = resMinValue - 24.7f;
Resistor_Value = Resistor_Value / 1000.0f;
resMaxValue = resMaxValue / 1000.0f;
resMinValue = resMinValue / 1000.0f;
if((Resistor_Value <= 1000) && (Resistor_Value >= 0))
{
sprintf(showData,"%4.1f",Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"KR"); //显示单位
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
if((resMaxValue <= 1000) && (resMinValue <= 1000) && (resMaxValue >= 0) && (resMinValue >= 0))
{
sprintf(showData,"%4.1f",resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%4.1f",resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
}
}
else if(info->resistor_range == RES_10K_100K) //使用外部100K电阻来测量剩余范围的阻值
{
if(Vol_Value >= 3.3f) //并不是外部电阻值过大,返回100R分压,重新开始测量
{
Resistor_Value = 0;
resMaxValue = 0;
resMinValue = 0;
sprintf(showData,"%5d",(uint16_t)Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData," R"); //显示单位
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
else if(Vol_Value <= 0.3f)
{
Resostor_Connect_100R(); //默认100R分压
info->resistor_range = RES_0_100R; //电阻量程
HAL_Delay(10);
}
else
{
Resistor_Value = (100000.0f * Vol_Value)/(3.287f-Vol_Value);
resMaxValue = (100000.0f * sum_tempValue[89])/(3.287f - sum_tempValue[89]);
resMinValue = (100000.0f * sum_tempValue[10])/(3.287f - sum_tempValue[10]);
Resistor_Value = Resistor_Value - 172.4f; //减去误差值
resMaxValue = resMaxValue - 172.4f;
resMinValue = resMinValue - 172.4f;
Resistor_Value = Resistor_Value / 1000.0f;
resMaxValue = resMaxValue / 1000.0f;
resMinValue = resMinValue / 1000.0f;
if((Resistor_Value <= 1000) && (Resistor_Value >= 0))
{
sprintf(showData,"%4.1f",Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"KR"); //显示单位
TFT_ShowString(124,102,(uint8_t *)showData,YELLOW,BLACK,24,0);
memset(showData,0,32);
}
if((resMaxValue <= 1000) && (resMinValue <= 1000) && (resMaxValue >= 0) && (resMinValue >= 0))
{
sprintf(showData,"%4.1f",resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%4.1f",resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
}
}
Clear_TaskData();
}
}
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
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
C
/*
* 函数内容:测通断任务
* 函数参数:无
* 返回值:无
*/
void Buzzing_Task(void)
{
float TempVolValue = 0, Vol_Value = 0;//临时电压数据、实际电压值
char showData[32]={0}; //显示数据
//外部电压平均值、参考电压平均值、计数下标
uint16_t value_sum = 0,ref_vol_value = 0,i = 0;
float Resistor_Value = 0,resMaxValue = 0, resMinValue = 0; //实际电阻值、最大电压值、最小电压值
//设置通道为电阻ADC引脚
Set_ADC_Channel(ADC_CHANNEL_9);
value_sum = Get_ADC_Average(100); //获取200次平均值
//设置通道为内部参考电压
Set_ADC_Channel(ADC_CHANNEL_VREFINT);
ref_vol_value = Get_ADC_Average(100); //获取100次平均值
TempVolValue = ((value_sum*1.0f) / ref_vol_value)*1.21f; //换算为真实电压值
sum_tempValue[tempNum] = TempVolValue; //记录每一个值
tempNum++;
if(tempNum >= 100)
{
tempNum = 0;
bubble_sort(sum_tempValue,100); //冒泡排序
for(i=10;i<90;i++)
{
//取中间80个
Vol_Value = Vol_Value + sum_tempValue[i];
}
Vol_Value = Vol_Value / 80.0f; //取80个的平均值
if(Vol_Value >= 3.3f){
sum_tempValue[89] = 0;
sum_tempValue[10] = 0;
}
Resistor_Value = (uint16_t)(100 * Vol_Value)/(3.287f-Vol_Value);
resMaxValue = (100 * sum_tempValue[89])/(3.287f-sum_tempValue[89]);
resMinValue = (100 * sum_tempValue[10])/(3.287f-sum_tempValue[10]);
if(Resistor_Value < 0){
Resistor_Value = -Resistor_Value;
}
if((Resistor_Value <= 20 && Resistor_Value>= 0) && (resMaxValue >= 0) && (resMinValue >= 0))
{
//对阻值范围进行限制
sprintf(showData,"%4d",(uint16_t)Resistor_Value); //显示实际电阻值
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
Open_Beep();
}
else{
Resistor_Value = 0;
resMaxValue = 0;
resMinValue = 0;
sprintf(showData," .OL");
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMaxValue); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)resMinValue); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
Closer_Beep();
}
Clear_TaskData();
}
}
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
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
C
/*
* 函数内容:测二极管档任务
* 函数参数:无
* 返回值:无
*/
void Dio_Task(void)
{
float TempVolValue = 0, Vol_Value = 0;//临时电压数据、实际电压值
char showData[32]={0}; //显示数据
//外部电压平均值、参考电压平均值、计数下标
uint16_t value_sum = 0,ref_vol_value = 0,i = 0;
//设置通道为电阻ADC引脚
Set_ADC_Channel(ADC_CHANNEL_9);
value_sum = Get_ADC_Average(200); //获取200次平均值
//设置通道为内部参考电压
Set_ADC_Channel(ADC_CHANNEL_VREFINT);
ref_vol_value = Get_ADC_Average(100); //获取100次平均值
TempVolValue = ((value_sum*1.0f) / ref_vol_value)*1.21f; //换算为真实电压值
sum_tempValue[tempNum] = TempVolValue; //记录每一个值
tempNum++;
if(tempNum >= 100)
{
tempNum = 0;
bubble_sort(sum_tempValue,100); //冒泡排序
for(i=10;i<90;i++)
{
//取中间80个
Vol_Value = Vol_Value + sum_tempValue[i];
}
Vol_Value = Vol_Value / 80.0f; //取80个的平均值
if(Vol_Value >= 3.3f)
{
sum_tempValue[89] = 0;
sum_tempValue[10] = 0;
sprintf(showData," .OL");
TFT_ShowString(18,44,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)sum_tempValue[89]); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%5d",(uint16_t)sum_tempValue[10]); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
else
{
sprintf(showData,"%4.2f",Vol_Value); //显示实际电压值
TFT_ShowString(20,40,(uint8_t *)showData,RED,BLACK,32,0);
memset(showData,0,32);
sprintf(showData,"%4.2f",sum_tempValue[89]); //显示max
TFT_ShowString(8,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
sprintf(showData,"%4.2f",sum_tempValue[10]); //显示min
TFT_ShowString(60,115,(uint8_t *)showData,RED,BLACK,12,0);
memset(showData,0,32);
}
Clear_TaskData();
}
}
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
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
主函数处理
大部分初始化操作cubemx已经帮我们处理完成了,这里主要是对屏幕和定时器进行初始化,并且开启默认输出;在while循环中,考虑到有屏幕显示、有任务处理、有按键扫描,这些操作所需时间间隔是不一致的,如果单纯用一个延时不太合适,这里加入一个定时器,进行1ms计时,然后分配不同的时间,比如500ms刷新屏幕,10ms扫描按键等。
C
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t keyValue = 0; //获取按键值
struct KeyInfo keyinfo = {0}; //按键切换信息
keyinfo.mode = VOL_MODE; //当前模式
keyinfo.resistor_range = RES_0_100R; //默认电阻分压
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_SPI1_Init();
MX_TIM3_Init();
MX_IWDG_Init();
/* USER CODE BEGIN 2 */
TFT_Init(); //初始化屏幕
TFT_ShowStaticUI(keyinfo); //显示静态UI
HAL_TIM_Base_Start_IT(&htim3); //消息定时器开始计时
Mode_Switch(keyinfo.mode); //模式切换所做操作
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(wdgTimer >= 50)
{
HAL_IWDG_Refresh(&hiwdg); //每隔50ms喂一次狗
wdgTimer = 0;
}
if(keyTimer >= 10) //每10ms进行按键扫描
{
keyTimer = 0;
keyValue = key_scanf();
if(keyValue!=KEY_ERROR){
key_handle(keyValue,&keyinfo); //如果有按键按下则进行处理
}
keyValue = KEY_ERROR;
}
if(keyinfo.mode == VOL_MODE)
{
//电压测量任务
Voltage_Task();
}
else if(keyinfo.mode == RES_MODE)
{
//电阻测量任务
Resistor_Task(&keyinfo);
}
else if(keyinfo.mode == CUR_MODE)
{
//电流测量任务
Electricity_Task();
}
else if(keyinfo.mode == BUZ_MODE)
{
//通断测量任务
Buzzing_Task();
}
else if(keyinfo.mode == DIODE_MODE)
{
//二极管测量任务
Dio_Task();
}
}
/* USER CODE END 3 */
}
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
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