第十三届蓝桥杯物联网试题(国赛)





还是那句话不能掉以轻心,全力以赴吧,遇事不要慌,该做的都做了,冷静沉稳的处理,看看配置,看看代码,还是不行就重启,都没问题换个板子

下面对比较复杂的部分的处理过程进行展现:


这个我是配合定时器和中断按键处理的,大致思路,按下按键在按键中断函数中将相应标志位置1

c 复制代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  // 按键
	//OLED_ShowString(0, "victory");
	STARTTEST = 1;
	MEMFLAG = 1;
}

主函函数识别标志位变为1则做相应ADC获取,以及OLED显示

c 复制代码
void Function_StartAdc(){  
  if(STARTTEST == 1){
		//Function_OledInit(10);
		HAL_TIM_Base_Start_IT(&htim7);
	    Function_GetAdc();
		Function_OledShow();
		HAL_GPIO_WritePin(K1_GPIO_Port, K1_Pin, GPIO_PIN_SET);
	}else {
		HAL_GPIO_WritePin(K1_GPIO_Port, K1_Pin, GPIO_PIN_RESET);
	    OLED_Clear();
		//HAL_GPIO_WritePin(OLED_Power_GPIO_Port, OLED_Power_Pin, GPIO_PIN_SET);
	}
}

检测数值是否稳定,在第一次获取ADC数值的时候备份一下,在定时器里去分析是否稳定,不稳定定时器计数值归零否者继续计数

c 复制代码
void Function_GetAdc(){
	uint16_t AdcData[2];
	for(unsigned char i = 0; i < 2; i ++){
	  HAL_ADC_Start(&hadc);
		HAL_ADC_PollForConversion(&hadc, 0xff);
		AdcData[i] = HAL_ADC_GetValue(&hadc);
		HAL_Delay(5);
	}
	HAL_ADC_Stop(&hadc);
	RP1Value = AdcData[1] * 3.30f / 4095;
	RP2Value = AdcData[0] * 3.30f / 4095;
	if(MEMFLAG == 1){  // 做备份
		MEMFLAG = 0;
		MEMRP1VALUE = RP1Value;
		MEMRP2VALUE = RP2Value;
	}
	if(RP1Value <= 3.3) WT = RP1Value * 80 / 3.3;
	else WT = 80;
	if(RP2Value <= 1) BF = 5;
	else if(RP2Value > 1 && RP2Value < 2) BF = RP2Value * 40 - 35;
	else BF = 45;
}
c 复制代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  // 10ms
	//OLED_ShowString(0, "victory");
	if(STARTTEST == 1){ // 测量体重
	  if(COUNTNUMBER >= 300){
			//HAL_TIM_Base_Stop_IT(&htim7);
			STARTTEST = 0;
			TESTVICTORY  = 1;
			COUNTNUMBER = 0;
			sprintf((char* )SENDMSG, "#%.1f#%.1f", WT, BF);
			LORA_Tx(SENDMSG, 20);
		}			
	    DERTARP1 = RP1Value - MEMRP1VALUE;
		DERTARP2 = RP2Value  - MEMRP2VALUE;
	  if(DERTARP1 > -0.1 && DERTARP1 < 0.1 && DERTARP2 > -0.1 && DERTARP2 < 0.1) COUNTNUMBER ++;
	  else {
			MEMRP1VALUE = RP1Value;
			MEMRP2VALUE = RP2Value;
		    COUNTNUMBER = 0;
		}
  }
	
	if(TESTVICTORY == 1){  // LD5闪烁
		if(COUNTNUMBER <= 300) {
		     COUNTNUMBER ++;
			 if(COUNTNUMBER % 10 == 0) HAL_GPIO_TogglePin(LD5_GPIO_Port, LD5_Pin);
		}
		else{
			TESTVICTORY = 0;
			HAL_TIM_Base_Stop_IT(&htim7);
			HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET);
			COUNTNUMBER = 0;
		}
	}
}

LD5是每0.1s反转一次,也就是整10位反转,所以直接%10即可

够3s后OLED直接清屏就行,断开电源开启还要初始化很麻烦


储存用结构体

c 复制代码
typedef struct{
  unsigned char MEMWT[10];
	unsigned char MEMBF[10];
}MEMO;

符合要求得数据直接memcpy过来就行

对于LORA传输的数据要做一些处理,再判断

c 复制代码
void Function_LorRxHandle(){
  if(RECEIVEMSG[0] == '#'){
		Function_ArrayClean(RXWT, sizeof(WT));
		Function_ArrayClean(RXBF, sizeof(BF));
		unsigned char i = 1;
		unsigned char j = 0;
		while(RECEIVEMSG[i] != '#') RXWT[j ++] = RECEIVEMSG[i ++];
		i ++;
		j = 0;
		while(RECEIVEMSG[i] != '\0') RXBF[j ++] = RECEIVEMSG[i ++];
		//OLED_ShowString(0, WT);
		//OLED_ShowString(2, BF);
		TPRXBF = strtof((char* )RXBF, NULL);
		TPMAXBF = strtof((char* )MAXBF, NULL);
		TPMINBF = strtof((char* )MINBF, NULL);
		if(!(TPRXBF >= TPMINBF && TPRXBF <= TPMAXBF)){
			HAL_TIM_Base_Start_IT(&htim7);
		}else{
			HAL_TIM_Base_Stop_IT(&htim7);
			HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET);
			Function_ArrayClean(WT, sizeof(WT));
		  Function_ArrayClean(BF, sizeof(BF));
			memcpy(BF, RXBF, 10);
			memcpy(WT, RXWT, 10);
			memcpy(MEMORX[INDEX].MEMBF, BF, 10);
			memcpy(MEMORX[INDEX].MEMWT, WT, 10);
			INDEX = (INDEX + 1) % 20;
		}
	}
	if(RECEIVEMSG[0] != '\0') Function_ArrayClean(RECEIVEMSG, sizeof(RECEIVEMSG));
}
c 复制代码
        unsigned char i = 1;
		unsigned char j = 0;
		while(RECEIVEMSG[i] != '#') RXWT[j ++] = RECEIVEMSG[i ++];
		i ++;  // 跳过'#'
		j = 0;
		while(RECEIVEMSG[i] != '\0') RXBF[j ++] = RECEIVEMSG[i ++];

