stm32单片机使用串口通信连接GY-33颜色传感器完成对颜色的识别并且打印出其颜色和对应的RGB值
目录
1.GY-33介绍及其接线
2.通信原理
3.代码
4.GY-33发送出来的数据及如何处理数据
5.软件使用
所需:stm32单片机(这里使用的是正点原子stm32mini板),GY_33传感器,GY_33配套软件,串口助手,USB转TTL
1.GY-33介绍及其接线
GY-33是一款低成本颜色识别传感器模块。工作电压3-5v,功耗小,体积小,安装方便。其工作原理是,照明LED发光,照射到被测物体后,返回光经过滤镜检测RGB的比例值,根据RGB的比例值识别出颜色。此模块,有两种方式读取数据,即串口UART(TTL电平)或者IIC(2线)。串口的波特率有9600bps与115200bps,可配置,有连续,询问输出两种方式,其响应频率为10hz。具体资料查看
http://pan.baidu.com/s/1kVq51dl
先来看看GY-33的实物及其接线
我们只需要焊接排针在这四位上,然后用杜邦线把这四位同stm32对应的引脚连接即可,由于我设置GY-33通过串口3同stm32通信 ,根据原理图DR应该连接PB10,CT应该连接PB11
2.通信原理
首先我们得先了解GY-33是怎么通过stm32和上位机完成通信的(这一步至关重要,如果连这个过程是怎样进行的都不知道,那就像无头苍蝇,永远完成不了这个功能)--------------
思路是1. 上位机通过串口1发送指令到stm32 2.stm32再通过串口3把指令发到GY-33颜色传感器 3.GY-33接受到指令后会自动输出其测量的颜色对应的数据(第四部分会讲数据类型及数据处理)回串口3 4.串口3接受到数据后中断,我们可以在串口3中断函数里对数据进行处理,从而提取出RGB值并打印出对应的颜色和RGB值
(文字看着腻歪,直接看下图通信思路及实现方法)
3.代码
先看看串口的通信协议
程序应该按通信协议设置
话不多说,直接上代码(看串口3中断函数代码前可以先看第四部分)
#include "stm32f10x.h"
#include "stdio.h"//printf函数void USART1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体USART_InitTypeDef USART_InitStructure;//定义串口结构体NVIC_InitTypeDef NVIC_InitStructure;//定义优先级结构体//使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOARCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//使能串口1//发送TXGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根据GY-33响应频率10hzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA//接收RXGPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根据GY-33响应频率10hzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA//串口USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件USART_InitStructure.USART_BaudRate=9600;//波特率USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//模式USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity=USART_Parity_No;//奇偶校验关闭USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长USART_Init(USART1,&USART_InitStructure);//初始化串口1//优先级配置NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中断NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能串口1中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应优先级NVIC_Init(&NVIC_InitStructure);//初始化优先级//使能USART_Cmd(USART1,ENABLE);//使能串口1USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能接收缓存非空寄存器
}
void USART3_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体USART_InitTypeDef USART_InitStructure;//定义串口结构体NVIC_InitTypeDef NVIC_InitStructure;//定义优先级结构体//使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOBRCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 ,ENABLE);//使能串口3//发送TXGPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PB10GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根据GY-33响应频率10hzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB//接收RXGPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//PB11GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB//串口USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件USART_InitStructure.USART_BaudRate=9600;//波特率USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//模式USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity=USART_Parity_No;//奇偶校验关闭USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长USART_Init(USART3,&USART_InitStructure);//初始化串口3//优先级配置NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;//串口3中断NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能串口3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应优先级NVIC_Init(&NVIC_InitStructure);//初始化优先级//使能USART_Cmd(USART3,ENABLE);//使能串口3USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//使能接收缓存非空寄存器
}
void USART1_IRQHandler ()//串口1中断
{if(USART_GetITStatus(USART1,USART_IT_RXNE))//如果接收到数据{ u8 data;data=USART_ReceiveData(USART1);//保存指令 USART_SendData(USART3,data);//串口3发送指令给传感器}
}
void USART3_IRQHandler()
{if(USART_GetITStatus(USART3,USART_IT_RXNE))//如果接收到数据{u8 data;static int result1,result2,result3;//静态保存static int i=0,staus=0,j=0,staus2=0,temp1=0,temp2=0,temp3=0;data=USART_ReceiveData(USART3);//赋值 if(data==0x5A)staus2=1;if(staus2){j++;if(j==1)temp1=data;if(j==2)temp2=data;if(j==3){temp3=data;j=0;if(temp3==0x45&&temp2==0x5A&&temp1==0X5A){staus2=0;staus=1;}}}//如果连续收到0x5a,0x5a,0x45,staus置1,进入下面数据处理if (staus)//将0x45看成第一位数据,保存第三,四,五位数据,分别对应红,绿,蓝的RGB值{i++;if(i==3)result1=USART_ReceiveData(USART3);if(i==4)result2=USART_ReceiveData(USART3);if(i==5){result3=USART_ReceiveData(USART3);if(result1==255&&result2==255&&result3==255)//三者RGB值都为255即打印白色printf("R=%d G=%d B=%d 白色\r\n",result1,result2,result3);if(result1<50&&result2<50&&result3<50)//三者RGB值都比较小即为黑色printf("R=%d G=%d B=%d 黑色\r\n",result1,result2,result3);else{if(result1>result2&&result1>result3)//不符合三者RGB都大或都小的情况下,红色RGB值最大即打印红色printf("R=%d G=%d B=%d 红色\r\n",result1,result2,result3);if(result2>result1&&result2>result3)//不符合三者RGB都大或都小的情况下,绿色RGB值最大即打印绿色printf("R=%d G=%d B=%d 绿色\r\n",result1,result2,result3);if(result3>result2&&result1<result3)//不符合三者RGB都大或都小的情况下,蓝色RGB值最大即打印蓝色printf("R=%d G=%d B=%d 蓝色\r\n",result1,result2,result3);}i=0;staus=0;}}
}
}
int main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);USART1_Init();USART3_Init();while(1);
}
#if 1//调用printf函数所需代码
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
4.GY-33发送出来的数据及如何处理数据
一共有三种不同的数据类型(0x15,0x25,0x45),每种数据都是以俩个0x5a开头(帧头)
GY-33发给串口3的数据由这三种不同的数据类型组成,例如5A 5A 15 08 01 78 01 92 00 4C 05 05 33 5A 5A 25 06 02 CC 0C 5D 00 02 18 5A 5A 45 03 FF F 4C 46 5A 5A 15 08 01 78 01 92 00 4C 05 05 33 5A 5A 25 06 02 CC 0C 5D 00 02 18 5A 5A 45 03 FF F 4C 46(不同数据类型用不同颜色)
并且每一种类型的数据所含数字的个数不同(每串数据的第四位数表示这串数据的有效数据个数,同种数据类型数字个数相同),我们需要选择一种数据类型来处理,这里我们就选择最简单的第三种数据进行处理吧
处理方法:首先得判断是第三种数据(依次接收到的数据是0x5a,0x5a,0x45)//若再判断下一位为0x03会更好,然后再把第三种数据的第五,六,七位取出来并打印(具体处理方法查看上面的代码) 其他俩种数据类型根据上面表格也可处理,处理方法与第三种数据类型类似
5.软件使用
在使用GY-33颜色传感器前,得先对其进行颜色白校准(使用COLOR,USA转ttl)usb转ttl直接连传感器,通过COLOR软件直接配置GY-33
白校准后打开xcom(注:16进制发送勾选上,波特率停止位等配置按如下)
打开串口就可以接收到打印的数据了
完成此次任务,我发现对信息的筛选及整合能力很关键,最重要的应该是先搞明白原理。
stm32单片机使用串口通信连接GY-33颜色传感器完成对颜色的识别并且打印出其颜色和对应的RGB值相关推荐
- 22.从零开始开发QT软件思路(单片机的串口通信)-- OpenCV从零开始到图像(人脸 + 物体)识别系列
本文作者:小嗷 微信公众号:aoxiaoji 吹比QQ群:736854977 链接:https://mp.weixin.qq.com/s?__biz=MzU1MTgxNjQyMg==&temp ...
- stm32单片机通过串口通信实现将GY_33颜色传感器的接收到的颜色和RGB值上传给上位机
目录 硬件连接 实现串口1和串口3相互通信 GY_33的概述 对GY_33的数据分析 GY_33数据处理 GY_33的配套软件使用 代码 主要思路:注:这里我使用串口1和串口3,可以更改串口 ...
- Proteus仿真stm32和51单片机,串口通信调试过程记录
前言 本文所用Proteus版本为8.10,主要内容为在Proteus中仿真stm32和51单片机进行串口通信,记录了仿真过程中遇到的问题和解决办法. 这里要注意的是,在Proteus中 ...
- labVIEW与单片机实现串口通信的设计过程
1.概述 在现代测控系统中,我们经常会采用上位机和下位机的开发控制模式.下位机主要是用来采集数据,可以通过嵌入式控制器.单片机控制器.PLC等来实现.上位机主要是图形界面,用来实时显示采集数据,并进行 ...
- Ardunio 完成STM32板子的串口通信
目录 一.Ardunio简介 二.Ardunio配置 三.实验 四.其它 实验目的: 安装 Ardunio IDE 和相关软件支持库,在Ardunio 上完成STM32板子的串口通信程序:持续向串口输 ...
- MATLAB与51单片机进行串口通信详解
目录 一.51单片机与电脑进行串口通信 二.MATLAB串口通信函数 三.串口属性 四.示例Demo 4.1 MATLAB接收单片机发来的数据 4.2 MATLAB向单片机发送数据控制LED 五.总结 ...
- arm linux串口控制led,通信程序设计 - Linux下ARM和单片机的串口通信设计
3 通信程序设计 ARM 与单片机的串口通信程序包括两方面: 一方面是作为上位机的ARM 的串口通信程序,另一方面是作为下位机的单片机的串口通信程序.在通信之前必须制定合理的通信协议以保证通信的可靠性 ...
- STM32和ROS串口通信常见问题汇总答疑
STM32和ROS串口通信常见问题汇总答疑 大家好,我是白茶清欢,最近看了博客文章<stm32和ros的串口通信>有很多问题的评论,这里汇总回复一下. 问题1:运行时报错如下: rosru ...
- 51单片机stc15w204s串口通信发数据接收数据串口中断发中文字符串完美运行软件延时发送一字节函数全注释
这里写自定义目录标题 KEIL自己先调试通了然后再说下面的事 51单片机stc15w204s串口通信直接上文件 KEIL自己先调试通了然后再说下面的自己看看就可 KEIL自己先调试通了然后再说下面的事 ...
最新文章
- Sqlite3支持的数据类型 日期函数 Sqlite3 函数
- 原创 | 从智慧交通、智慧安防、智能电网三大应用场景看我国智慧城市建设现状...
- unity meta文件
- 计算机网络技术在农业中的应用,计算机网络技术在农业节水灌溉系统中的运用——评《计算机网络技术与应用实践》...
- 代码覆盖率工具 Istanbul 入门教程
- 5年 Python 功力,总结了 10 个开发技巧
- go-zero:开箱即用的微服务框架
- 【系统架构设计师】2020-08-05
- php.ini 安全配置
- c#中高效的excel导入oracle的方法
- PCB 电测试--测试点数自动输出到流程指示中(读取TGZ Stephdr文件)
- python的Singleton模式实现
- SLAM学习笔记-------------(九)后端1
- Android第九天
- 【HDU6704】K-th occurrence(后缀数组+二分+st+主席树)
- 算法导论第三版第二章答案
- 传奇客户端wil和pak文件的目录与作用
- 微信扫码支付模式一 : 获取商户订单信息超时或者商户返回的httpcode非200
- easyexcel的导出
- 3周个人错误和知识弱点盲点{随时更新}
热门文章
- normrnd函数 matlab,关于normrnd函数~~请教请教
- Win7快捷键——最小化窗口
- CentOS系统主机每日巡检脚本
- c语言putpixel函数普通写法,C语言标准函数库5
- 【零基础学Java】
- QSS和QML的区别(简单了解)
- .Net Framework4.0下载安装
- 工程师如何对待开源 --- 一个老工程师的肺腑之言
- MSE RMSE PSNR SSIM
- Cadence PSpice 疑难2:报错ERROR(ORPSIM-15660): These devices failed to converge的原因与解决方法