STM32G030C8T6 串口调试 (中断接收,prinf发送)使用cubemx+keil

最近使用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[i];            //同样没有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<rxlen;i++)
		{
			buf[i]=RS485_RX_BUF[i];	
		}		
		*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    区分几个容易搞混的函数

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用KeilSTM32F103C8T6实现HC-05蓝牙接收字符串的步骤: 1. 在Keil中创建一个新的工程,并选择适当的芯片型号。 2. 在工程文件夹中创建一个新的C文件,命名为main.c。 3. 在main.c文件中添加必要的头文件和宏定义: ``` #include "stm32f10x.h" #include <stdio.h> #define USART_TX_PIN GPIO_Pin_9 #define USART_RX_PIN GPIO_Pin_10 #define USART_GPIO GPIOA #define USART USART1 ``` 4. 在main函数中初始化USART串口通信: ``` int main(void) { // 初始化USART串口通信 USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 使能USART和GPIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置USART的引脚 GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(USART_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USART_GPIO, &GPIO_InitStructure); // 配置USART USART_InitStructure.USART_BaudRate = 9600; 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_Rx | USART_Mode_Tx; USART_Init(USART, &USART_InitStructure); // 配置USART中断 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART, USART_IT_RXNE, ENABLE); USART_Cmd(USART, ENABLE); while (1) {} } ``` 5. 实现USART的中断处理函数: ``` void USART1_IRQHandler(void) { if (USART_GetITStatus(USART, USART_IT_RXNE) != RESET) { char ch = USART_ReceiveData(USART); printf("%c", ch); } } ``` 6. 在main函数中添加一个无限循环来保持程序运行。 7. 在工程选项中配置串口的调试输出,以便在调试期间查看串口接收到的数据。 8. 将HC-05蓝牙模块连接到STM32F103C8T6开发板的USART1串口引脚。 9. 启动程序并开始与HC-05蓝牙模块进行通信。你应该能够通过Keil的调试输出窗口看到串口接收到的数据。 注意:此示例仅适用于接收字符串,如果你需要发送数据,请使用USART_SendData函数发送数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值