最近使用STM32G030c8t6做STM32F103C8T6 的替代,使用过程也是一波三折...
现学现卖的使用STM32cubeMx,下面是cubemx的串口配置
配置串口的IO 奇怪我这个版本还是怎么的,io只能是输出...但好在能用。
使能中断
常规配置 9600波特率 、8位数据 、无奇偶校验、1位停止位
收发模式
时钟就不说了
这个选项很友好,让main.c干净不少。接着就是生成代码了。
重点开始:
此部分参考了正点原子的代码
发送部分代码:
#include "stdio.h"
#include "stdarg.h"
#include "string.h"
/********/
uint8_t ubuf[256];
void u2_printf(char* fmt,...);
/********/
void u2_printf(char* fmt,...)
{
unsigned int i,length;
EN_485(1); //485使能,设置为发送模式
va_list ap;
va_start(ap,fmt);
vsprintf((char*)ubuf,fmt,ap);
va_end(ap);
length=strlen((const char*)ubuf);
while((USART2->ISR&0X40)==0); //g030 没有SR寄存器,等效的是ISR
for(i = 0;i < length;i ++)
{
USART2->TDR = ubuf
; //同样没有DR寄存器,等效的为TDR
while((USART2->ISR&0X40)==0);
}
EN_485(0);//485使能,设置为接收模式
}
此部分为正点原子的接收查询函数
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(uint8_t *buf,uint16_t *len)
{
uint16_t rxlen=RS485_RX_CNT;
uint16_t i=0;
*len=0; //默认为0
HAL_Delay(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 使用自带的HAL_Delay()函数
if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
{
for(i=0;i
{
buf=RS485_RX_BUF;
}
*len=RS485_RX_CNT; //记录本次数据长度
RS485_RX_CNT=0; //清零
}
}
uart.c中的 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) 函数
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//__HAL_UART_DISABLE_IT(&huart2,UART_IT_TC);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);//开启接收中断 ####这个很重要####
/* USER CODE END USART2_MspInit 1 */
}
}
接着就是 stm32g0xx_it.c 中的 void USART2_IRQHandler(void) 函数:
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint8_t res;
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE)!=RESET) //接收中断 UART_IT_RXNE
{
HAL_UART_Receive(&huart2,&res,1,1000);
if(RS485_RX_CNT<256)
{
RS485_RX_BUF[RS485_RX_CNT]=res; //记录接收到的值
RS485_RX_CNT++; //接收数据增加1
}
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);//开启接收中断 修改为此函数来再次打开中断后 程序接收正常 *********这里很重要,不添加就只能进入一次中断
/* USER CODE END USART2_IRQn 1 */
}
以下要注意了~
因为在之前的调试中参考论坛等解决办法,如:
我把第一个HAL_UART_Receive_IT(&huart1, rData, 1)函数放到了main.c函数的串口初始化之后(题主放在串口初始化函数里),然后就解决了。

此方法能够进入中断,在按照上述代码操作后,中断进入都正常了。但是发送测试是第一次发送数据是不能成功的,且第一个数据永远都是 0xb4 雷打不动~~~!!
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); //HAL_UART_Receive_IT(&huart2,rData,1); //不能加 千万不能加 我加了收到的第一个数据是0xB4 后面正常 MX_CRC_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ //HAL_UART_Receive_IT(&huart2,rData,1); //千万不能加
参考:https://my.oschina.net/u/3874841/blog/4359293

参考:https://blog.csdn.net/qq_45413245/article/details/104585026 区分几个容易搞混的函数
最近使用STM32G030c8t6做STM32F103C8T6 的替代,使用过程也是一波三折...
现学现卖的使用STM32cubeMx,下面是cubemx的串口配置
配置串口的IO 奇怪我这个版本还是怎么的,io只能是输出...但好在能用。
使能中断
常规配置 9600波特率 、8位数据 、无奇偶校验、1位停止位
收发模式
时钟就不说了
这个选项很友好,让main.c干净不少。接着就是生成代码了。
重点开始:
此部分参考了正点原子的代码
发送部分代码:
#include "stdio.h"
#include "stdarg.h"
#include "string.h"
/********/
uint8_t ubuf[256];
void u2_printf(char* fmt,...);
/********/
void u2_printf(char* fmt,...)
{
unsigned int i,length;
EN_485(1); //485使能,设置为发送模式
va_list ap;
va_start(ap,fmt);
vsprintf((char*)ubuf,fmt,ap);
va_end(ap);
length=strlen((const char*)ubuf);
while((USART2->ISR&0X40)==0); //g030 没有SR寄存器,等效的是ISR
for(i = 0;i < length;i ++)
{
USART2->TDR = ubuf
; //同样没有DR寄存器,等效的为TDR
while((USART2->ISR&0X40)==0);
}
EN_485(0);//485使能,设置为接收模式
}
此部分为正点原子的接收查询函数
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(uint8_t *buf,uint16_t *len)
{
uint16_t rxlen=RS485_RX_CNT;
uint16_t i=0;
*len=0; //默认为0
HAL_Delay(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 使用自带的HAL_Delay()函数
if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
{
for(i=0;i
{
buf=RS485_RX_BUF;
}
*len=RS485_RX_CNT; //记录本次数据长度
RS485_RX_CNT=0; //清零
}
}
uart.c中的 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) 函数
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//__HAL_UART_DISABLE_IT(&huart2,UART_IT_TC);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);//开启接收中断 ####这个很重要####
/* USER CODE END USART2_MspInit 1 */
}
}
接着就是 stm32g0xx_it.c 中的 void USART2_IRQHandler(void) 函数:
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint8_t res;
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE)!=RESET) //接收中断 UART_IT_RXNE
{
HAL_UART_Receive(&huart2,&res,1,1000);
if(RS485_RX_CNT<256)
{
RS485_RX_BUF[RS485_RX_CNT]=res; //记录接收到的值
RS485_RX_CNT++; //接收数据增加1
}
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);//开启接收中断 修改为此函数来再次打开中断后 程序接收正常 *********这里很重要,不添加就只能进入一次中断
/* USER CODE END USART2_IRQn 1 */
}
以下要注意了~
因为在之前的调试中参考论坛等解决办法,如:
我把第一个HAL_UART_Receive_IT(&huart1, rData, 1)函数放到了main.c函数的串口初始化之后(题主放在串口初始化函数里),然后就解决了。

此方法能够进入中断,在按照上述代码操作后,中断进入都正常了。但是发送测试是第一次发送数据是不能成功的,且第一个数据永远都是 0xb4 雷打不动~~~!!
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); //HAL_UART_Receive_IT(&huart2,rData,1); //不能加 千万不能加 我加了收到的第一个数据是0xB4 后面正常 MX_CRC_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ //HAL_UART_Receive_IT(&huart2,rData,1); //千万不能加
参考:https://my.oschina.net/u/3874841/blog/4359293

参考:https://blog.csdn.net/qq_45413245/article/details/104585026 区分几个容易搞混的函数
举报