打印
[STM32F1]

关于传感器的数据解析

[复制链接]
3338|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

请教各位大师:
1. 如何解析PM2.5传感器感知的数据?数据见上图
2. 关于编程,我需要编写哪些可实现该传感器和MCU通信的函数;
PS:现已看过该款传感器的通信方式,有看过相关通信方式的视频教程,但小弟没有开发经验,请各位大师指教。
沙发
买醉的显示器|  楼主 | 2017-1-11 17:01 | 只看该作者
多谢诸位大师,问题一已经解决了;
第二条,关于之间的通信函数,系统时钟是必须要配置的吗?

使用特权

评论回复
板凳
gejigeji521| | 2017-1-11 23:23 | 只看该作者
你的传感器是什么接口的啊,串口还是SPI,还是IIC啊?

使用特权

评论回复
地板
gejigeji521| | 2017-1-11 23:24 | 只看该作者
你如果是串口的,就用单片机串口跟它对接,如果是SPI,就用SPI接口,I2C以此类推。

使用特权

评论回复
5
买醉的显示器|  楼主 | 2017-1-12 16:09 | 只看该作者
gejigeji521 发表于 2017-1-11 23:24
你如果是串口的,就用单片机串口跟它对接,如果是SPI,就用SPI接口,I2C以此类推。 ...

感谢您的指点
我选的接口是串口
目标:就是将感知的PM2.5数据显示到LCD屏幕上;
问题:请问这中间具体需要做什么?

使用特权

评论回复
6
wahahaheihei| | 2017-1-12 16:14 | 只看该作者
就是调试好串口程序,然后按照协议读取,读取后另外一个工作就是调试捅LCD,能显示字符就行,然后将读取的数据输出到LCD上。楼主果然新手啊。。

使用特权

评论回复
7
买醉的显示器|  楼主 | 2017-1-12 16:46 | 只看该作者
wahahaheihei 发表于 2017-1-12 16:14
就是调试好串口程序,然后按照协议读取,读取后另外一个工作就是调试捅LCD,能显示字符就行,然后将读取的 ...

感谢您的回复
您说的路数,我大概也知道,只是再具体点,我就不懂了;
有以下想跟大师确认的问题,还请大师指点:
1. 您说的调试好串口程序,串口程序是指自己编写的uart.c?
2. 您说的按照协议读取,也就是说按照RX/TX的传输模式?
3. 对于您说的调试通LCD,这里有一个问题就是,如何将所要显示的汉字、符号显示到LCD上?

使用特权

评论回复
8
wahahaheihei| | 2017-1-12 18:49 | 只看该作者
你说你用的什么单片机吧,什么样的LCD,简单的LCD就是LCD1602,每行可以显示16个字符,一共两行,这个最简单,网上例子多,论坛搜一下,一堆。再确定你用的单片机型号,然后找相关的串口例子看看。

使用特权

评论回复
9
买醉的显示器|  楼主 | 2017-1-12 20:00 | 只看该作者
wahahaheihei 发表于 2017-1-12 18:49
你说你用的什么单片机吧,什么样的LCD,简单的LCD就是LCD1602,每行可以显示16个字符,一共两行,这个最简单 ...

stm32f103

使用特权

评论回复
10
wahahaheihei| | 2017-1-13 20:17 | 只看该作者
PM2.5芯片是什么型号的?

使用特权

评论回复
11
wahahaheihei| | 2017-1-13 20:18 | 只看该作者
2、STM32跟PC机(也就是电脑)如何连接
       我的STM32F103C8T6只是裸板,没有串口芯片,当然用的也是学生机——笔记本电脑,同样也没串口。
解决办法1、买一块 MAX3232转接板+一条USB转串口线 +邮费=30块左右
              2、只需要买一块PL2303的USB转接板。这样就将第一种的转接板和连接结合到一起了。
不过我用的是第一种,MAX3232+USB的串口线  ,为什么不用方便的2种?
max3232对于没有串口的开发板可以充当电平转换芯片,如何开发板有了电平转换芯片,我便使用USB转串口线经行连接,这样便灵活了。第二种只是用在既没转换芯片也没USB转串口的情况,不过对于最小系统板来说,它既可以下载程序,又可以当做串口来调试。至于台式机就不需要USB转串口线了,普通串口线即可。
                连接示意如下所示:

使用特权

评论回复
12
wahahaheihei| | 2017-1-13 20:19 | 只看该作者
2、STM32跟PC机(也就是电脑)如何连接
       我的STM32F103C8T6只是裸板,没有串口芯片,当然用的也是学生机——笔记本电脑,同样也没串口。
解决办法1、买一块 MAX3232转接板+一条USB转串口线 +邮费=30块左右
              2、只需要买一块PL2303的USB转接板。这样就将第一种的转接板和连接结合到一起了。
