完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、stm32cubeMX配置
1、配置RCC为外部晶振 2、配置时钟树 3、配置usart1 usart2 ,其中usart1将作为打印串口使用,蓝牙透传模块将使用usart2进行通讯,配置如下。 usart1 不用处理接收的数据,故不用打开中断,只需配置上面即可,我们重写fgetc函数以后,就可以使用printf函数。 usart2 配置如下 打开usart2 中断 最后配置中断优先级 最后生成代码即可。 二、数据解析 1、usart2中断函数,在中断函数里添加这句话, HAL_UART_Receive_IT(&huart2, mReceivemBuff, BUFFER_SIZE); 再次开启中断,不然接收到指定mReceivemBuff长度的数据后,就不会开启中断了。 /** * @brief This function handles USART2 global interrupt. */ void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ HAL_UART_Receive_IT(&huart2, mReceiveBuff, BUFFER_SIZE); /* USER CODE END USART2_IRQn 1 */ } 2、中断回调函数。 以数据 B5 5B 05 01 01 01 01 00 0D BC 为例,且BUFFER_SIZE为1 ,那么发送十个字节数据,HAL_UART_RxCpltCallback函数将会回调十次,每次返回一个数据,那么我们就要对数据头 尾判断来截取我们需要的数据。 static uint16_t CRC16(uint8_t * buf, uint16_t len) { uint8_t i; uint16_t crc = 0xffff; if (len == 0) { len = 1; } while (len--) { crc ^= *buf; for (i = 0; i<8; i++) { if (crc & 1) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } buf++; } return(crc); } static void handlerUart2Data(uint8_t *mData, uint8_t mLen) { uint8_t mLedStatusCommand[10]= {0xb5,0x5B,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00}; uint16_t mSendDataCrc = 0; uint16_t tempCrc = CRC16(mData,8); printf("crc==0x%xrn",tempCrc); if ((mData[0] == UART_DATA_HEAD_ONE) && (mData[1] == UART_DATA_HEAD_TWO) &&( (tempCrc&0x00ff)== mData[8]) && (((tempCrc>>8)&0x00ff) == mData[9])) { if(mData[3] == CMD_LED) { if (mData[4] == SET_CMD) { if (mData[5] == LED_NO_1) { if (mData[6] == CMD_ON) { mainRoomLedConfigure(LED_ON); saveLedDataByNum(LED_NO_1,LED_ON); }else if (mData[6] == CMD_OFF) { mainRoomLedConfigure(LED_OFF); saveLedDataByNum(LED_NO_1,LED_OFF); } } else if (mData[5] == LED_NO_2) { if (mData[6] == CMD_ON) { secondRoomLedConfigure(LED_ON); saveLedDataByNum(LED_NO_2,LED_ON); printf("get %drn",getLedDataByNum(LED_NO_2)); }else if (mData[6] == CMD_OFF) { secondRoomLedConfigure(LED_OFF); saveLedDataByNum(LED_NO_2,LED_OFF); printf("get %drn",getLedDataByNum(LED_NO_2)); } } HAL_UART_Transmit(&huart2, mData, mLen, 1000); } else if (mData[4] == GET_CMD){ // return all led status // apk send this data === {0xb5,0x5B,0x05,0x01,0x00,0x03,0x00,0x00,0x00,0x00} //and stm 32 send {0xb5,0x5B,0x05,0x01,0x00,0xxx,0xxx,0xxx,0x00,0x00} mLedStatusCommand[7] = getLedDataByNum(LED_NO_3); mLedStatusCommand[6] = getLedDataByNum(LED_NO_2); mLedStatusCommand[5] = getLedDataByNum(LED_NO_1); mSendDataCrc = CRC16(mLedStatusCommand,8); mLedStatusCommand[9] = (mSendDataCrc >> 8); mLedStatusCommand[8] = (mSendDataCrc & (0xff)); HAL_UART_Transmit(&huart2, mLedStatusCommand, mLen, 1000); } } else if(mData[3] == CMD_BEEP) { if (mData[4] == SET_CMD) { if (mData[5] == BEEP_NO_1){ if (mData[6] == CMD_ON){ setBeepStatus(1); saveBeepData(CMD_ON); }else if (mData[6] == CMD_OFF){ setBeepStatus(0); saveBeepData(CMD_OFF); } } //set success and send the same data to control device HAL_UART_Transmit(&huart2, mData, mLen, 1000); } }else if (mData[3] == 0x05){ int value = mData[5] *7 ; saveLedDataByNum(LED_NO_4,mData[5]); __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4,value); HAL_UART_Transmit(&huart2, mData, mLen, 1000); } } else{ mData[8] = (tempCrc&0x00ff); mData[9] = ((tempCrc>>8)&0x00ff); HAL_UART_Transmit(&huart2, mData, mLen, 1000); } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { Uart2_Buffer[Uart2_Rx] = mReceiveBuff[0]; Uart2_Rx++; Uart2_Rx &= 0xFF; if(Uart2_Buffer[Uart2_Rx-1] == 0xB5) { Uart2_head1 = Uart2_Rx-1; }else if((Uart2_Rx-1 == Uart2_head1+1)&&(Uart2_Buffer[Uart2_Rx-1] == 0x5B)) { Uart2_head2 = Uart2_Rx-1; }else if(Uart2_Rx-1 == Uart2_head2+1) { Uart2_Len = Uart2_Buffer [Uart2_Rx-1]; } else if(Uart2_Rx-1 == Uart2_head1 + Uart2_Len + 4) { Uart2_temp = CRC16(Uart2_Buffer,Uart2_Len+3); if(((Uart2_temp&0x00ff)==Uart2_Buffer[Uart2_head1+Uart2_Len+3])&&(((Uart2_temp>>8)&0x00ff)==Uart2_Buffer[Uart2_head1+Uart2_Len+4])) { //crc right and the data parse end and go to parse data Uart2_Sta = 1; } else { //crc wrong and set contorl device the right crc value Uart2_Buffer[Uart2_head1+Uart2_Len+3] = Uart2_temp&0x00ff; Uart2_Buffer[Uart2_head1+Uart2_Len+4] = (Uart2_temp>>8)&0x00ff; HAL_UART_Transmit(&huart2, Uart2_Buffer, Uart2_Rx, 1000); Uart2_Rx = 0; } } if(Uart2_Sta) { handlerUart2Data(Uart2_Buffer, Uart2_Rx); //parse data Uart2_Rx = 0; Uart2_Sta = 0; } } 假如规定所有的数据都是等长的,即定义BUFFER_SIZE为10 ,发送端每次发送十个字节,那么中断回调函数每次回调一次,处理数据就简单多了。直接对mReceiveBuff处理即可。 static void handlerUart2Data(uint8_t *mData, uint8_t mLen) { uint8_t mLedStatusCommand[10]= {0xb5,0x5B,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00}; uint16_t mSendDataCrc = 0; uint16_t tempCrc = CRC16(mData,8); printf("crc==0x%xrn",tempCrc); if ((mData[0] == UART_DATA_HEAD_ONE) && (mData[1] == UART_DATA_HEAD_TWO) &&( (tempCrc&0x00ff)== mData[8]) && (((tempCrc>>8)&0x00ff) == mData[9])) { if(mData[3] == CMD_LED) { if (mData[4] == SET_CMD) { if (mData[5] == LED_NO_1) { if (mData[6] == CMD_ON) { mainRoomLedConfigure(LED_ON); saveLedDataByNum(LED_NO_1,LED_ON); }else if (mData[6] == CMD_OFF) { mainRoomLedConfigure(LED_OFF); saveLedDataByNum(LED_NO_1,LED_OFF); } } else if (mData[5] == LED_NO_2) { if (mData[6] == CMD_ON) { secondRoomLedConfigure(LED_ON); saveLedDataByNum(LED_NO_2,LED_ON); printf("get %drn",getLedDataByNum(LED_NO_2)); }else if (mData[6] == CMD_OFF) { secondRoomLedConfigure(LED_OFF); saveLedDataByNum(LED_NO_2,LED_OFF); printf("get %drn",getLedDataByNum(LED_NO_2)); } } HAL_UART_Transmit(&huart2, mData, mLen, 1000); } else if (mData[4] == GET_CMD){ // return all led status // apk send this data === {0xb5,0x5B,0x05,0x01,0x00,0x03,0x00,0x00,0x00,0x00} //and stm 32 send {0xb5,0x5B,0x05,0x01,0x00,0xxx,0xxx,0xxx,0x00,0x00} mLedStatusCommand[7] = getLedDataByNum(LED_NO_3); mLedStatusCommand[6] = getLedDataByNum(LED_NO_2); mLedStatusCommand[5] = getLedDataByNum(LED_NO_1); mSendDataCrc = CRC16(mLedStatusCommand,8); mLedStatusCommand[9] = (mSendDataCrc >> 8); mLedStatusCommand[8] = (mSendDataCrc & (0xff)); HAL_UART_Transmit(&huart2, mLedStatusCommand, mLen, 1000); } } else if(mData[3] == CMD_BEEP) { if (mData[4] == SET_CMD) { if (mData[5] == BEEP_NO_1){ if (mData[6] == CMD_ON){ setBeepStatus(1); saveBeepData(CMD_ON); }else if (mData[6] == CMD_OFF){ setBeepStatus(0); saveBeepData(CMD_OFF); } } //set success and send the same data to control device HAL_UART_Transmit(&huart2, mData, mLen, 1000); } } } else{ mData[8] = (tempCrc&0x00ff); mData[9] = ((tempCrc>>8)&0x00ff); HAL_UART_Transmit(&huart2, mData, mLen, 1000); } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { handlerUart2Data(mReceiveBuff, BUFFER_SIZE); //HAL_UART_Transmit(&huart2, mReceiveBuff, BUFFER_SIZE, 1000); } 另外发送数据用的函数为HAL_UART_Transmit(&huart2, mReceiveBuff, BUFFER_SIZE, 1000); |
|
|
|
只有小组成员才能发言,加入小组>>
3309 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9050 浏览 16 评论
4085 浏览 18 评论
1169浏览 3评论
602浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
594浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2331浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 00:46 , Processed in 1.020968 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号