HT32F52352学习笔记之五
经过一小段时间的奋战,终于是把串口通信的相关代码编写并调试完成了。可以实现接收中断、发送数据、经过重定向的printf、puts、getchar、scanf都可以通过串口的方式实现输出输入。另外,由于使用的是HT32F52352的最小系统板,在发送数据时可不外接CH340模块,但是要实现接收数据一定一定要外接CH340模块,我也不知道为什么会这样,真的服了,被这个不需要外接CH340模块就能发送数据给电脑给迷惑了,导致用电脑发数据给芯片时一直进不了中断函数,不过能用就行了。另外,在重定向时还需要注意一定要把printf.c里的signed int printf(const char *f, ...)、signed int puts(const char *pString)以及ht32_retarget.c里的int fputc (int ch, FILE *f)、int fgetc (FILE *f)注释掉,不然编译器会报错Error: L6200E: Symbol printf multiply defined (by printfa.o and printf.o).注释掉就不会出现这样的错误了。
另外,根据数据手册上的说明,USART的引脚是需要进行复用初始化的。和STM32F103不一样的是HT32F52352不需要对Rx、Tx的GPIO引脚进行配置,只需要复位初始化即可使用。而且可以当作USART1、USART0 的Rx、Tx引脚不止四个,但是一共只有两个串口。
主要的代码:
(1)USART初始化
#include "usart.h"
static void USART_CKCU_Config()
{
CKCU_PeripClockConfig_TypeDef CCLOCK;
CCLOCK.Bit.AFIO = 1;
COM_CLK(CCLOCK) = 1;
CKCU_PeripClockConfig(CCLOCK, ENABLE);
}
static void USART_AFIO_Config()
{
AFIO_GPxConfig(COM_TX_GPIO_ID, COM_TX_AFIO_PIN, AFIO_FUN_USART_UART);
AFIO_GPxConfig(COM_RX_GPIO_ID, COM_RX_AFIO_PIN, AFIO_FUN_USART_UART);
}
static void USARTx_Config()
{
USART_InitTypeDef USART_InitStructure;
/*USART初始化
*波特率:115200
*字节长度:8位
*停止位:1位
*校验位:无
*模式:正常模式
**/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
USART_InitStructure.USART_Parity = USART_PARITY_NO;
USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
USART_Init(COM_PORT , &USART_InitStructure);
/* 设置USART中断标志 */
USART_IntConfig(COM_PORT, USART_INT_RXDR, ENABLE);
/* 使能USART接收、发送 */
USART_TxCmd(COM_PORT, ENABLE);
USART_RxCmd(COM_PORT, ENABLE);
/* 初始化中断 */
NVIC_EnableIRQ(COM_IRQn);
}
void USARTx_Init()
{
USART_CKCU_Config();
USART_AFIO_Config();
USARTx_Config();
}
// 发送一个字节
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 Data)
{
USART_SendData(COM_PORT, Data);
// 等待发送数据寄存器清空
while (USART_GetFlagStatus(COM_PORT, USART_FLAG_TXDE) == RESET);
}
//发送每个元素数据长度为8位的数组
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num)
{
u8 i;
for( i = 0;i < num;i++)
{
Usart_Sendbyte(USARTx,*array);
array++;
}
}
// 发送字符串
void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str)
{
uint8_t i;
for(i = 0;str[i] != '\0';i++)
{
Usart_Sendbyte(USARTx,str[i]);
}
}
// 重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
USART_SendData(COM_PORT, (uint8_t) ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(COM_PORT, USART_FLAG_TXDE) == RESET);
return (ch);
}
// 重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(COM_PORT, USART_FLAG_RXDNE) == RESET);
return (int)USART_ReceiveData(COM_PORT);
}
(2)中断函数:
void COM_IRQHandler(void)
{
u8 data;
if( USART_GetFlagStatus(COM_PORT, USART_FLAG_RXDR) )
{
data = USART_ReceiveData(COM_PORT);
printf("data = %c\n",data);
}
}
对硬件方面(如引脚、模式选择等的封装):
#ifndef _USART_H
#define _USART_H
#include "ht32f5xxxx_01.h"
#include <stdio.h>
#define DEBUG_USART0 (0)
#define DEBUG_USART1 (1)
#if DEBUG_USART0
//串口0 USART - 0
#define COM_CLK(CK) (CK.Bit.USART0)
#define COM_PORT (HT_USART0)
#define COM_IRQn (USART0_IRQn)
#define COM_IRQHandler (USART0_IRQHandler)
#define COM_TX_GPIO_ID (GPIO_PA)
#define COM_TX_AFIO_PIN (AFIO_PIN_2)
#define COM_TX_AFIO_MODE (AFIO_FUN_USART_UART)
#define COM_RX_GPIO_ID (GPIO_PA)
#define COM_RX_AFIO_PIN (AFIO_PIN_3)
#define COM_RX_AFIO_MODE (AFIO_FUN_USART_UART)
#elif DEBUG_USART1
//串口1 USART - 1
#define COM_CLK(CK) (CK.Bit.USART1)
#define COM_PORT (HT_USART1)
#define COM_IRQn (USART1_IRQn)
#define COM_IRQHandler (USART1_IRQHandler)
#define COM_TX_GPIO_ID (GPIO_PA)
#define COM_TX_AFIO_PIN (AFIO_PIN_4)
#define COM_TX_AFIO_MODE (AFIO_FUN_USART_UART)
#define COM_RX_GPIO_ID (GPIO_PA)
#define COM_RX_AFIO_PIN (AFIO_PIN_5)
#define COM_RX_AFIO_MODE (AFIO_FUN_USART_UART)
#endif
void USARTx_Init(void);
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 Data);
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num);
void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str);
#endif
用到的库函数:
(1)USART初始化结构体
/* USART Mode ----------------------------------------------------------------------------------------------*/
/** @defgroup USART_Mode Definitions of USART mode
* @{
*/
#define USART_MODE_NORMAL ((u32)0x00000000)
#define USART_MODE_IRDA ((u32)0x00000001)
#define USART_MODE_RS485 ((u32)0x00000002)
#define USART_MODE_SYNCHRONOUS ((u32)0x00000003)
/* USART Parity --------------------------------------------------------------------------------------------*/
/** @defgroup USART_Parity Definitions of USART parity
* @{
*/
#define USART_PARITY_NO ((u32)0x00000000)
#define USART_PARITY_EVEN ((u32)0x00001800)
#define USART_PARITY_ODD ((u32)0x00000800)
/* USART Stop Bits -----------------------------------------------------------------------------------------*/
/** @defgroup USART_Stop_Bit Definitions of USART stop bit
* @{
*/
#define USART_STOPBITS_1 ((u32)0x00000000)
#define USART_STOPBITS_2 ((u32)0x00000400)
/* USART Word Length ---------------------------------------------------------------------------------------*/
/** @defgroup USART_Word_Length Definitions of USART word length
* @{
*/
#define USART_WORDLENGTH_7B ((u32)0x00000000)
#define USART_WORDLENGTH_8B ((u32)0x00000100)
#define USART_WORDLENGTH_9B ((u32)0x00000200)
/* Definition of USART Init Structure ---------------------------------------------------------------------*/
typedef struct
{
u32 USART_BaudRate;
u16 USART_WordLength;
u16 USART_StopBits;
u16 USART_Parity;
u16 USART_Mode;
} USART_InitTypeDef;
(2)USART初始化函数
/*********************************************************************************************************//**
* @brief Initialize the USART/UART peripheral according to the specified parameters in the USART_InitStruct.
* @param USARTx: Parameter to select the UxART peripheral.
* @param USART_InitStruct: pointer to a USART_InitTypeDef structure.
* @retval None
************************************************************************************************************/
void USART_Init(HT_USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
(3)USART中断标志设置函数(文末附带对USART 中断使能寄存器 – USRIER的说明)
/*********************************************************************************************************//**
* @brief Enable or Disable the USART/UART interrupts.
* @param USARTx: Parameter to select the UxART peripheral.
* @param USART_INT_x: Specify if the USART/UART interrupt source to be enabled or disabled.
* This parameter can be one of the following values:
* @arg USART_INT_RXDR :(u32)0x00000001
* @arg USART_INT_TXDE :(u32)0x00000002
* @arg USART_INT_TXC :(u32)0x00000004
* @arg USART_INT_OE :(u32)0x00000008
* @arg USART_INT_PE :(u32)0x00000010
* @arg USART_INT_FE :(u32)0x00000020
* @arg USART_INT_BI :(u32)0x00000040
* @arg USART_INT_RSADD :(u32)0x00000080
* @arg USART_INT_TOUT :(u32)0x00000100
* @arg USART_INT_CTS :(u32)0x00000200
* @param NewState: This parameter can be ENABLE or DISABLE.
* @retval None
************************************************************************************************************/
void USART_IntConfig(HT_USART_TypeDef* USARTx, u32 USART_INT_x, ControlStatus NewState)
(4)USART Rx/Tx使能函数
#define USART_TxCmd(USARTx, NewState) USART_TxRxCmd(USARTx, USART_CMD_TX, NewState)
#define USART_RxCmd(USARTx, NewState) USART_TxRxCmd(USARTx, USART_CMD_RX, NewState)
/*********************************************************************************************************//**
* @brief Enable or Disable the USART Tx/Rx.
* @param USARTx: Parameter to select the USART peripheral.
* @param TxRx: This parameter can be USART_CMD_TX or USART_CMD_RX.
* @param NewState: This parameter can be ENABLE or DISABLE.
* @retval None
************************************************************************************************************/
void USART_TxRxCmd(HT_USART_TypeDef* USARTx,u32 TxRx, ControlStatus NewState)
(5)NVIC初始化中断函数
// 就是那个找不到声明和定义的初始化中断函数
NVIC_EnableIRQ(COM_IRQn);
对USART 中断使能寄存器 – USRIER的说明: