目录

硬件连接

实现串口1和串口3相互通信

GY_33的概述

对GY_33的数据分析

GY_33数据处理

GY_33的配套软件使用

代码


主要思路:注:这里我使用串口1和串口3,可以更改串口

                   1.上位机通过串口1发送数据给stm32单片机

                   2.stm32通过串口3发送数据给GY_33

                   3.GY_33通过串口3发送数据给stm32单片机

                   4.stm32处理数据完后通过串口1发送数据给上位

所需:stm32单片机(这里使用的是正点原子stm32mini板),GY_33传感器,GY_33配套软件,串口助手,USB转TTL

以下为GY_33的配套资料以及软件的链接

GY-33_免费高速下载|百度网盘-分享无限制


硬件连接

这里使用的是串口1,串口3.

根据mini板的芯片图

串口1的引脚为PA10(RX),PA9(TX)

串口3的引脚为PB10(TX),PB11(RX)

GY_33硬件图,DR(RX) ,CT(TX)                              

所以根据输出端->接收端,接收端->输出端:

GY_33的连线:

1.VCC->3V3

2.GND->GND

3.DR->PB10

4.CT->PB11

stm32单片机连接(本来有接线帽接好了就不用操作这步):

1.PA10->TXD

2.PA9->RXD

上位机:插好usb

实现串口1和串口3相互通信

思路:串口1接收到数据后,进入串口1中断,将串口1接收到的数据保存,通过串口3发送给

GY_33。(串口3同理)

代码如下

void USART1_IRQHandler ()//串口1中断
{if(USART_GetITStatus(USART1,USART_IT_RXNE))//如果接收到数据{   u8 data;data=USART_ReceiveData(USART1);//赋值   USART_SendData(USART3,data);//发给传感器}
}

GY_33的概述

GY-33是一款低成本颜色识别传感器模块。 工作电压3-5v,功耗小,体积小,安装方便。 其工作原理是,照明LED发光,照射到被测 物体后,返回光经过滤镜检测RGB的比例值 ,根据RGB的比例值识别出颜色。 此模块,有两种方式读取数据,即 串口UART(TTL电平)或者IIC(2线)。 串口的波特率有9600bps与115200bps,可配置, 有连续,询问输出两种方式,可掉电保存设置。 有简单的7种颜色识别,不需要计算RGB值。 可适应不同的工作环境,与单片机及电脑连接。 模块另外可以设置单独传感器芯片工作模式, 作为简单传感器模块,MCU不参与数据处理工作。

简单来说,他可以识别不同颜色反馈不同的数据回来,让我们通过反馈数据来识别颜色,可应用于智能车等识别颜色的模块。

对GY_33的数据分析

1.GY_33的输出格式:

分析:1.Byte0和Byte1中的0x5A 0X5A代表一段新数据发送开始的标志

             2.Byte2中的数值代表发送数据的类型(下面会细说)

             3.Byte3中代表要发送几个数据(不包括校验和),图中Byte3=6,所以下面Byte4-Byte9为它所要发送的有效数据,Byte10为校验和(就是将前面所有数据加起来(包括帧头),仅仅保留第八位的和),来检验它发送的数据有无错误(可以减少错误,但不能避免,不精确)

2.GY_33数据分析

由于我们采用的是串口模式,它只会发送0x15,0x25,0x45这三种数据

对三种数据举例分析

1.Byte2=0x15(RGBC)

例如发送下面这串代码(16进制)

<5A-5A-15-08-01-78-01-92-00-4C-05-05-33 >

5A 5A 为缀头     0x15为数据类型,表示发送的是原始RGBC值    08为发送八个数据

 我们可以通过这串数据算出,R,G,B,C的值

2.Byte2=0x25(亮度,色温,颜色)

例如发送下面这串代码(16进制)

< 5A-5A-25-06-02-CC-0C-5D-00-02-18 > 

5A 5A 为缀头     0x25为数据类型,表示发送的是亮度,色温,颜色   06为发6个数据

亮度和色温的计算很简单,进行一个位运算,而颜色的值,将其转化为2进制,哪一位为1

则亮,例如color等于4,转化为2进制为100,那么bit2为1,所以为粉色。

3.Byte=0x45(处理好的RGB值)

 这一段数据就是将Byte=0x15这串数据,经过MCU计算好的R,G,B值

很容易可以看到,5A 5A为帧头,0x45代表数据类型,03代表有三个有效数据

第一位为R:FF   第二位G:FF    第三位B:4C     第四位为校验和

GY_33数据处理

由于传感器会发出三种类型的数据,并且每一类型的数据所含数字个数不同,需要我们选择一种数据,进行处理,返回RGB值,并且判断颜色。

这里选择Byte=0x45的数据,也就是处理好的RGB值,其他类型数据方法接收类似。

<5A-5A-15-08-01-78-01-92-00-4C-05-05-33 > (Byte2=0x15)

< 5A-5A-25-06-02-CC-0C-5D-00-02-18 > (Byte2=0x25)

<5A-5A-45-03-FF-FF-4C-46> (Byte2=0x45)

注:虽然三种数据长度各不相同,但同一类型数据,长度相同

