找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2507|回复: 1
打印 上一主题 下一主题
收起左侧

stm32多路巡回数据采集系统设计 含源程序

[复制链接]
跳转到指定楼层
楼主
ID:425104 发表于 2020-2-22 10:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

此次设计是利用stm32开发板设计的。数据采集系统是模拟域与数字域之间必不可少的纽带,它的存在具有着非常重要的作用。本文介绍的重点是数据采集系统,而该系统硬件部分的重心在于单片机芯片。数据采集与通信控制采用了模块化的设计,数据采集与通信控制采用了单片机STM32来实现,硬件部分是以单片机为核心,还包括A/D模数转换模块,显示模块。该系统从机负责数据采集并应答主机的命令。输入数据是由模拟信号产生器产生,实现对采集到的数据进行模拟量到数字量的转换,并用TFTLCD来显示所采集的结果。软件部分应用C语言编写控制软件,对数据采集系统、模数转换系统、数据显示、数据通信等程序进行了设计。

2 总体方案设计

多路巡回数据采集仪设计需要将模拟量转换为数字量,而 A/D是将模拟量转换为数字量的器件,STM32单片机是该系统的基本的微处理系统,它完成数据读取、处理及逻辑控制、数据传输、数据转换等一系列的任务,然后通过控制液晶屏显示。

数据采集系统不仅需要硬件设置,还需要软件的相应配置才能调试好硬件,使系统正常工作。硬件电路的调试与硬件设计和软件配置息息相关。系统的硬件包括STM32核心板、液晶屏显示、数据采集电路等。


图1 系统框图


此多路巡回数据采集仪的设计采用的是红外传感器,烟雾传感器,利用二个模块分别检测外围环境的变化,通过最后采集的数据来反映不同环境下的数据的不同。

3 硬件设计

3.1 各个模块的实现

  3.1.1 红外对管传感器

TCRT5000传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态;被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,此时模块的输出端为低电平,指示二极管被点亮。模拟输出AO当发射管的红外信号经反射被接收管接收后,接收管的电阻会发生变化,在电路上一般以电压的变化形式体现出来,而经过ADC转换或LM324等电路整形后得到处理后的输出结果。电阻的变化起取于接收管所接收的红外信号强度,常表现在反射面的颜色(反射率)、形状和反射面接收管的距离等方面。

图3.1.1 红外对管传感器原理图
3.1.2 烟雾传感器

       MQ-2型烟雾传感器属于二氧化锡半导体气敏材料,属于表面离子式N型半导体。处于200~300摄氏度时,二氧化锡吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,从而使其电阻值增加。当与烟雾接触时,如果晶粒间界处的势垒收到烟雾的调至而变化,就会引起表面导电率的变化。利用这一点就可以获得这种烟雾存在的信息,烟雾的浓度越大,导电率越大,输出电阻越低,则输出的模拟信号就越大。

图3.1.2 烟雾传感器原理图

3.2 显示部分

本次设计采用的为TFT型液晶屏,TFT型的液晶显示器较为复杂,主要的构成包括了荧光管、导光板、偏光板、滤光板、玻璃基板、配向膜、液晶材料、薄模式晶体管等等。首先液晶显示器必须先利用背光源,也就是荧光灯管投射出光源,这些光源会先经过一个偏光板然后再经过液晶,这时液晶分子的排列方式进而改变穿透液晶的光线角度。然后这些光线接下来还必须经过前方的彩色的滤光膜与另一块偏光板。因此我们只要改变刺激液晶的电压值就可以控制最后出现的光线强度与色彩,并进而能在液晶面板上变化出有不同深浅的颜色组合了。

本次设计还有一个就是设置屏幕的背景图,采用的是320*240的分辨率进行图片采样,利用图片转化软件对选中的图片进行采点,然后转化成16进制的数字,然后放到库里面,需要用的时候直接调用就可以了。




图3.2 利用Img2Lcd软件进行代码生成
4 软件设计

4.1 整体设计框图

本软件系统是基于STM32的库函数下进行的编程。需要对库函数进行调用并对相应的函数进行初始化。然后对采集的模拟信号进行转换,通过对波特率的调整,对信号进行实时检测,然后通过均值滤波,控制液晶显示屏显示最终得到的结果。

其具体架构如图:


            
(a)主程序流程图





4.2 ADC采样

   4.2.1 ADC原理

由于STM32自带ADC模块,所以只需要对其进行配置就可使用。12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

本次设计采用了四路AD采样ADC1-GPIOA1,ADC2-GPIOA2,ADC3-GPIOA3,ADC4-GPIOA4;利用四组不同的传感器对环境的检测,当达到对应的阈值时,控制相对应的器件。

图4.2.5 ADC的时序图

5系统调试
首先,将电路连接好如图正常工作,adc1为4095,
然后将红外传感器遮住,adc1变小为177

图5.2调试
调试完成,正常工作。
6总结

