目錄
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);//使能GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//使能串口1
//發送TX
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PA9
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根據GY-33回應頻率10hz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA
//接收RX
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根據GY-33回應頻率10hz
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);//使能串口1
USART_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);//使能GPIOB
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 ,ENABLE);//使能串口3
//發送TX
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PB10
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//根據GY-33回應頻率10hz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB
//接收RX
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//PB11
GPIO_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);//使能串口3
USART_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進制發送勾選上,波特率停止位等配置按如下)
打開串口就可以接收到列印的資料了
完成此次任務,我發現對資訊的篩選及整合能力很關鍵,最重要的應該是先搞明白原理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/342273.html
標籤:其他
上一篇:沖刺大廠每日演算法&面試題,動態規劃21天——第三天
下一篇:正確決議JObject