容易看到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(加深颜色为了看到清楚)

在如此大的数据中,我们需要提取 5A 5A 45 03 FF F 4C 46这数据只要找到这串数据的不同之处即可,不难发现这串数据开头格式为5A 5A 45,也就是说我们接受到5A 5A 45 这几个连起来的数据就开始接受我们要的数据(也可以用5A 5A 45 03(更加精确))

代码实现如下

if(USART_GetITStatus(USART3,USART_IT_RXNE))//如果接收到数据,进入串口3中断{int data;//u8 result;static int i=0,temp1,temp2,staus=0,j=0,staus2=0,temp3=1,temp4=2,temp5=3;data=USART_ReceiveData(USART3);//赋值   if(data==0x5A){staus2=1;}//如果接收到帧头开始准备接受数据if(staus2)//测试是否是我们所需的数据{j++;if(j==1){temp3=data;}//将第一个帧头保存下来if(j==2){temp4=data;}//第二个帧头保存下来if(j==3){temp5=data;//保存数据类型j=0;//归0if(temp5==0x45&&temp4==0x5A&&temp3==0X5A)//符合我们所需类型{staus2=0;//关闭测试staus=1;//数据类型正确,开启接受数据}}}if (staus)//接收数据{    i++;if(i==3){ temp1 = data;}//存放Rif(i==4){ temp2 = data;}//存放Gif(i==5){   delay_us(20);/*延时避免数据传输过快导致错误,单个中断时可用,多中断不行,该中断完成时间太久,未完成任务就被其他中断打断*///判断颜色(通过实际测试得)if(temp1>=255&&temp2>=255&&data>=255){printf("R:%d   G:%d   B:%d   白色\r\n",temp1,temp2,data);}if(temp1<=40&&temp2<=40&&data<=40){printf("R:%d   G:%d   B:%d   黑色\r\n",temp1,temp2,data);}else{      if(temp2>temp1&&temp2>data){printf("R:%d   G:%d   B:%d   绿色\r\n",temp1,temp2,data);}if(temp1>temp2&&temp1>data){printf("R:%d   G:%d   B:%d   红色\r\n",temp1,temp2,data);}if(data>temp1&&data>temp2){printf("R:%d   G:%d   B:%d   蓝色\r\n",temp1,temp2,data);}                     }                                         i = 0;//发送完毕,接受新数据staus = 0;//关闭数据接受状态}}                   }

GY_33的配套软件使用

以下指令为本次所需

该指令的实现可通过USB转TTL直接连传感器,通过上图配套软件直接配置GY_33.

注意,要调白平衡,调试方法,将传感器对准白色物体,再发送白平衡指令,不然传感器数据不准,因为没有参照物。

指令的发送可通过以下软件实现。

1.串口助手(注:要选择16进制发送)

2.COLOR

代码

根据协议来初始化串口参数,以下为完全代码

#include "stm32f10x.h"
#include "stdio.h"
#include "delay.h"
void USART1_Init(void)//初始化串口1
{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;GPIO_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;GPIO_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);//使能串口USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能接收缓存非空寄存器
}
void USART3_Init(void)//初始化串口3
{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;GPIO_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);//发给传感器}
}
void USART3_IRQHandler()//串口3中断
{if(USART_GetITStatus(USART3,USART_IT_RXNE))//如果接收到数据{int data;u8 result;static int i=0,temp1,temp2,staus=0,j=0,staus2=0,temp3=1,temp4=2,temp5=3;data=USART_ReceiveData(USART3);//赋值    if(data==0x5A){staus2=1;}//如果接收到帧头开始准备接受数据if(staus2)//测试是否所需数据{j++;if(j==1){temp3=data;}保存第一个数if(j==2){temp4=data;}保存第二个数if(j==3){temp5=data;j=0;if(temp5==0x45&&temp4==0x5A&&temp3==0X5A)//如果数据为0X5A 0X5A,0X45{staus2=0;//关闭测试staus=1;//前缀正确,开启接受数据}}}if (staus)//接收数据{   i++;if(i==3){ temp1 = data;}//存放Rif(i==4){ temp2 = data;}//存放Gif(i==5){   delay_us(20);//延时避免数据传输过快导致错误//判断颜色if(temp1>=255&&temp2>=255&&data>=255){printf("R:%d   G:%d   B:%d   白色\r\n",temp1,temp2,data);}if(temp1<=40&&temp2<=40&&data<=40){printf("R:%d   G:%d   B:%d   黑色\r\n",temp1,temp2,data);}else{     if(temp2>temp1&&temp2>data){printf("R:%d   G:%d   B:%d   绿色\r\n",temp1,temp2,data);}if(temp1>temp2&&temp1>data){printf("R:%d   G:%d   B:%d   红色\r\n",temp1,temp2,data);}if(data>temp1&&data>temp2){printf("R:%d   G:%d   B:%d   蓝色\r\n",temp1,temp2,data);}                     }                                         i = 0;//发送完毕,接受新数据staus = 0;//关闭数据接受状态}}                   }
}
int main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);USART1_Init();USART3_Init();delay_init();while(1);
}
//print所需函数
#if 1
#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

