历史上的今天
今天是:2025年07月30日(星期三)
2019年07月30日 | stm32f4手动添加HAL库模块
2019-07-30 来源:eefocus
以uart为例
首先打开stm32f4xx_hal_conf.h中的define:

然后在工程中添加相关的.c文件

定义模块初始化函数,并在main中调用
/* USART3 init function */
static void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 19200;//9600;//
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
在stm32f4xx_hal_msp.c中定义模块的MspInit和Deinit(一般没啥用,主要是Init)设置gpio,dma及中断等配置
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
/* USER CODE END USART3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
/**USART3 GPIO Configuration
PC10 ------> USART3_TX
PC11 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART3 DMA Init */
/* USART3_TX Init */
hdma_usart3_tx.Instance = DMA1_Stream3;
hdma_usart3_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart3_tx);
/* USART3_RX Init */
hdma_usart3_rx.Instance = DMA1_Stream1;
hdma_usart3_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_NORMAL;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart3_rx);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */
/* USER CODE END USART3_MspInit 1 */
}
}
如果使能了中断,在stm32f4xx_it.c中定义模块中断句柄,这个文件中缺少中断句柄会导致hardfault
extern uint8_t recv_end_flag;
extern uint8_t Rx_len;
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
uint32_t temp;
/* 如果是串口3中断 */
if(USART3 == huart3.Instance)
{
/* 如果是串口3IDLE中断 */
if(RESET != __HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE))
{
/* 清除中断标志 */
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
/* 停止DMA接收 */
HAL_UART_DMAStop(&huart3);
/* 获取DMA当前还有多少未填充 */
temp = __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
/* 计算串口接收到的数据个数 */
Rx_len = 100 - temp;
recv_end_flag = 1;
}
}
/* USER CODE END USART3_IRQn 1 */
}
在相应的位置包含stm32f4xx_hal.h文件,就可以调用模块stm32f4xx_hal_uart.h中的接口了
/* IO operation functions *******************************************************/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
史海拾趣
|
如今,汽车制造业已经与软件结下了不解之缘。不仅如此,汽车制造业已经深陷于软件危机之中。问题不是出在汽车制造业,这种软件危机只不过是设备软件产业本身所面临压力的间接反映而已。如今,新产品能够获得的市场窗口期非常狭窄,而功能上的复 ...… 查看全部问答> |
|
第1章 数字电子技术基础 119页.ppt 第2章 组合逻辑电路 136页.ppt 第3章 时序逻辑电路 171页.ppt 第4章 脉冲信号的产生与整形 46页.ppt 第5章 数模和模数转换 29页.ppt 数字电子技术.ppt… 查看全部问答> |
|
我的bsp里面有stepldr和eboot, 我想让eboot跑起来, 但把stepldr.nb1烧写到flash中后,在dnw上显示的却是乱码!!!! 这个是串口的初始代码: void Uart_Init(void) { int i; rUFCON1 = 0x0;   ...… 查看全部问答> |
|
现在的IP地址已经不够用了,但是依然可以使用非独立的IP地址来访问网络。 例如我的IP:10.15.1.79[mask:255.255.0.0],这个应该肯定不是独立IP了。 如果我要给外网发送一个IP报(140.252.0.1),可以判断是外网,就可以通过默认路由转发这个IP报。 ...… 查看全部问答> |
|
两个函数分别是微秒和毫秒的延时,精确度在5%以内。LPC1343应该不适合,毕竟M3不想M0,有流水。 void sleepUs(uint32_t us){ // 1us base on 12MHz = 2, 50MHz = 8; uint32_t i = (us ...… 查看全部问答> |
|
请问版主和高手们: AD中的参考电压怎么选择,内部参考电压何时用2.5V和1.5V,ADC12MCTLx中的Sref位的参考电压源应该根据什么选择。对此我不明白,请懂的朋友给解释一下,谢谢了!!… 查看全部问答> |




