锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

课设 stm32的8路电压表采集系统

时间:2023-01-09 23:30:00 cbb电容100v473k集成电路芯片lm565cn

基于stm32的8路电压表

  • 程序架构
  • 连接阿里云
    • 阿里云
    • wifi
    • mqtt
  • 电压采集
    • ADC
    • 分压电路
  • 声光报警
  • 数据存储
    • AT24C02
  • 供电

程序代码及PCB

程序架构

我们使用嵌入式实时系统UCOS III开发程序作为框架。
UCOS III资料:UCOSIII简介
在这里插入图片描述

声光报警 电压检测 串口屏 AT24C02 阿里云 等待电压值更新 更新上、下限 阻塞等待完成检测 完成8个通道检测 检测电压范围是否正常 完成检测,循环写AT24C02 同时,发送数据至串口屏 写入低8位,AT24C02需5ms处理 写入高8位,AT24C02需5ms处理 发布话题至阿里云,从而更新数据 进入阻塞,等待下一次检测完成 声光报警 电压检测 串口屏 AT24C02 阿里云

连接阿里云

阿里云

在本课设中,我们使用的是阿里云的物联网平台。阿里云物联网平台是一个集成了设备管理、数据安全通信和消息订阅等能力的一体化平台。向下支持连接海量设备,采集设备数据上云;向上提供云端API,服务端可通过调用云端API将指令下发至设备端,实现远程控制。
详细介绍:什么是物联网平台

wifi

WiFi模块使用ESP8266,型号为安信可的ESP-12S,使用AT指令配置相关的功能。
esp8266资料:安信可ESP8266简介
ESP8266有三种工作模式:
1.Station (客户端模式)模块相当于一个客户端,可以链接到其他路由器发出的WIFI信号。主要应用在网络通信中。
2.AP (接入点模式)模块本身相当于一个路由器,其他设备可链接到该模块发送的信号,主要应用在主从设备的主机部分。
3.Station+AP (两种模式共存)就是说模块可以当成一个设备(client)连接区域网内的路由,也可以设置成是一个路由(sever),也可以既作为局域网里面的client同时又是其他client的sever。
本课设中使用STA模式,并连接WiFi,AT指令配置如下

AT+CWMODE=1
AT+RST
AT+CWJAP="iQOO Z1x","12345678"

mqtt

MQTT(消息队列遥测传输) 是基于 TCP/IP 协议栈而构建的支持在各方之间异步通信的消息协议。MQTT在空间和时间上将消息发送者与接收者分离,因此可以在不可靠的网络环境中进行扩展。虽然叫做消息队列遥测传输,但它与消息队列毫无关系,而是使用了发布和订阅(Pub/Sub)的模型。
MQTT 是一种轻量级的、灵活的网络协议,致力于为 IoT 开发人员实现适当的平衡:

  1. 这个轻量级协议可在严重受限的设备硬件和高延迟/带宽有限的网络上实现。
  2. 它的灵活性使得为 IoT 设备和服务的多样化应用场景提供支持成为可能。

详细介绍:MQTT 入门介绍
使用AT指令连接阿里云
连接指令参考

AT+CIPSNTPCFG=1,8,"ntp1.aliyun.com"
AT+MQTTUSERCFG=0,1,"","","",0,0,""
AT+MQTTUSERNAME=0,"voltmeter&a1LF9tJmi7L"
AT+MQTTPASSWORD=0,"00D54361109FD2F1F4537F928C0CBB6EEA81E253"
AT+MQTTCLIENTID=0,"12345|securemode=3\,signmethod=hmacsha1\,timestamp=789|"
AT+MQTTCONN=0,"a1LF9tJmi7L.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,1

使用AT指令对阿里云发布话题

AT+MQTTPUB=0,"/sys/a1LF9tJmi7L/voltmeter/thing/event/property/post","{\"method\":\"thing.service.property.set\"\,\"id\":\"2012934115\"\,\"params\":{\"ch2\":4.7231}\,\"version\":\"1.0.0\"}",1,0

电压采集

ADC

我们所使用的stm32f411拥有1个ADC,12通道,其拥有12位的分辨率,对于3.3v,可以达到约0.00081v的精度。我们在程序中配置通道0-8进行测量,配置采样速率25MHz,每个规则序列中只包含一个通道,并配置连续扫描。
每次采样时会采集10个值,经过冒泡法排序后,去除最小、最大值,并计算平均值从而达到滤波的效果。

