catalogue
Realize the communication between serial port 1 and serial port 3
Main idea: Note: Here I use serial port 1 and serial port 3 to change the serial port
1. The upper computer sends data to stm32 MCU through serial port 1
2.stm32 sends data to Gy through serial port 3_ thirty-three
3.GY_33 send data to stm32 MCU through serial port 3
4.stm32 sends data to the upper computer through serial port 1 after data processing
What you need: stm32 single chip microcomputer (the punctual atom stm32mini board is used here), GY_33 sensor, GY_33 supporting software, serial port assistant, USB to TTL
Gy below_ 33 supporting materials and software links
GY-33_ Free high-speed download | Baidu online disk - unlimited sharing
Serial port 1 and serial port 3 are used here
According to the chip diagram of mini board
The pins of serial port 1 are PA10 (Rx) and PA9 (TX)
The pins of serial port 3 are pb10 (TX) and pb11 (Rx)
GY_33 hardware diagram, DR(RX) , CT(TX)
Therefore, according to output end - > receiving end, receiving end - > output end:
GY_33 connection:
1.VCC->3V3
2.GND->GND
3.DR->PB10
4.CT->PB11
stm32 single-chip microcomputer connection (this step is not needed when the wiring cap is connected):
1.PA10->TXD
2.PA9->RXD
Upper computer: plug in usb
Realize the communication between serial port 1 and serial port 3Idea: after serial port 1 receives the data, enter serial port 1 to interrupt, save the data received by serial port 1 and send it to the user through serial port 3
GY_33. (same for serial port 3)
The code is as follows
void USART1_IRQHandler ()//Serial port 1 interrupt { if(USART_GetITStatus(USART1,USART_IT_RXNE))//If data is received { u8 data; data=USART_ReceiveData(USART1);//assignment USART_SendData(USART3,data);//Send to sensor } }For GY_33 data analysis
1.GY_33 output format:
Analysis: 1. 0x5A 0X5A in byte0 and Byte1 represents the start flag of a new data transmission
2. The value in byte2 represents the type of data sent (described in detail below)
3.Byte3 represents several data to be sent (excluding checksum). In the figure, Byte3=6, so the following Byte4-Byte9 is the valid data to be sent, and Byte10 is the checksum (that is, add all the previous data (including the frame header), and only retain the sum of the eighth bit) to check whether there are errors in the data sent (errors can be reduced, but they cannot be avoided and inaccurate)
2.GY_33 data analysis
Because we use the serial port mode, it will only send 0x15, 0x25 and 0x45 data
Three kinds of data are analyzed with examples
1.Byte2=0x15(RGBC)
For example, send the following string of codes (hexadecimal)
<5A-5A-15-08-01-78-01-92-00-4C-05-05-33 >
5A is the batten head 0x15 is the data type, indicating that the original RGBC value is sent 08 send eight data for
We can calculate the values of R,G,B,C from this string of data
2. Byte2 = 0x25 (brightness, color temperature, color)
For example, send the following string of codes (hexadecimal)
< 5A-5A-25-06-02-CC-0C-5D-00-02-18 >
5A is the batten head 0x25 is the data type, indicating that the brightness, color temperature and color are sent 06 sends 6 data
The calculation of brightness and color temperature is very simple. A bit operation is carried out, and the value of color is converted into binary. Which bit is 1
For example, if color is equal to 4 and binary is 100, bit2 is 1, so it is pink.
3.Byte=0x45 (processed RGB value)
This section of data is the R, G and b values calculated by MCU for the string of data Byte=0x15
It is easy to see that 5A is the frame header, 0x45 represents the data type, and 03 represents three valid data
The first is R: FF Second bit G: FF Third B: 4C The fourth digit is the checksum
GY_33 data processingBecause the sensor will send three types of data, and each type of data contains different numbers, we need to select a data, process it, return RGB value and judge the color.
Here, select the data with Byte=0x45, that is, the processed RGB value. The receiving methods of other types of data are similar.
<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)
Note: Although the length of the three kinds of data is different, the length of the same type of data is the same
It is easy to see that the data types and lengths in 3 are different, but the sensor will send them together, for example
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 45 03 FF f 4C 46 (darken color for clarity)
In such a large data, we need to extract 5A 5A 45 03 FF F 4C 46 as long as we find the differences between the data, it is not difficult to find that the beginning format of the data is 5A 5A 45, that is, when we receive the connected data of 5A 5A 45, we begin to accept the data we want (5a 5A 45 03 (more accurate))
The code is implemented as follows
if(USART_GetITStatus(USART3,USART_IT_RXNE))//If data is received, enter serial port 3 and interrupt { 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);//assignment if(data==0x5A)//If the frame header is received, start preparing to accept data if(staus2)//Is the test the data we need { j++; if(j==1)//Save the first frame header if(j==2)//The second frame header is saved if(j==3) { temp5=data;//Save data type j=0;//Return to 0 if(temp5==0x45&&temp4==0x5A&&temp3==0X5A)//Meet the type we need { staus2=0;//Close test staus=1;//If the data type is correct, start to accept data } } } if (staus)//receive data { i++; if(i==3){ temp1 = data;}//Storage R if(i==4){ temp2 = data;}//Storage G if(i==5) { delay_us(20);/*Delay to avoid errors caused by too fast data transmission. A single interrupt is available, but multiple interrupts are not. The completion time of the interrupt is too long, and the unfinished task is interrupted by other interrupts*/ //Judge color (through actual test) if(temp1>=255&&temp2>=255&&data>=255) { printf("R:%d G:%d B:%d white\r\n",temp1,temp2,data); } if(temp1<=40&&temp2<=40&&data<=40) { printf("R:%d G:%d B:%d black\r\n",temp1,temp2,data); } else { if(temp2>temp1&&temp2>data) { printf("R:%d G:%d B:%d green\r\n",temp1,temp2,data); } if(temp1>temp2&&temp1>data) { printf("R:%d G:%d B:%d gules\r\n",temp1,temp2,data); } if(data>temp1&&data>temp2) { printf("R:%d G:%d B:%d blue\r\n",temp1,temp2,data); } } i = 0;//After sending, accept new data staus = 0;//Close data acceptance status } } }GY_33 supporting software use
The following instructions are required for this
The implementation of this command can be directly connected to the sensor through USB to TTL, and Gy can be directly configured through the supporting software in the figure above_ thirty-three
Note: adjust the white balance, adjust the method, aim the sensor at the white object, and then send the white balance command, otherwise the sensor data is inaccurate because there is no reference object.
The sending of instructions can be realized by the following software.
1. Serial port assistant (Note: to select hexadecimal transmission)
2.COLOR
codeInitialize the serial port according to the protocol
#include "stm32f10x.h" #include "stdio.h" #include "delay.h" void USART1_Init(void)//Initialize serial port 1 { GPIO_InitTypeDef GPIO_InitStructure;//Define GPIO structure USART_InitTypeDef USART_InitStructure;//Define serial port structure NVIC_InitTypeDef NVIC_InitStructure;//Define priority structure //Enable clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//Enable GPIOA RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//Enable serial port 1 //Send TX GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PA9 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//Multiplexed push-pull output GPIO_Init(GPIOA,&GPIO_InitStructure);//Initialize GPIOA //Receive RX GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//Floating input GPIO_Init(GPIOA,&GPIO_InitStructure);//Initialize GPIOA //Serial port USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//No hardware USART_InitStructure.USART_BaudRate=9600;//Baud rate USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//pattern USART_InitStructure.USART_StopBits=USART_StopBits_1;//A stop bit USART_InitStructure.USART_Parity=USART_Parity_No;//Parity off USART_InitStructure.USART_WordLength=USART_WordLength_8b;//Word length USART_Init(USART1,&USART_InitStructure);//Initialize serial port 1 //Priority configuration NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//Serial port 1 interrupt NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//Enable serial port 1 interrupt NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//seize NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//Response priority NVIC_Init(&NVIC_InitStructure);//Initialization priority //Enable USART_Cmd(USART1,ENABLE);//Enable serial port USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//Enable receive cache non empty register } void USART3_Init(void)//Initialize serial port 3 { GPIO_InitTypeDef GPIO_InitStructure;//Define GPIO structure USART_InitTypeDef USART_InitStructure;//Define serial port structure NVIC_InitTypeDef NVIC_InitStructure;//Define priority structure //Enable clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//Enable GPIOB RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 ,ENABLE);//Enable serial port 3 //Send TX GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PB10 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//Multiplexed push-pull output GPIO_Init(GPIOB,&GPIO_InitStructure);//Initialize GPIOB //Receive RX GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//PB11 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//Floating input GPIO_Init(GPIOB,&GPIO_InitStructure);//Initialize GPIOB //Serial port USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//No hardware USART_InitStructure.USART_BaudRate=9600;//Baud rate USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//pattern USART_InitStructure.USART_StopBits=USART_StopBits_1;//A stop bit USART_InitStructure.USART_Parity=USART_Parity_No;//Parity off USART_InitStructure.USART_WordLength=USART_WordLength_8b;//Word length USART_Init(USART3,&USART_InitStructure);//Initialize serial port 3 //Priority configuration NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;//Serial port 3 interrupt NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//Enable serial port 3 interrupt NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//seize NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//Response priority NVIC_Init(&NVIC_InitStructure);//Initialization priority //Enable USART_Cmd(USART3,ENABLE);//Enable serial port 3 USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//Enable receive cache non empty register } void USART1_IRQHandler ()//Serial port 1 interrupt { if(USART_GetITStatus(USART1,USART_IT_RXNE))//If data is received { u8 data; data=USART_ReceiveData(USART1);//assignment USART_SendData(USART3,data);//Send to sensor } } void USART3_IRQHandler()//Serial port 3 interrupt { if(USART_GetITStatus(USART3,USART_IT_RXNE))//If data is received { 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);//assignment if(data==0x5A)//If the frame header is received, start preparing to accept data if(staus2)//Test for required data { j++; if(j==1)Save first number if(j==2)Save second number if(j==3) { temp5=data;j=0; if(temp5==0x45&&temp4==0x5A&&temp3==0X5A)//If the data is 0x5a, 0x5a, 0X45 { staus2=0;//Close test staus=1;//If the prefix is correct, enable to accept data } } } if (staus)//receive data { i++; if(i==3){ temp1 = data;}//Storage R if(i==4){ temp2 = data;}//Storage G if(i==5) { delay_us(20);//Delay to avoid errors caused by too fast data transmission //Judge color if(temp1>=255&&temp2>=255&&data>=255) { printf("R:%d G:%d B:%d white\r\n",temp1,temp2,data); } if(temp1<=40&&temp2<=40&&data<=40) { printf("R:%d G:%d B:%d black\r\n",temp1,temp2,data); } else { if(temp2>temp1&&temp2>data) { printf("R:%d G:%d B:%d green\r\n",temp1,temp2,data); } if(temp1>temp2&&temp1>data) { printf("R:%d G:%d B:%d gules\r\n",temp1,temp2,data); } if(data>temp1&&data>temp2) { printf("R:%d G:%d B:%d blue\r\n",temp1,temp2,data); } } i = 0;//After sending, accept new data staus = 0;//Close data acceptance status } } } } int main() { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); USART1_Init(); USART3_Init(); delay_init(); while(1); } //print required function #if 1 #pragma import(__use_no_semihosting) //Support functions required by the standard library struct __FILE { int handle; }; FILE __stdout; //Definition_ sys_exit() to avoid using half host mode _sys_exit(int x) { x = x; } //Redefine fputc function int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//Cycle sending until sending is completed USART1->DR = (u8) ch; return ch; } #endif