不过我用的是第一种,MAX3232+USB的串口线  ,为什么不用方便的2种?
max3232对于没有串口的开发板可以充当电平转换芯片,如何开发板有了电平转换芯片,我便使用USB转串口线经行连接,这样便灵活了。第二种只是用在既没转换芯片也没USB转串口的情况,不过对于最小系统板来说,它既可以下载程序,又可以当做串口来调试。至于台式机就不需要USB转串口线了,普通串口线即可。
                连接示意如下所示:

另外如果你有一块STM32官方的Nucleo开发板,上面一般带USB转串口的功能的。

46919191681017.jpg (32.59 KB )

46919191681017.jpg

使用特权

评论回复
13
wahahaheihei| | 2017-1-13 20:20 | 只看该作者
2、STM32跟PC机(也就是电脑)如何连接
       我的STM32F103C8T6只是裸板,没有串口芯片,当然用的也是学生机——笔记本电脑,同样也没串口。
解决办法1、买一块 MAX3232转接板+一条USB转串口线 +邮费=30块左右
              2、只需要买一块PL2303的USB转接板。这样就将第一种的转接板和连接结合到一起了。
不过我用的是第一种,MAX3232+USB的串口线  ,为什么不用方便的2种?
max3232对于没有串口的开发板可以充当电平转换芯片,如何开发板有了电平转换芯片,我便使用USB转串口线经行连接,这样便灵活了。第二种只是用在既没转换芯片也没USB转串口的情况,不过对于最小系统板来说,它既可以下载程序,又可以当做串口来调试。至于台式机就不需要USB转串口线了,普通串口线即可。
                连接示意如下所示:
如果你有一个STM32官方的Nucleo开发板上面有USB转串口的功能。

使用特权

评论回复
14
wahahaheihei| | 2017-1-13 20:21 | 只看该作者
代码分析
       再写这里之前,应该已经学过模块化编程了,STM32的每个XXX.c 和xxx.h 这都是模块化编程。良好的程序,与其好的代码风格有关。你的代码风格跟你接触教你写代码的有很大关系。以前刚刚学习单片机编程,我还不信,现在我承认,跟教我单片机的老师风格有些像。
这里我做的是一个串口发送数据到PC机的例子:
       要让STM32能够顺利发出数据,要进行如下配置
PA9,PA10管脚要配置,   USART也需要配置波特率,数据有几位,停止位,数据流等。
USART和uart有什么区别   USART在做串口时,两者并不区别,但是USART有SPI的功能。还有串口通信为什么要配置波特率,停止位,硬件数据留这些,以前我也没想过,现在只觉得协议这个东西,是一个好的标准。
        建立一个usart_debug.c的文本,内容如下
#include"usart_debug.h"
void GPIO_Configuration(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能UASRT的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA的时钟,开始的时候,我没用这句话,调了两天,跟源码一句一句比才知道
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; //波特率较高,IO翻转需较高频率
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出;我看网上有人说设置成GPIO_Mode_Out_PP普通推挽输出也行,但实践出真知,我试了发送是乱码。;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置成浮空输入,既然是输入所以就不用配置IO口的频率了
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void USART1_config(void)
{
USART_InitTypeDef     USART_InitStructure;
USART_InitStructure.USART_BaudRate= 115200;     //配置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //配置数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1;      //停止位
USART_InitStructure.USART_Parity= USART_Parity_No ;         //奇偶校验位
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //硬件流
USART_InitStructure.USART_Mode =USART_Mode_Rx |USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
//这段很重要,如果要使用printf函数打印信息,需要加fputc函数,就需要对printf函数重定向到串口,以前工作中他们老是提重定向,什么串口重定向,USB重定向什么的,我也是云里雾里,如今给我的感觉就是将上层函数实现对底层硬件的操作
int  fputc(int ch,  FILE*f){
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); //网上的一些函数里面是没有这一句代码,如果不加的话,打印时第一个字符就会没有,原因据说是硬件复位后,USART_FLAG_TC被置一了,而要发送数据必须让其为底才可以,一表示数据发送发出的标志,也可以用这样一句USART_ClearFlag(USART2,USART_FLAG_TC);清楚标准位。可是我没这样做一样发成功了,这个疑惑以后再想明白。
USART_SendData(USART1, (uint16_t)ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET);
return ch;
}
void usart_debug_config(void)  //提供给main函数调用的串口配置函数
{
GPIO_Configuration(); //IO口配置
USART1_config();   //串口配置
}
还就是usart_debug.h
#ifndef __usart_debug_H
#define    __usart_debug_H
#include "stm32f10x.h"
#include
void usart_debug_config(void);
int fputc(int ch, FILE *f);
#endif // __USART1_H
       main函数:
这里使用两种方式一种是 使用普通的方式发送,另一种使用printf函数
其实还有一种USART_printf函数来实现,这里不做介绍。有空看看区别一下printf和usart_printf,据说是支持格式多少的问题
#include"stm32f10x.h"
#include"usart_debug.h" //包含main函数里的调用函数
int main(void)
{
unsigned char TxBuf1[100] ={"发送字符串!!!"};
int  i;
SystemInit();
usart_debug_config();
for( i = 0; TxBuf1 != ''; i++)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);//这里跟分析fputc时是一样的
USART_SendData(USART1 , TxBuf1);//发送字符数组里的单个字符
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}
printf("hello world!  世界你好! "); //调用printf函数
while(1)
{
;
}
}

