/* * rs485.c * * Created on: 2024年6月20日 * Author: psx */ #include "rs485.h" #include "uart_dev.h" #include "ring_queue.h" #include "pdebug.h" #include "uart_send.h" void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void USART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); //#define USART3_buffer_len 128 //#define USART4_buffer_len 128 //uint8_t USART3_Rbuffer_Num = 0; //uint8_t USART4_Rbuffer_Num = 0; /* 接收缓冲区数组 */ uint8_t USART3_Rbuffer[1] = {0x00}; uint8_t USART4_Rbuffer[1] = {0x00}; //uint8_t USART_Rbuffer[100] = {0x00}; //uint8_t USART_RbufferLen = 0; ///* 发送 */ //uint8_t USART3_Tbuffer_Num = 0; //uint8_t USART3_Tbuffer_Len = 0; //uint8_t *USART3_Tbuffer; uart_send_info *GwSendInfo; uart_send_info *BatSendInfo; /* * @brief 初始化GW485 * @param * @retval */ void GW_485_Init(int baud) { /* 初始化GW485控制引脚 */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = Pin_GW_485_RDE; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置PB4为复用推挽输出 GPIO_Init(GPIO_GW_485_RDE, &GPIO_InitStructure); GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, read); USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* USART4 TX --> PB0 RX --> PB1 */ RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOB, ENABLE); RCC_PB1PeriphClockCmd(RCC_PB1Periph_USART4, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置PB0为复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置PB1为浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; // USART_InitStructure.USART_BaudRate = 9600; // USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART4, &USART_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USART4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级为2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //中断优先级初始化 USART_ITConfig(USART4, USART_IT_RXNE, ENABLE); USART_ITConfig(USART4, USART_IT_IDLE, ENABLE); USART_Cmd(USART4,ENABLE); } /* * @brief 初始化BAT_485 * @param * @retval */ void BAT_485_Init(int baud) { /* 初始化GW485控制引脚 */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = Pin_BAT_485_RDE; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置PB5为复用推挽输出 GPIO_Init(GPIO_BAT_485_RDE, &GPIO_InitStructure); GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, read); USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* USART3 TX --> PB10 RX --> PB11 */ RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOB, ENABLE); RCC_PB1PeriphClockCmd(RCC_PB1Periph_USART3, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置PB10为复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置PB11为浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART3, &USART_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级为1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //中断优先级初始化 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); USART_Cmd(USART3,ENABLE); } /* * @brief 通过485发送一个字节 * @param pUSARTx 对应的串口设备 * @param data 字符 * @retval */ void USARTx_SendByte(USART_TypeDef* pUSARTx, uint8_t data) { // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, write); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, write); // } // else { // return; // } USART_SendData(pUSARTx, data); while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); // // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, read); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, read); // } // else { // return; // } } ///* // * @brief 通过串口发送一个字节 // * @param pUSARTx 对应的串口设备 // * @param data 字符 // * @retval // */ //void USARTx_SendByte_str(USART_TypeDef* pUSARTx, uint8_t data) //{ // USART_SendData(pUSARTx, data); // while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); //} // ///* // * @brief 通过485发送一个字符串 // * @param pUSARTx 对应的串口设备 // * @param data 字符串 // * @retval // */ //void USARTx_SendStr(USART_TypeDef* pUSARTx, char *str) //{ // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, write); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, write); // } // else { // return; // } // // uint8_t i = 0; // do // { // USARTx_SendByte_str(pUSARTx, *(str+i)); // i++; // }while(*(str+i) != '\0'); // while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET); // // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, read); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, read); // } // else { // return; // } //} // ///* // * @brief 通过485发送一个字符串的指定长度 // * @param pUSARTx 对应的串口设备 // * @param data 字符串 // * @retval // */ //void USARTx_SendStr_Len(USART_TypeDef* pUSARTx, char *str, int len) //{ // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, write); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, write); // } // else { // return; // } // // uint8_t i = 0; // do // { // USARTx_SendByte_str(pUSARTx, *(str+i)); // i++; // }while(--len); // while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET); // // if (pUSARTx == GW_485) { // GPIO_WriteBit(GPIO_GW_485_RDE, Pin_GW_485_RDE, read); // } // else if (pUSARTx == BAT_485) { // GPIO_WriteBit(GPIO_BAT_485_RDE, Pin_BAT_485_RDE, read); // } // else { // return; // } //} void USARTx_ITSendstr(USART_TypeDef* pUSARTx, char *str, int len) { USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); } /* * @brief USART3的串口中断处理函数 * @param * @retval */ void USART3_IRQHandler(void) { if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //中断产生 { // printf(" in usart3 \n"); // USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除中断标志 /* 有数据来时,总线不空闲 */ uart_send.idleStateBat = 0; uart_send.BatState = 0; USART3_Rbuffer[0] = USART_ReceiveData(USART3); //接收数据 uart_device_info *dev = (uart_device_info *)g_bat485_uart3_handle; if(!RingQueueFull(&dev->uart_ring_queue)) InRingQueue(&dev->uart_ring_queue, USART3_Rbuffer[0]); } if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //中断产生 { uart_send.idleStateGw = 1; USART_ReceiveData(USART3); } // if(USART_GetITStatus(USART3, USART_FLAG_TXE) != RESET) //中断发送 // { // USART_SendData(USART3, uart_send.sendDataBat->data[uart_send.sendDataBat->Counter++]); // if (uart_send.sendDataBat->dataLen == uart_send.sendDataBat->Counter) { // USART_ITConfig(USART3, USART_IT_TXE, DISABLE); // uart_send.sendOverStateBat = 1; // uart_send.sendStateBat = 0; // uart_send.insertState++; //// printf("\n\n bat uart_send.insertState : %d \n\n", uart_send.insertState); // /* 插入指针指向为空时 */ // if (uart_send.insertData == NULL) { // if (!uart_send.data1.dataState) { // uart_send.insertData = &uart_send.data1; // } // if (!uart_send.data2.dataState) { // uart_send.insertData = &uart_send.data2; // } // if (!uart_send.data3.dataState) { // uart_send.insertData = &uart_send.data3; // } // } // Delay_Us(100); // bat485_tx_disenabla(); // } // } } /* * @brief USART4的串口中断处理函数 * @param * @retval */ void USART4_IRQHandler(void) { if(USART_GetITStatus(USART4, USART_IT_RXNE) != RESET) //中断产生 { /* 有数据来时,总线不空闲 */ uart_send.GwState = 0; uart_send.idleStateGw = 0; USART4_Rbuffer[0] = USART_ReceiveData(USART4); //接收数据 uart_device_info *dev = (uart_device_info *)g_gw485_uart4_handle; if(!RingQueueFull(&dev->uart_ring_queue)) InRingQueue(&dev->uart_ring_queue, USART4_Rbuffer[0]); } if(USART_GetITStatus(USART4, USART_IT_IDLE) != RESET) //中断产生 { uart_send.idleStateGw = 1; USART_ReceiveData(USART4); } // if(USART_GetITStatus(USART4, USART_FLAG_TXE) != RESET) //中断发送 // { //// USART_SendData(USART4, uart_send.sendDataGw->data[uart_send.sendDataGw->Counter++]); // //// USART_SendData(USART4, USART_Tbuffer[count++]); //// if (len == count) { //// USART_ITConfig(USART3, USART_IT_TXE, DISABLE); //////// } ////// if (uart_send.sendDataGw->dataLen <= uart_send.sendDataGw->Counter) { ////// USART_ITConfig(USART3, USART_IT_TXE, DISABLE); ////// uart_send.sendOverStateGw = 1; ////// uart_send.sendStateGw = 0; ////// uart_send.insertState++; ////// printf("\n\n Gw uart_send.insertState : %d \n\n", uart_send.insertState); ////// /* 插入指针指向为空时 */ ////// if (uart_send.insertData == NULL) { ////// if (!uart_send.data1.dataState) { ////// uart_send.insertData = &uart_send.data1; ////// } ////// if (!uart_send.data2.dataState) { ////// uart_send.insertData = &uart_send.data2; ////// } ////// if (!uart_send.data3.dataState) { ////// uart_send.insertData = &uart_send.data3; ////// } ////// } //// Delay_Us(100); //// gw485_tx_disenabla(); //// } // } // if(USART_GetFlagStatus(USART4,USART_FLAG_TC) == SET) //中断发送 // { // USART_SendData(USART4, USART4_Tbuffer[USART3_Tbuffer_Num++]); // if (USART4_Tbuffer_Len == USART4_Tbuffer_Num) { // USART4_Tbuffer_Num = 0; // USART_ITConfig(USART4, USART_IT_TC, DISABLE); //// USART_ClearFlag(USART3,USART_FLAG_ORE); //清标志 //// USART_ReceiveData(USART3); //读DR // } // } }