//排序
void my_sort(u16 *buf,u8 num)
{ 
        
	u8 i,j,flag=1;
	u16 k;
for(i=0;i<9;i++)
	{ 
        
		for(j=0;j<9-i;j++)
		{ 
        
			flag = 0;    //在内循环中设这个标记,如果没有发生互换,就设为0
			if(buf[j]>buf[j+1])
			{ 
        
				k = buf[j];
				buf[j] = buf[j+1];
				buf[j+1] = k;	
				flag = 1;	//发生互换就设为1 
			}				
		}		
		if(flag==0)//最后利用一个分支来始没有交换的时候跳出,这样可以减少计算次数
		{ 
        
			break;
		}
	}
}
//adc采集任务
static  void  ADC_task  ( void * p_arg )
{ 
        
	u16 buf[10];
	u8 i=0;
	OS_ERR err;
	while(1)
	{ 
        
		OSSemPend(&STAER_ADC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求ADC开始信号量 
		for(i=0;i<9;i++)//采集9个通道电压
		{ 
        
			Get_Adc(channel_list[i].ADC_channels,buf);
			my_sort(buf,10);
			channel_list[i].current=my_average(buf,1,8)/4096*3.3*10000;//转化为3.3V电压值
			if(i!=8)
				bouns_light(&channel_list[i]);
		}
		OSSemPost(&END_ADC_SEM,OS_OPT_POST_1,&err);//发送信号量 
		OSTimeDlyHMSM(0, 0, 0, 5, 0, &err);
	}
}

同时我们使用优质的LDO芯片XC6203为stm32及adc供电,保证了其基准电压的稳定。
stm32的adc详细介绍:STM32—ADC详解

分压电路

由于stm32的ADC只能测量0-3.3v电压,我们使用精密电阻(精度0.1%)进行分压,并且增加了一个100nf的电容稳定电压,从使8个通道的特性相差较小。分压电阻为1.2M和1M,经过分压,stm32可以测量0-6.05V电压

声光报警

蜂鸣器及LED

蜂鸣器

我们使用5V的有源蜂鸣器,保证了声音足够大。但是stm32无法输出5V电压,于是我们将IO口配置为开漏输出,通过上拉电阻实现5v输出。

void BEEP_init(void)
{ 
        
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT;
	//蜂鸣器配置开漏输出,使用上拉电阻输出5V
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	BEEP_OFF();


}

LED

我们通过相关的电路设计,实现通过stm321的一个IO口控制两个LED的亮灭。正常时,stm32的IO配置为高阻态,此时红灯、绿灯都不亮;超过上限,IO口配置为推挽输出、低电平,此时红灯亮;低于下限,IO配置为推挽输出、高电平,此时绿灯亮。

void LED_set(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pinx,unsigned char state)
{ 
        
	GPIO_InitTypeDef GPIO_InitStructure;
  
  if(state==0)//两个灯都不亮
	{ 
        
		GPIO_InitStructure.GPIO_Pin = GPIO_Pinx;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//高阻态
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
		GPIO_Init(GPIOx, &GPIO_InitStructure);
	}
	else if(state==1)//下侧亮
	{ 
        
		GPIO_InitStructure.GPIO_Pin = GPIO_Pinx;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
		GPIO_Init(GPIOx, &GPIO_InitStructure);	
		GPIO_SetBits(GPIOx,GPIO_Pinx);//置为高电平
	}
	else if(state==2)//下侧亮
	{ 
        
		GPIO_InitStructure.GPIO_Pin = GPIO_Pinx;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
		GPIO_Init(GPIOx, &GPIO_InitStructure);	
		GPIO_ResetBits(GPIOx,GPIO_Pinx);//置为低电平
	}
	
}

串口屏

电压值的显示及上、下限的设置,我们使用串口屏,通过上位机制作其显示的界面并烧录。通过串口屏,我们可以设置相关的上下限、查看当前值及掉电保存的值。并且通过串口于stm32通讯

数据存储

AT24C02

尽管stm32用于内部flash,当时由于其读写寿命只有1万次左右。而我们的课设中以10Hz的速度更新9个通道值,每个电压值对应的存储块每秒读写就有10次,一分钟就有600次,所以我们选择EEPROM作为存储介质,AT24C02拥有30万次的读写寿命,再通过均衡读写,就可以实现课设的要求。
详细介绍:AT24C02
存储器FLASH,EEPROM介绍:FLASH和EEPROM的区别


static  void  AT24C02_task  ( void * p_arg )
{ 
        
	OS_ERR err;
	u16 temp=0;
	u8 i=0;
	while(1)
	{ 
        
		OSSemPend(&END_ADC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量 
		for(i=0;i<9;i++)
		{ 
        
			temp=channel_list[i].current;
			screen_send_value(channel_list[i].screen_name_current,temp);
			AT24CXX_WriteOneByte(channel_list[i].AT24C02_Palce,temp%256);//写入低字节
			OSTimeDlyHMSM(0, 0, 0, 5, 0, &err);
			AT24CXX_WriteOneByte(channel_list[i].AT24C02_Palce+1,temp/256);//写入高字节
			OSTimeDlyHMSM(0, 0, 0, 5, 0, &err);
		}
		if(ch>0)
		{ 
        
			temp=channel_list[ch-1].current;
			screen_send_value("chnael.x0.val",temp);	
		}		
		OSSemPost(&STAER_ADC_SEM,OS_OPT_POST_1,&err);//发送信号量 
	}
}

供电

供电一开始我们选择使用AMS117,将12V降至5v,但压差过大,AMS117发热较大,无法正常使用。或许可以考虑使用7805或LM2956进行压降。不过我们后来想了一下,不如直接用5V供电。至于stm32的3.3v供电,我们使用了LDO芯片XC6204

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章