CUBE MX结合Keil5 c/c++ STMF429混合编译调试记录

环境

CUBE MX 6.10.9

Keil 5.39

编译环境通之前的“CUBE MX结合Keil5 c/c++ STMF412混合编译调试记录”

编译出现错误

keil5调试一直卡在BEAB BKPT 0XAB

问题现象:

keil5调试一直卡在BEAB BKPT 0XAB

解决方案:

printf重定义c++不能正确链接,参考"CUBE MX结合Keil5 c/c++ STMF412混合编译调试记录"-“printf重定义报错“章节。

串口1DMA接收数据和数据长度为0

问题描述:串口DMA中断数据全0,数据长度也为0

rx_len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //计算出数据长度

检查dma.c发现cube模型没有生成以下函数:

/* DMA interrupt init */
  /* DMA1_Stream5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  /* DMA2_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
  /* DMA2_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  /* DMA2_Stream4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
  /* DMA2_Stream5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);

解决方案:原因不明,估计是哪个寄存器设置有问题。我先用单字节串口接收程序调通后再换回DMA接收,换回去后DMA可正常接收,串口参数、引脚配置没有变化。

除了CUBEMX生成的代码(未改过),我的代码如下:

//main.c
/* USER CODE BEGIN 2 */
	myPCHuart = huart1;
	Config_Serial_Init();


************************************************************

stm32f4xx_it.c

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
#if((!UART_SINGLE_BYTE_RECV) == 1)
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
#endif
	myPcUSART_IRQHandler();
  /* USER CODE END USART1_IRQn 1 */
}


**************************************************************
//自定义c文件串口接收函数
void myPcUSART_IRQHandler()
{
#if((!UART_SINGLE_BYTE_RECV) == 1)
#if (ADSB_IN)
	/*当DMA正常使用时启用*/
	// 定义变量
	extern uint8_t uart1_rx_buffer[BUFFER_SIZE];//接收数组
	uint8_t rx_len = 0; //接收到的数据长度
	if (__HAL_UART_GET_FLAG(&myPCHuart,UART_FLAG_IDLE) != RESET)// 通过IDLE标志位判断接收是否结束
  { 
      
      HAL_UART_DMAStop(&myPCHuart);             
			//int dmaLen = __HAL_DMA_GET_COUNTER(&myHdma_usart_rx); 		 
      rx_len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&myHdma_usart_rx); //计算出数据长度
			 if(uart1_rx_buffer[0] == '!')
				{
					//Config_RecHandler(uart1_rx_buffer);
					Config_RecHandler_String(uart1_rx_buffer);  // DMA命令处理
				}
				else
				{
					RingBuffer_Write(&rx_buffer_ring,uart1_rx_buffer,rx_len);
				}
#if(DEBUG_MSG)
				//RingBuffer_Read(&rx_buffer_ring,uart1_rx_buffer,rx_len);
				// 发送接收到的数据
				//printf("USART1_Ring Received:%s\r\n",uart1_rx_buffer);//打印接收到的数据
				memset(uart1_rx_buffer,0,rx_len);
      
      
			HAL_UART_Transmit(&huart1, uart1_rx_buffer,rx_len,1000);//将收到的数据发送出去
#endif
			__HAL_DMA_SET_COUNTER(&myHdma_usart_rx, BUFFER_SIZE);
      HAL_UART_Receive_DMA(&myPCHuart,uart1_rx_buffer,BUFFER_SIZE);//开启DMA接收,方便下一次接收数据
			__HAL_UART_CLEAR_IDLEFLAG(&myPCHuart);//清除标志位
   }
#endif
#else
		USART1->SR &= ~USART_SR_RXNE;   
		unsigned char ch = USART1->DR;
		//RingBuffer_Byte_Write(&PCData_rx_ring,ch);
		Config_RecHandler(ch);
#endif
}

EC11 knob旋钮编码器无法进入HAL_TIM_IC_CaptureCallback中断

问题描述:EC11采用定时器Encoder采样,CUBEMX生成代码后无法进入EC11 knob旋钮编码器无法进入HAL_TIM_IC_CaptureCallback中断

配置如下:

解决方案:按照上图配置NVIC(最后两张配置截图)

配置SSD1312 OLED显示屏

纯代码配置:

使用CUBEMX配置好相关引脚为OUT PUT(不用CUBE配置SPI)引脚(DC、RES、CS、SDA、SCL),其中CS为spi的NSS,SDA一般为spi的MOSI,SCL为spi的CLK脚。并在OLED头文件添加以下代码:

/*外设配置区 Start*/
//-----------------OLED端口定义----------------

#define OLED_SCLK_Clr() HAL_GPIO_WritePin(OLED_SCK_GPIO_Port,OLED_SCK_Pin,GPIO_PIN_RESET)//SCL  即SPI-CLK引脚
#define OLED_SCLK_Set() HAL_GPIO_WritePin(OLED_SCK_GPIO_Port,OLED_SCK_Pin,GPIO_PIN_SET)

#define OLED_SDIN_Clr() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_RESET)//DIN	即SPI-MOSI引脚
#define OLED_SDIN_Set() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_SET)

#define OLED_RES_Clr() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_RESET)//RES
#define OLED_RES_Set() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_SET)

#define OLED_DC_Clr() HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_RESET)//DC
#define OLED_DC_Set() HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_SET)
 		     
#define OLED_CS_Clr()  HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_RESET)//CS		即SPI-NSS引脚
#define OLED_CS_Set()  HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_SET)
/*外设配置区 Start*/

然后将oled_ssd13xx.h和oled_ssd13xx.c文件移植进去,此时可以点亮屏幕,加入knob_EC11_key.h和knob_EC11_key.c旋钮按键和oled_panel.c即可添加GUI交互显示业务。

HAL_Delay(10);导致程序卡死

原因:下面代码破坏了SysTick,调用后恢复即可

SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器

	// 重新初始化SysTick定时器
	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
程序中调用了下面函数
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器

}


修改为:
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器

	// 重新初始化SysTick定时器
	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}

0.5微秒定时器中断问题

问题描述:理论上,180MHz的系统

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值