Stm32 hal库 usart2与hc-08透传模块通讯(附数据解析)
一、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长度的数据后,就不会开启中断了。
void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
HAL_UART_Receive_IT(&huart2, mReceiveBuff, BUFFER_SIZE);
}
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%x\r\n",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 %d\r\n",getLedDataByNum(LED_NO_2));
}else if (mData[6] == CMD_OFF)
{
secondRoomLedConfigure(LED_OFF);
saveLedDataByNum(LED_NO_2,LED_OFF);
printf("get %d\r\n",getLedDataByNum(LED_NO_2));
}
}
HAL_UART_Transmit(&huart2, mData, mLen, 1000);
}
else if (mData[4] == GET_CMD){
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);
}
}
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]))
{
Uart2_Sta = 1;
}
else
{
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);
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%x\r\n",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 %d\r\n",getLedDataByNum(LED_NO_2));
}else if (mData[6] == CMD_OFF)
{
secondRoomLedConfigure(LED_OFF);
saveLedDataByNum(LED_NO_2,LED_OFF);
printf("get %d\r\n",getLedDataByNum(LED_NO_2));
}
}
HAL_UART_Transmit(&huart2, mData, mLen, 1000);
}
else if (mData[4] == GET_CMD){
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);
}
}
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);
完整代码下载添加链接描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)