单片机型号:STM32L051C8T6
开发环境MDK5.12
库版本:STM32L0xx_HAL_Driver V1.1.0
主机环境:Windows XP
之前一直使用的STM32F030C8T6单片机来做开发,因需求更改更换了一个新型号STM32L051C8T6,主要是用到了其低功耗特性,本以为直接把代码拷贝一下就可以使用了,结果是太天真了,STM32F030C8T6使用的库是STM32F0_StdPeriph_Lib而STM32L051C8T6使用的库是STM32L0xx_HAL_Driver两者的差别还是很大的,而且官方也推荐使用后者,没办法,重新学习一下吧。。。参考其例程磕磕绊绊的勉强可以写一个工程了,这里写一下有关UART的调试。
参考的程序是STM32L053R8-Nucleo例程中的UART_TwoBoards_ComIT工程,采用中断方式来进行两个单片机之间的通信。STM32L0xx_HAL_Driver库的分层更加明显,板极初始化代码如下
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USART1 clock */
USARTx_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the NVIC for UART ########################################*/
/* NVIC for USART1 */
HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
}
/**
* @brief UART MSP De-Initialization
* This function frees the hardware resources used in this example:
* - Disable the Peripheral's clock
* - Revert GPIO and NVIC configuration to their default state
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
/*##-1- Reset peripherals ##################################################*/
USARTx_FORCE_RESET();
USARTx_RELEASE_RESET();
/*##-2- Disable peripherals and GPIO Clocks #################################*/
/* Configure UART Tx as alternate function */
HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
/* Configure UART Rx as alternate function */
HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);
/*##-3- Disable the NVIC for UART ##########################################*/
HAL_NVIC_DisableIRQ(USARTx_IRQn);
}
/**********************************************************************
函数:uart_init()
函数作用:串口初始化
参数:
uint32_t BaudRate=========================串口波特率
返回值:无
上一版本:无
当前版本:1.0
作者:
最后修改时间:2015-04-02
说明:
**********************************************************************/
void uart_init(uint32_t BaudRate)
{
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = BaudRate;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}
__HAL_UART_ENABLE(&UartHandle);
NVIC_SetPriority(USARTx_IRQn,0);
NVIC_EnableIRQ(USARTx_IRQn);
uart_rev.front = aRxBuffer;
uart_rev.rear = aRxBuffer; //两个指针指向相同的地址空间
if(HAL_UART_Receive_IT(&UartHandle,(uint8_t*)aRxBuffer,1) != HAL_OK)
{
Error_Handler();
}
}
struct uart
{
uint8_t *rear; //在中断函数中更改
uint8_t *front; //在主循环中更改
};
void USARTx_IRQHandler(void)
{
HAL_UART_IRQHandler(& UartHandle);
}
在HAL_UART_IRQHandler()中会自动调用串口接收中断的回调函数
/**
* @brief Rx Transfer completed callback
* @param UartHandle: UART handle
* @note This example shows a simple way to report end of IT Rx transfer, and
* you can add your own implementation.
* @retval None
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint8_t ret = HAL_OK;
/* Set transmission flag: trasfer complete*/
uart_rev.rear++; //更新rear指针
if(uart_rev.rear >= (aRxBuffer + BUFFSIZE))
uart_rev.rear = aRxBuffer;
do
{
ret = HAL_UART_Receive_IT(UartHandle,uart_rev.rear,1);
}while(ret != HAL_OK);
}
/**********************************************************************
函数:uart_read()
函数作用:从接收缓冲区中读取数据
参数:
uint8_t *fmt--------------------------------接收到的数据
uint16_t time_out---------------------------超时时间
返回值:0:读取到数据-1:没有读取到数据
上一版本:无
当前版本:1.0
作者:
最后修改时间:2015-04-08
说明:
**********************************************************************/
int8_t uart_read(uint8_t *fmt, uint16_t time_out)
{
while(time_out)
{
if(uart_rev.front != uart_rev.rear)
{
//如果队首指针和队尾指针不同表明缓冲区中有数据还未收取
*fmt=*uart_rev.front;
uart_rev.front++;
if (uart_rev.front >= (aRxBuffer+BUFFSIZE))
uart_rev.front = aRxBuffer;
return 0;
}
time_out--;
}
return (int8_t)-1;
}
#include "UART.h"
#include "stm32l0xx_hal_def.h"
#include "utils.h"
UART_HandleTypeDef UartHandle;
uint8_t aRxBuffer[BUFFSIZE];
struct uart uart_rev;
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USART1 clock */
USARTx_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the NVIC for UART ########################################*/
/* NVIC for USART1 */
HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
}
/**
* @brief UART MSP De-Initialization
* This function frees the hardware resources used in this example:
* - Disable the Peripheral's clock
* - Revert GPIO and NVIC configuration to their default state
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
/*##-1- Reset peripherals ##################################################*/
USARTx_FORCE_RESET();
USARTx_RELEASE_RESET();
/*##-2- Disable peripherals and GPIO Clocks #################################*/
/* Configure UART Tx as alternate function */
HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
/* Configure UART Rx as alternate function */
HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);
/*##-3- Disable the NVIC for UART ##########################################*/
HAL_NVIC_DisableIRQ(USARTx_IRQn);
}
/**********************************************************************
函数:uart_init()
函数作用:串口初始化
参数:
uint32_t BaudRate=========================串口波特率
返回值:无
上一版本:无
当前版本:1.0
作者:
最后修改时间:2015-04-02
说明:
**********************************************************************/
void uart_init(uint32_t BaudRate)
{
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = BaudRate;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}
__HAL_UART_ENABLE(&UartHandle);
NVIC_SetPriority(USARTx_IRQn,0);
NVIC_EnableIRQ(USARTx_IRQn);
uart_rev.front = aRxBuffer;
uart_rev.rear = aRxBuffer; //两个指针指向相同的地址空间
if(HAL_UART_Receive_IT(&UartHandle,(uint8_t*)aRxBuffer,1) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
while(1)
{
}
}
/**********************************************************************
函数:uart_read()
函数作用:从接收缓冲区中读取数据
参数:
uint8_t *fmt--------------------------------接收到的数据
uint16_t time_out---------------------------超时时间
返回值:0:读取到数据-1:没有读取到数据
上一版本:无
当前版本:1.0
作者:
最后修改时间:2015-04-08
说明:
**********************************************************************/
int8_t uart_read(uint8_t *fmt, uint16_t time_out)
{
while(time_out)
{
if(uart_rev.front != uart_rev.rear)
{
//如果队首指针和队尾指针不同表明缓冲区中有数据还未收取
*fmt=*uart_rev.front;
uart_rev.front++;
if (uart_rev.front >= (aRxBuffer+BUFFSIZE))
uart_rev.front = aRxBuffer;
return 0;
}
time_out--;
}
return (int8_t)-1;
}
int8_t uart_send(uint8_t *fmt, uint8_t len)
{
while(len)
{
printf("%c",*fmt);
fmt++;
len--;
}
return 0;
}
#ifdef UART_DEBUG
int fputc(int ch, FILE *f)
{
USART1->TDR = ch;
while(!(USART1->ISR & USART_ISR_TXE));
return(ch);
}
#endif
/**
* @brief Tx Transfer completed callback
* @param UartHandle: UART handle.
* @note This example shows a simple way to report end of IT Tx transfer, and
* you can add your own implementation.
* @retval None
*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)
{
uint8_t ret = HAL_OK;
UartReady = SET;
#if 1
uart_snd.front++; //更新rear指针
if(uart_snd.front >= (aTxBuffer + BUFFSIZE))
uart_snd.front = aTxBuffer;
if(uart_snd.front != uart_snd.rear)
{
//如果队首指针和队尾指针不同表明缓冲区中有数据还未发送
do
{
ret = HAL_UART_Transmit_IT(&UartHandle,uart_snd.front,1);//请求发送下一个数据
}while(ret != HAL_OK);
}
#endif
}
/**
* @brief Rx Transfer completed callback
* @param UartHandle: UART handle
* @note This example shows a simple way to report end of IT Rx transfer, and
* you can add your own implementation.
* @retval None
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint8_t ret = HAL_OK;
/* Set transmission flag: trasfer complete*/
uart_rev.rear++; //更新rear指针
if(uart_rev.rear >= (aRxBuffer + BUFFSIZE))
uart_rev.rear = aRxBuffer;
do
{
ret = HAL_UART_Receive_IT(UartHandle,uart_rev.rear,1);
}while(ret != HAL_OK);
}
/******************************************************************************/
/* STM32L0xx Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handler's name please refer to the startup */
/* file (startup_stm32l0xx.s). */
/******************************************************************************/
/**
* @brief This function handles UART interrupt request.
* @param None
* @retval None
* @Note This function is redefined in "main.h" and related to DMA stream
* used for USART data transmission
*/
void USARTx_IRQHandler(void)
{
HAL_UART_IRQHandler(& UartHandle);
}