46919191681017.jpg (32.59 KB )

46919191681017.jpg

使用特权

评论回复
15
wahahaheihei| | 2017-1-13 20:22 | 只看该作者
仿真及调试
程序编好之后,在target option里要选择 USE microLIB (keil自带的微库),这是使用非标准C库,在编译链接是,将我们编写的fputc函数作为编译的首选,否则就会编译stdio.h里的fputc函数。
写到这里我发现我这个代码感觉不是很好,使用微库而不用标准C库,应该会有影响,我瞬间就明白了他们为什么要自己编写支持输出格式很少的的USART_printf函数了,后面目测我也会使用这个函数。
一个好的程序代码就是结构健全,BUG很少。把简单做到极致
在KEIL里继续软件仿真
仿真和下载时要注意的是,仿真要选USE Simulation  而下载要选右边的JTAG。。。。
然后点击debug 进入调试界面
view--->serial windos -->UART 1
全速运行 其结果如下:
串口发送数据就到此为止。

使用特权

评论回复
16
wahahaheihei| | 2017-1-13 20:23 | 只看该作者
串口接收数据
这儿写的跟上面的已经没有关系了,不要搞混。
关于从PC机发送数据到STM32,这一部分则需要中断来实现,因为我们不需要时时刻刻都来检测外部是否发出数据给STM32,因此只要有数据来,就触发中断。这里就需要配置NVIC了
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //优先组为2
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  //打开USART中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;          //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //中断通道使能
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    //串口接收中断使能
USART_Cmd(USART1, ENABLE);
}
其他配置比如串口复用到IO配置,串口时钟配置,和发送数据是一样的。
串口中断处理函数:
void USART1_IRQHandler(void)
{  int RX_status;  //自己定义一个标志位
RX_status = USART_GetFlagStatus(USART1, USART_FLAG_RXNE);//读取接收数据标志位,如果装好了一帧数据则硬件将其置一。
if(RX_status == SET) {
USART_SendData(USART1 , USART_ReceiveData(USART1));//将收到的数据再由STM32发送给PC机。
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);//等待发送完成。
}
}
       串口的发送接收大致如此,还是要搞懂什么数据位,硬件流,停止位,校验位什么,一个东西既然出现了就要好好分析出现的意义。想到了今天给电脑拆机清灰,电脑最好两年清一次。反正每次上螺丝都会多出那么一两个来,是不是可以不用要?
       肯定不是,生产商肯定也知道节约成本什么,他们的结构工程师也知道PCB上开一个螺丝孔也是要收钱的。所以每一颗螺丝都有它的意义,所以什么校验位,停止位也有他的意义,即便我们不使用。其实剩的螺丝我也扔了,完全不知道上在哪儿!

使用特权

评论回复
17
wahahaheihei| | 2017-1-13 20:24 | 只看该作者
串口发送数据     百度云盘:http://pan.baidu.com/s/1i3kj31N
串口发送接收数据  百度云盘:http://pan.baidu.com/s/1o6r0OIY

使用特权

评论回复
18
买醉的显示器|  楼主 | 2017-1-14 14:44 | 只看该作者
wahahaheihei 发表于 2017-1-13 20:17
PM2.5芯片是什么型号的?

PMS5003ST

使用特权

评论回复
19
买醉的显示器|  楼主 | 2017-1-14 15:06 | 只看该作者
wahahaheihei 发表于 2017-1-13 20:24
串口发送数据     百度云盘:http://pan.baidu.com/s/1i3kj31N串口发送接收数据  百度云盘:ht ...

大师 您好
非常感谢您对UART的解释,我试了您分享的网盘资料时,
出现这个错误,请问您用的是哪个版本?
我用的是keil4.72;  MCU:stm32f103ze  传感器型号:PMS5003ST  LCD是tft的

再次表示对您的感谢。

使用特权

评论回复
20
买醉的显示器|  楼主 | 2017-1-14 15:48 | 只看该作者
wahahaheihei 发表于 2017-1-13 20:23
串口接收数据这儿写的跟上面的已经没有关系了,不要搞混。关于从PC机发送数据到STM32,这一部 ...

我不太懂void NVIC_Config(void) 这个函数是做什么用的?
在很多例程里,有见过如您所编写NVIC这段代码,虽然知道和中断有关,但仅仅是知道而已,依然云里雾里。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

27

帖子

1

粉丝