Stm32_标准库_期末设计_温度测量&光照测量&手机与芯片通信实现信息的更新

目录

前言:

期末设计预期的效果是整个系统能对环境温度、环境的光照情况进行测量及显示,并且能对时间及日期进行显示。时间与日期的控制不再打算用按键进行修改,取而代之用蓝牙模块实现手机与蓝牙模块之间单向通信,即手机向蓝牙模块发送当前的时间或日期,蓝牙模块接受数据,通过内部代码对数据进行筛选与解析,最后更新芯片自身数据为手机发送的数据。


1.接线:

1、光敏传感器AO端口接GPIO_PA_0

2、热敏传感器AO端口接GPIO_PA_1

3、蓝牙模块端口RXD接GPIO_PA_9

4、蓝牙模块端口TXD接GPIO_PA_10


2.效果:


3.手机与芯片单向通信:

手机与芯片之间的单向通信首先要解决以下几个问题:

1、如何确保接收数据的完整性?

2、如何判断传输数据的合法性?

解答如下:


------ 2023/10/16

(1) 确保接收数据的完整性:

首先需要注意的就是数据之所以会出现丢失,主要原因在于手机向接受端发送信息时,接收端不能及时接受信息,以至于前一个数据还未来的及接受就被后来的数据覆盖

数据不能被及时接收的原因:

网上常用数据接收代码:

void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
	Serial_RxData = USART_ReceiveData(USART1); //一个一个接收
	Serial_RxFlag = 1;
	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}

由上述串口接收数据中断函数可以看出,触发中断后数据总是一个字节逐个被Serial_RxData变量接收

接着标记标志位Serial_RxFlag,主函数发现标志位变化,才会接受并储存Serial_RxData上的数据

这个逻辑看似没有问题,但漏洞在于,我们的主函数不可能时刻判断标志位的值是否变化吧?朴素的说主函数不可能就执行判断标志位是否变化这一个语句吧?正是由于主函数在执行其他语句的时候导致没能时刻观察标志位的变化,而导致数据不能被立即接收,最终导致了数据丢失

那么解决方向就显而易见了,即如何做到数据能在中断发生的时候就立即接收呢?
答案就是数组

优化代码:

c 复制代码
void USART1_IRQHandler(void)//中断函数
{
	
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		news[I] = USART_ReceiveData(USART1);//读数据
		Serial_RxFlag = 1;//至标志位为有数据
		I ++;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		 
	}
}

在中断产生的时候就立即用数组进行接收,同时标记标志位

主函数发现标志位变化了,等待一会就可以获取数组,取出传输方发送的全部信息了


(2) 判断传输数据的合法性:

传输方发送的信息不可能都是符合标准的,那么如何对数据进行筛选就显得及其重要

首先对我们需要的正确信息进行分析其特点:

例如需要获取的正确信息如下:
    日期:2023/10/17
    时间:21:57:55

分析上述两个典型数据,可以发现日期的特点是数据里存在/,数据时间特点是有:,那么第一次筛选条件就是判断接收数据是否存在上述任意一种符号。

这个在数据传输阶段就可以用两个标志位判断:

c 复制代码
if(news[i] == '/') flagDate = 1;
if(news[i] == ':') flagTime = 1;

接下来摆在面前的就是假若筛选后的数据里出现超过两个/:符号的时候

再进一步讲上若传入的数据符号为两个,但是传入的时间为25:15:80阁下又应该如何应对?

要解决上述问题还是要对传入数据的特点进行细节分析:

拿日期 2023/10/17 进行分析,其中/符号出现了两次我们完全可以用一个cnt在拆解数据的过程中进行计数,若最后cnt的大小不等于2的时候那么这个数据就会被判断为不合法这样符号问题就解决了

那么又如何对年份,月份,天数、进行判别呢?这就需要将数据进行切割了拿2023/10/17 示范,分析数据,巧妙的是在2023出现的时候cnt = 0,也就是在2023之前没有出现/而到10出现的时候cnt = 1,最后17出现的时候自然cnt = 2。恍然大悟用一个updateDate[cnt]分别对数据进行储存即可updateDate[0] = 2023、updateDate[1] = 10、updateDate[2] = 17再对这三个数据分别分析就可以最终判断传入的数据是否合法了!

实现代码:

c 复制代码
uint8_t Function_DateState(unsigned int *updateDate, char *News){
	      uint8_t cnt = 0;
	      uint8_t i = 0;
	      uint8_t end = Serial_GetI();
	      char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	      while(i < end){
					if(News[i] == '/') {
						 cnt ++;
						 i ++;
						 if(cnt >= 3) {
							 
							 return 0;
						 }
						 continue;
					}
					updateDate[cnt] = updateDate[cnt]* 10 + (News[i] - '0');
					i ++;
        }
				 
				if(cnt != 2) return 0;
				  
				if(Function_Numlength(updateDate[0]) >= 5 || updateDate[0] > 9999 || updateDate[0] == 0) return 0;
				
				if((updateDate[0] % 4 == 0 && updateDate[0] % 100 != 0 )|| updateDate[0] % 400 == 0) month[2] = 29;
	      else month[2] = 28;
				 
				if(Function_Numlength(updateDate[1]) >= 3 || updateDate[1] > 12 || updateDate[1] == 0) return 0;
				if(Function_Numlength(updateDate[2]) >= 3 || updateDate[2] > month[updateDate[1]]|| updateDate[2] == 0) return 0;
				
        Time_GetArrayMonth()[2] = month[2];//这里年份也会发生变化,要修改原有数据
				
				return 1;
				
}

------ 2023/10/17

相关推荐
m0_739312872 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章3 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu3 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
基极向上的三极管4 小时前
【AD】3-4 在原理图中放置元件
嵌入式硬件
徐嵌4 小时前
STM32项目---水质水位检测
stm32·单片机·嵌入式硬件
徐嵌4 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot
lantiandianzi4 小时前
基于单片机的老人生活安全监测系统
单片机·嵌入式硬件·生活
东胜物联4 小时前
探寻5G工业网关市场,5G工业网关品牌解析
人工智能·嵌入式硬件·5g
stm32发烧友4 小时前
基于STM32的智能家居环境监测系统设计
stm32·嵌入式硬件·智能家居
hairenjing112312 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word