STM32芯片具有非常强大的功能,还有非常全面的库函数,应用起来非常方便。此次设计在最开始的时候我们遇到了很多的问题,不知道如何使用ADC采集但是后来通过小组的努力共同查阅资料和向实验室的同学请教对ADC有了一定的了解,顺利的完成了课设。在过程中也遇到了许多的问题,比如在使用开发板时接线的时候要细心,不能够接错线,在程序编写的时候要查阅很多资料和借鉴资料,遇到问题要善于查阅资料找解决办法等等。不过最终一一克服困难顺利完成设计,实现了多路巡回数据采集设计。通过本次的设计对32有了更深刻的理解,提高了我们同学之间的团队合作能力与实践能力。


单片机源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "lcd.h"
  6. #include "ds18b20.h"
  7. #include "image2lcd.h"
  8. #include "adc.h"

  9. extern const u8 gImage_image1[];//图片数据(包含信息头),存储在image1.c里面.
  10. int main(void)
  11. {
  12.               u8 t=0;            
  13.             
  14.                             u16 adcx1,adcx2;
  15.               float temp;
  16.             
  17.                 HEADCOLOR *imginfo;            
  18.               short temperature;  
  19.               delay_init();                                //延时函数初始化               
  20.               uart_init(9600);                            //串口初始化为9600
  21.               LED_Init();                                                          //初始化与LED连接的硬件接口
  22.               LCD_Init();
  23.                               Adc_Init();                                                          //ADC初始化            
  24.   LCD_Fill(0,0,470,350,WHITE);
  25.               srand(imginfo->h*imginfo->w);
  26.               image_display(0,0,(u8*)gImage_image1);//在指定地址显示图片
  27.             

  28.               while(DS18B20_Init())              //DS18B20初始化            
  29.               {
  30.                             LCD_ShowString(60,190,200,16,16,"DS18B20 Error");
  31.                             delay_ms(200);
  32.                  LCD_ShowString(60,210,200,16,16,"Temp:   . C");                                         
  33.               }                           

  34.               POINT_COLOR=BLUE;//设置字体为蓝色   
  35.               LCD_ShowString(60,190,200,16,16,"DS18B20 OK");
  36.               LCD_ShowString(60,210,200,16,16,"Temp:   . C");            
  37.             
  38.               POINT_COLOR=BLUE;//设置字体为蓝色
  39.               LCD_ShowString(60,230,200,16,16,"ADC1:");//倾倒
  40.               LCD_ShowString(60,270,200,16,16,"ADC2:");//红外
  41.             
  42.               POINT_COLOR=RED;//设置字体为红色
  43.   LCD_ShowString(120,250,48,16,16,"0.000V");
  44.   LCD_ShowString(120,290,48,16,16,"0.000V");
  45.             
  46.               while(1)
  47.               {            

  48.                             adcx1=Get_Adc_Average(ADC_Channel_1,10);//ADC1烟雾传感器                            adcx2=Get_Adc_Average(ADC_Channel_2,10);//ADC2红外传感器
  49.                            
  50.                             POINT_COLOR=RED;//设置字体为红色
  51.                             LCD_ShowxNum(120,230,adcx1,4,16,0);//显示ADC的值
  52.                             LCD_ShowxNum(120,270,adcx2,4,16,0);//显示ADC的值
  53.                            
  54.                             //第一个ADC转换为电压值
  55.                             temp=(float)adcx1*(3.3/4096);
  56.                             adcx1=temp;
  57.                             LCD_ShowxNum(120,250,adcx1,1,16,0);//显示电压值
  58.             
  59.                             //第二个ADC转换为电压值
  60.                             temp=(float)adcx2*(3.3/4096);
  61.                             adcx2=temp;
  62.                             LCD_ShowxNum(120,290,adcx2,1,16,0);//显示电压值

  63.                            
  64.                            
  65.                             if(t%10==0)//每100ms读取一次
  66.                             {                                                                                                                              
  67.                                           temperature=DS18B20_Get_Temp();            
  68.                                           if(temperature<0)
  69.                                           {
  70.                                                         LCD_ShowChar(60+40,210,'-',16,0);                                          //显示负号
  71.                                                         temperature=-temperature;                                                                      //转为正数
  72.                                           }
  73.                                           else
  74.                                                         LCD_ShowChar(60+40,210,' ',16,0);                                          //去掉负号
  75.                                             LCD_ShowNum(60+40+8,210,temperature/10,2,16);              //显示正数部分                 
  76.                                              LCD_ShowNum(60+40+32,210,temperature%10,1,16);              //显示小数部分                              
  77.                             }                                                         
  78.                             delay_ms(10);
  79.                             t++;
  80.               }
  81. }
复制代码

全部资料51hei下载地址:
源程序.7z (280.16 KB, 下载次数: 31)
文档.doc (286.5 KB, 下载次数: 25)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:59738 发表于 2023-11-21 10:54 | 只看该作者
感谢楼主分享  能帮我很好的开拓思路
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表