c语言day6
模拟获取co2,pm2.5的数值,并对co2的浓度,pm2.5的浓度做出划分,详情划分在代码注释
首先写写出模拟获取数值的函数,但是由于要对浓度划分,所以先枚举出来等级划分
typedef enum
{
Excellent,//默认0往下递增
Good,
Average,
Poor
}QualityLevel;
接着写出模拟获取co2函数(在这里用到了static关键字,静态函数能够确保只在co2的c文件使用以便于接下来在pm2的文件中使用)
static int32_t GetRawData(void)//模拟获取co2
{
return 500;
}
根据浓度值划分来写出对应的枚举参数
/*
小于100 对应 Excellent 0
大于等于100、小于200 对应 Good 1
大于等于200、小于300 对应 Average 2
大于等于300 对应 Poor 3~
*/
QualityLevel GetCo2Level(void)//等级划分
{
int32_t raw = GetRawData();
int32_t level = raw / 100;//除以100正好跟枚举的数值相匹配
return (QualityLevel) level;
}
方面观察写一个打印co2当前的浓度等级
void DisplayCo2Level(QualityLevel lv)
{
switch (lv)
{
case Excellent:
printf("The air quality of co2 is excellent.\n");
break;
case Good:
printf("The air quality of co2 is good.\n");
break;
case Average:
printf("The air quality of co2 is average.\n");
break;
default:
printf("The air quality of co2 is poor.\n");
break;
}
}
记得在h文件对函数声明在main函数就可以获取co2的浓度划分了
QualityLevel co2Level;//获取co2数值
co2Level = GetCo2Level();
DisplayCo2Level(co2Level);//打印
同理pm2.5的函数可以参考这个来写
static int32_t GetRawData(void)//模拟pm25原始数据
{
return 50;
}
/*
小于10 对应 Excellent
大于等于10、小于35 对应 Good
大于等于35、小于75 对应 Average
大于等于75 对应 Poor
*/
QualityLevel GetPm25Level(void)//对数据进行环境评判
{
int32_t raw = GetRawData();
QualityLevel level;
if(raw < 10)
{
level = Excellent;
}
else if(raw >= 10 && raw < 35)
{
level = Good;
}
else if(raw >= 35 && raw < 75)
{
level = Average;
}
else
{
level = Poor;
}
return level;
}
void DisplayPm25Level(QualityLevel lv)//打印当前数据质量
{
switch (lv)
{
case Excellent:
printf("The air quality of pm2.5 is excellent.\n");
break;
case Good:
printf("The air quality of pm2.5 is good.\n");
break;
case Average:
printf("The air quality of pm2.5 is average.\n");
break;
default:
printf("The air quality of pm2.5 is poor.\n");
break;
}
}
练习2,模拟传感器的温度值,并且转换成华氏温度,并且传入一个外部校准对温度值进行校准
根据这段话可以分析:模拟传感器的温度值-写出一个外部校准函数-对温度值进行5次求和在进行校准-转换成华氏温度
模拟传感器获得的温度
static float GetRawData(void)//模拟获取温度
{
static uint8_t s_chgVal = 0;
s_chgVal++;
s_chgVal %= 5;//数值维持在1-4
return 20.f + s_chgVal;
}
在main函数中写入一个外部校准函数
float GetTemCofHmi(void)//外部校准
{
return 1.2f;
}
接着回到tem的c文件,要想在c文件调用这个函数,并且跟主函数的耦合性不大,可以在tem的c文件中写入一个获取外部校准的函数的变量,届时,在主函数借用两个函数就能完成传递,首先定义一个静态全局变量(确保在对温度值求和的时候校准使用)
static float g_temCof;
void SetTemCof(float temCof)//外部温度校准函数获得
{
g_temCof = temCof;
}
接着对温度求和(这里用到了宏定义,温度小于最小的值,返回最小的值,大于最大的值返回最大的值)
float GetCelTem(void)
{
float cel1 = GetRawData();//获取5次温度值
printf("cel1 = %.1f.\n", cel1);
float cel2 = GetRawData();
printf("cel2 = %.1f.\n", cel2);
float cel3 = GetRawData();
printf("cel3 = %.1f.\n", cel3);
float cel4 = GetRawData();
printf("cel4 = %.1f.\n", cel4);
float cel5 = GetRawData();
printf("cel5 = %.1f.\n", cel5);
float cel = (cel1 + cel2 + cel3 + cel4 + cel5) / 5;//求和
cel *= g_temCof;//温度校准
if (cel < CEL_MIN_VALUE)
{
cel = CEL_MIN_VALUE;
}
if (cel > CEL_MAX_VALUE)
{
cel = CEL_MAX_VALUE;
}
return cel;
}
根据公式获得华氏温度(在这里把公式宏定义)
float GetFahTem(void)//转换成华氏温度
{
float raw = GetRawData();
float fah = CEL_TO_FAH(raw) * 1.2f;
return fah;
}
h文件的宏定义
#define CEL_MAX_VALUE 55.0f
#define CEL_MIN_VALUE 5.0f
#define CEL_TO_FAH(t) ((t) * 9.0f / 5.0f + 32)
在main函数中调用这两个函数
volatile float celTem;//获取温度
SetTemCof(GetTemCofHmi());//调用函数来完成外部校准系数的传递
celTem = GetCelTem();//温度
printf("Temperature is %.1f cel degrees.\n", celTem);
float fahTem = GetFahTem();//华氏温度
printf("Temperature is %.1f fah degrees.\n", fahTem);
栈溢出的危害:
如果函数实际使用的栈空间超过栈最大值,就会发生栈溢出,导致程序异常
避免栈溢出
增加栈的最大值,在保证硬件内存空间够用的情况下
一维数组应用案例:给一个数组NUMS,数组中有2n个元素,按照[x1,x2,x3.....xn,y1,y2,y3....yn]的格式排列,请将数组按照[x1,y1,x2,y2,....xn,yn]格式重新排列
示例:nums=[2,5,1,3,4,7],n = 3;
观察实列可得每次访问的2个目标数组元素的下标和 i 对应关系为:(2*i)和(2*i+1)
每次访问的2个目标原始数组元素的下标和 i 的对应关系:(i)和(2*i+1)
nums = [2,5,1,3,4,7],n = 3;
for(uint32_t i = 0; i < n; i++)
{
res[2*i] = nums[i];
res[2*i+1] = nums[i+n];
}
for(uint32_t i = 0; i < 2*n; i++)
{
printf("%d.",res[i]);
}
printf("\n");
二维数组:数据类型 数组名称[行数][列数]
int32_t buffer[3][4];//buffer为3行4列的数组
应用案例:在一维数组的基础上,增加温度传感器数量到3个,这样可以检测3个环境点位的温度,在main函数中,每个点位都要保持5个温度数据
static float g_temCof;
static float GetRawData(uint8_t sensorID)//模拟获取温度
{
static uint8_t s_chgVal = 0;
s_chgVal++;
s_chgVal %= 5;//数值维持在1-4
return 20.f + s_chgVal;
}
void SetTemCof(float temCof)//外部温度校准
{
g_temCof = temCof;
}
float GetCelTem(uint8_t sensorID)
{
float cel = GetRawData(sensorID);//获取5次温度值
cel *= g_temCof;//温度校准
if (cel < CEL_MIN_VALUE)
{
cel = CEL_MIN_VALUE;
}
if (cel > CEL_MAX_VALUE)
{
cel = CEL_MAX_VALUE;
}
return cel;
}
float GetFahTem(void)//转换成华氏温度
{
float raw = GetRawData(sensorID);
float fah = CEL_TO_FAH(raw) * 1.2f;
return fah;
}
在main函数首先对传感器的型号遍历接着进入温度遍历
volatile float celTem[3][5];
for(uint8_t i = 0; i < 3; i++)
{
for(uint8_t j = 0; j < 5; j++)
{
celTem[i][j] = GetCelTem(i);
printf ("tem of sensor%d = %.1f by %d tem.\n",i,celTem[i][j],j);
}
}