这一步部分的作用是将例如#value1#value2分别取出来,因为value1和2的位数不知道所以用memcpy是不行的,这就要用算法来操作了

操作之前记得将数组里的值清除一下,防止这次的数据被前面接收的数据污染:

c 复制代码
void Function_ArrayClean(unsigned char* array, uint16_t len){
	for(unsigned char i = 0; i < len; i ++) array[i] = '\0';
}
c 复制代码
if(RECEIVEMSG[0] != '\0') Function_ArrayClean(RECEIVEMSG, sizeof(RECEIVEMSG));

将处理函数放外面是因为,比赛可能有其他人发送的数据可能会被误收,更要清除

对串口数据的处理更是将神器strtof函数运用到极致,真是不得不佩服大佬写的函数

c 复制代码
void Function_UartRxMsgHandle(){
  if(UARTRXMSG[0] != '\0'){
	    HAL_Delay(10);
		//OLED_ShowString(0, UARTRXMSG);
		TEMP = strtof((char* )UARTRXMSG, &p);
		if(*p == '\0'){  // 查询指令
			if(TEMP >= 1 && TEMP <= 20){
				Function_ArrayClean(SENDMSG, sizeof(SENDMSG));
				sprintf((char* )SENDMSG, "WT:%sKG,BF:%s%%", MEMORX[(int)TEMP - 1].MEMWT, MEMORX[(int)TEMP - 1].MEMBF);
				HAL_UART_Transmit(&huart2, SENDMSG, sizeof(SENDMSG), 0xff);
			}else{
				HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);
			}
		}else if(*p == ','){  // 改变指令
			Function_ArrayClean(TEMPUARTRX, sizeof(TEMPUARTRX));
			unsigned char i = 0;
			unsigned char j = 0;
			while(UARTRXMSG[i ++] != ',');
			while(UARTRXMSG[i] != '\0') TEMPUARTRX[j ++] = UARTRXMSG[i ++];
			
			TEMP1 = strtof((char* )TEMPUARTRX, &q);
			if(*q == '\0' && TEMP <= TEMP1 && TEMP >= 0 && TEMP <= 45 && TEMP1 >= 0 && TEMP1 <= 45){
			  sprintf((char* )MINBF, "%d", (int)TEMP);
				sprintf((char* )MAXBF, "%d", (int)TEMP1);
			}else HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);
		}else HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);
		Function_ArrayClean(UARTRXMSG, sizeof(UARTRXMSG));
		 
	}
}

延时10ms是因为是DMA接收,所以让CPU别急着处理让DMA将数据接受完再处理

之前讲过strtof的性质,将字符串转换成浮点型直到不能转换为止,所以利用这个性质:
将数据先全部转换一次,如果全部都能转换即指针指向空字符,那么就是查询语句,如果指针指向','那就说明是设置值命令,如果指向的是其他字符,则可返还错误,如果指向','此时可利用上面分割#字符的方式将','字符分割到另一个数组做分析,再次分析另一个设置数据合不合法

c 复制代码
            while(UARTRXMSG[i ++] != ',');
			while(UARTRXMSG[i] != '\0') TEMPUARTRX[j ++] = UARTRXMSG[i ++];

先跳过第一个','再对后一个字符串做处理

这个处理过程让我找到了后端开发的感觉,先写主体判断框架,再实现框架内部内容

这一部分得慢慢来慢慢调试

相关推荐
CV金科16 小时前
蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)
stm32·单片机·嵌入式硬件·算法·蓝桥杯
希望有朝一日能如愿以偿17 小时前
力扣题解(飞机座位分配概率)
算法·leetcode·职场和发展
TANGLONG22220 小时前
【C语言】数据在内存中的存储(万字解析)
java·c语言·c++·python·考研·面试·蓝桥杯
ya888g21 小时前
蓝桥等级考试C++组17级真题-2023-05-21
开发语言·c++·蓝桥杯
SZPU领跑1 天前
第十二届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)(第一套)
stm32·单片机·算法·职场和发展·蓝桥杯
神一样的老师1 天前
面向MQTT基础物联网网络的Age-of-Information感知的保留消息策略
网络·物联网
TANGLONG2221 天前
【C语言】字符和字符串函数(2)
java·c语言·c++·python·考研·面试·蓝桥杯
Tlog嵌入式1 天前
蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键
arm开发·stm32·单片机·mcu·物联网·蓝桥杯·iot
码农超哥同学1 天前
Python知识点:如何使用Google Cloud IoT与Python进行边缘计算
python·物联网·面试·编程·边缘计算
qq_294481311 天前
nrf 24l01使用方法
stm32·嵌入式硬件·物联网