stm32单片机通过串口通信实现将GY_33颜色传感器的接收到的颜色和RGB值上传给上位机相关推荐

  1. stm32单片机使用串口通信连接GY-33颜色传感器完成对颜色的识别并且打印出其颜色和对应的RGB值

    目录 1.GY-33介绍及其接线 2.通信原理 3.代码 4.GY-33发送出来的数据及如何处理数据​ 5.软件使用 所需:stm32单片机(这里使用的是正点原子stm32mini板),GY_33传感 ...

  2. stm32水质检测系统(TDS检测,水温检测,PH检测,wifi上传,上位机显示)

    一.硬件材料清单: 1.STM32核心板 2.OLED显示屏 3.PH传感器 4.TDS传感器 5.DS18B02水温传感器 6.ESP8266 二.实现的功能 1.数据的实时检测 2.本地OLED数 ...

  3. Proteus仿真stm32和51单片机,串口通信调试过程记录

    前言 本文所用Proteus版本为8.10,主要内容为在Proteus中仿真stm32和51单片机进行串口通信,记录了仿真过程中遇到的问题和解决办法.        这里要注意的是,在Proteus中 ...

  4. labVIEW与单片机实现串口通信的设计过程

    1.概述 在现代测控系统中,我们经常会采用上位机和下位机的开发控制模式.下位机主要是用来采集数据,可以通过嵌入式控制器.单片机控制器.PLC等来实现.上位机主要是图形界面,用来实时显示采集数据,并进行 ...

  5. arm linux串口控制led,通信程序设计 - Linux下ARM和单片机的串口通信设计

    3 通信程序设计 ARM 与单片机的串口通信程序包括两方面: 一方面是作为上位机的ARM 的串口通信程序,另一方面是作为下位机的单片机的串口通信程序.在通信之前必须制定合理的通信协议以保证通信的可靠性 ...

  6. STM32和ROS串口通信常见问题汇总答疑

    STM32和ROS串口通信常见问题汇总答疑 大家好,我是白茶清欢,最近看了博客文章<stm32和ros的串口通信>有很多问题的评论,这里汇总回复一下. 问题1:运行时报错如下: rosru ...

  7. 51单片机stc15w204s串口通信发数据接收数据串口中断发中文字符串完美运行软件延时发送一字节函数全注释

    这里写自定义目录标题 KEIL自己先调试通了然后再说下面的事 51单片机stc15w204s串口通信直接上文件 KEIL自己先调试通了然后再说下面的自己看看就可 KEIL自己先调试通了然后再说下面的事 ...

  8. Ardunio 完成STM32板子的串口通信

    目录 一.Ardunio简介 二.Ardunio配置 三.实验 四.其它 实验目的: 安装 Ardunio IDE 和相关软件支持库,在Ardunio 上完成STM32板子的串口通信程序:持续向串口输 ...

  9. 51单片机之串口通信

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.串口介绍 二.电路 三.寄存器 四.串口通信操作流程 前言 2022.9.14的学习记录.` 一.串口介绍 串口是 ...

最新文章

  1. lopa分析_HAZOP : 保护层分析之失效使能分析导则
  2. 计算机二级2021辅导书,2021该如何准备计算机二级考试?
  3. Android:TextView 自动滚动(跑马灯) (转)
  4. 控件列[Coolite]上传文件
  5. Linux安装ntp同步时间
  6. 用python实现(1.求输入的百倍,十位,个位数;2.输入a,b和ab间夹角,计算c边长;3.计算两点间曼哈顿距离;4.计算给定数据的几何平均数;5.计算向量的L1和L2范数)
  7. iOS网络开发—POST请求和GET请求
  8. git pull/git fetch更新分支
  9. Java从入门到精通第一版(Java基础)
  10. MAC OS(U盘启动教程)
  11. 拼多多平台API接入文档
  12. 未签订书面劳动合同的仲裁时效
  13. 不同比例,不同尺寸的笔记本屏幕对比
  14. centos访问window共享目录
  15. springboot POST 405 错误
  16. 声网首席科学家钟声:感知实时互联网
  17. rust拆除拆除指令_Rust 输出到命令行
  18. couldnotfindartifactcom.orcale:ojdbc6:pom:11.2.0.1.0innexus-aliyun
  19. 手把手教你使用Java生成助记词、私钥、地址|Java区块链钱包生成助记词、地址
  20. 自适应网站与响应式网站的区别在哪?

热门文章

  1. Day10 -- JavaScript实现按下 Shift 键后进行多选操作的功能
  2. 电影top250爬虫
  3. focus 获取焦点, blur 失去焦点 事件 javascript 写法
  4. 使用psql无法连接数据库,并报错 FATAL:53300
  5. java return返回值_java中关于return返回值的用法详解
  6. 格林公式挖洞法中内曲线顺时针的直观解释
  7. flask篇B2,重定向,url_for,模板语法
  8. 新手怎么学习嵌入式?什么人适合转行学习嵌入式?
  9. Android room 兼容版本,Android ROOM的基本使用
  10. 交易猫源码跳转APP 独立后台管理