1、PY32F003F18复用功能总结:
//GPIOx=GPIOA,Pin=GPIO_PIN_0,alternate=GPIO_AF9_USART2,则将PA0引脚复用为USART2_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_0,alternate=GPIO_AF10_SPI1,则将PA0引脚复用为SPI1_MISO
//GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF0_SPI1,则将PA1引脚复用为SPI1_SCK
//GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF9_USART2,则将PA1引脚复用为USART2_RX
//GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF10_SPI1,则将PA1引脚复用为SPI1_MOSI
//GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF0_SPI1,则将PA2引脚复用为SPI1_MOSI
//GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF1_USART1,则将PA2引脚复用为USART1_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF4_USART2,则将PA2引脚复用为USART2_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF10_SPI1,则将PA2引脚复用为SPI1_SCK
//GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF12_I2C,则将PA2引脚复用为I2C_SDA
//GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF1_USART1,则将PA3引脚复用为USART1_RX
//GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF4_USART2,则将PA3引脚复用为USART2_RX
//GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF10_SPI1,则将PA3引脚复用为SPI1_MOSI
//GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF12_I2C,则将PA3引脚复用为I2C_SCL
//GPIOx=GPIOA,Pin=GPIO_PIN_4,alternate=GPIO_AF9_USART2,则将PA4引脚复用为USART2_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_5,alternate=GPIO_AF0_SPI1,则将PA5引脚复用为SPI1_SCK
//GPIOx=GPIOA,Pin=GPIO_PIN_5,alternate=GPIO_AF9_USART2,则将PA5引脚复用为USART2_RX
//GPIOx=GPIOA,Pin=GPIO_PIN_6,alternate=GPIO_AF0_SPI1,则将PA6引脚复用为SPI1_MISO
//GPIOx=GPIOA,Pin=GPIO_PIN_6,alternate=GPIO_AF15_RTCOUT,则将PA6引脚复用为RTC_OUT
//GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF0_SPI1,则将PA7引脚复用为SPI1_MOSI
//GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF8_USART1,则将PA7引脚复用为USART1_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF9_USART2,则将PA7引脚复用为USART2_TX
//GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF10_SPI1,则将PA7引脚复用为SPI1_MISO
//GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF12_I2C,则将PA7引脚复用为I2C_SDA
//GPIOx=GPIOA,Pin=GPIO_PIN_12,alternate=GPIO_AF0_SPI1,则将PA12引脚复用为SPI1_MOSI
//GPIOx=GPIOA,Pin=GPIO_PIN_12,alternate=GPIO_AF6_I2C,则将PA12引脚复用为I2C_SDA
//GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF0_SWJ,则将PA13引脚复用为SWDIO
//GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF8_USART1,则将PA13引脚复用为USART1_RX,通常不要占用SWDIO
//GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF10_SPI1,则将PA13引脚复用为SPI1_MISO,通常不要占用SWDIO
//GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF0_SWJ,则将PA14引脚复用为SWCLK
//GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF1_USART1,则将PA14引脚复用为USART1_TX,通常不要占用SWCLK
//GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF4_USART2,则将PA14引脚复用为USART2_TX,通常不要占用SWCLK
//GPIOx=GPIOB,Pin=GPIO_PIN_5,alternate=GPIO_AF0_SPI1,则将PB5引脚复用为SPI1_MOSI
//GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF0_USART1,则将PB6引脚复用为USART1_TX
//GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF4_USART2,则将PB6引脚复用为USART2_TX
//GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF6_I2C,则将PB6引脚复用为I2C_SCL
//GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF0_USART1,则将PB7引脚复用为USART1_RX
//GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF4_USART2,则将PB7引脚复用为USART2_RX
//GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF6_I2C,则将PB7引脚复用为I2C_SDA
2、PY32F003F18重定义fputc函数
//重定义fputc函数
//函数功能:发送ch的值给USART2串口
int fputc(int ch, FILE *f)
{
uint32_t isrflags;
USART2->DR = (uint8_t)(ch & 0xFFU);
//将ch写入串口数据寄存器(USART_DR),Send a byte to USART
while(1)
{
isrflags = READ_REG(USART2->SR);//读"串口状态寄存器(USART_SR)"
if((isrflags & USART_SR_TXE) != RESET)//如果TXE=1,即串口发送完成
break;
}
return (ch);
}
3、测试程序
#include "USART2.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
//PA0 ------> USART2_TX
//PA1 ------> USART2_RX
void USART2_GPIO_Config(void);
void USART2_NVIC_Cpnfig(void);
void USART2_Mode_Config(uint32_t baudrate);
void USART2_Init(uint32_t baudrate);
void USART2_Load_Send_Data(void);
//函数功能:USART2的IO口配置,PA0是为USART2_TX,PA1是USART2_RX
void USART2_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructureure;
__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
GPIO_InitStructureure.Pin = GPIO_PIN_0; //选择第0脚,PA0是为USART2_TX
GPIO_InitStructureure.Mode = GPIO_MODE_AF_PP; //复用功能推挽模式
GPIO_InitStructureure.Pull = GPIO_PULLUP; //引脚上拉被激活
GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速
GPIO_InitStructureure.Alternate = GPIO_AF9_USART2; //将引脚复用为USART2
HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);
//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器
//将PA0初始化为USART2_TX
GPIO_InitStructureure.Pin = GPIO_PIN_1; //选择第1脚,PA1是USART2_RX
GPIO_InitStructureure.Mode = GPIO_MODE_AF_PP; //复用功能推挽模式
GPIO_InitStructureure.Pull = GPIO_PULLUP; //引脚上拉被激活
GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速
GPIO_InitStructureure.Alternate = GPIO_AF9_USART2; //将引脚复用为USART2
HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);
//根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器
//将PA1初始化为USART2_RX
}
//函数功能:设置串口2中断优先级为0x01
void USART2_NVIC_Cpnfig(void)
{
HAL_NVIC_SetPriority(USART2_IRQn, 0x01, 0);
//设置串口2中断优先级为0x01,0无意义.USART2_IRQn表示中断源为串口2
}
//函数功能:波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Mode_Config(uint32_t baudrate)
{
UART_HandleTypeDef UART_HandleStructureure;
HAL_StatusTypeDef retData;
__HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟
UART_HandleStructureure.Instance = USART2; //接口为USART2
UART_HandleStructureure.Init.BaudRate = baudrate; //波特率为115200bps
UART_HandleStructureure.Init.WordLength = UART_WORDLENGTH_8B; //串口字长度为8
UART_HandleStructureure.Init.StopBits = UART_STOPBITS_1; //串口停止位为1位
UART_HandleStructureure.Init.Parity = UART_PARITY_NONE; //串口无需奇偶校验
UART_HandleStructureure.Init.HwFlowCtl = UART_HWCONTROL_NONE; //串口无硬件流程控制
UART_HandleStructureure.Init.Mode = UART_MODE_TX_RX; //串口工作模式为发送和接收模式
retData=HAL_UART_Init(&UART_HandleStructureure);
//根据UART_HandleStructureure型结构初始化USART2
if ( retData!= HAL_OK)//串口初始化失败
{
}
// __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_PE);
// //串口接收数据时,使能奇偶校验错误时产生中断,Enable the UART Parity Error Interrup
// __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_ERR);
// //串口接收数据时,使能帧错误、噪音错误和溢出错误时产生中断
// //Enable the UART Error Interrupt: (Frame error, noise error, overrun error)
__HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);
开启串口接收中断
//串口接收数据时,使能"接收数据寄存器不为空"则产生中断(位RXNE=1)
//Enable the UART Data Register not empty Interrupt
/在串口中断服务函数中发送数据配置开始//
// __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_TXE);
//串口发丝数据时,使能"串口发送数据寄存器为空"产生中断(位TXE=1)
//Enable the UART Transmit data register empty Interrupt
__HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TXE);
//串口发丝数据时,不使能"串口发送数据寄存器为空"产生中断(位TXE=0)
//Disable the UART Transmit Complete Interrupt
// __HAL_UART_ENABLE_IT(&UART_HandleStructureure,UART_IT_TC);
//串口发丝数据时,使能"串口发送完成"产生中断(位TC=1)
//Enable the UART Transmit Complete Interrupt
__HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TC);
//串口发丝数据时,不使能"串口发送完成"产生中断(位TC=1)
/在串口中断服务函数中发送数据配置结束//
HAL_NVIC_EnableIRQ(USART2_IRQn);
//使能串口2中断
//USART2_IRQn表示中断源为串口2
}
//函数功能:
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
void USART2_Init(uint32_t baudrate)
{
USART2_GPIO_Config();//USART2的IO口配置,PA0是为USART2_TX,PA1是USART2_RX
USART2_NVIC_Cpnfig();//设置串口2中断优先级为0x01
USART2_Mode_Config(baudrate);
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
}
//重定义fputc函数
//函数功能:发送ch的值给USART2串口
int fputc(int ch, FILE *f)
{
uint32_t isrflags;
USART2->DR = (uint8_t)(ch & 0xFFU);
//将ch写入串口数据寄存器(USART_DR),Send a byte to USART
while(1)
{
isrflags = READ_REG(USART2->SR);//读"串口状态寄存器(USART_SR)"
if((isrflags & USART_SR_TXE) != RESET)//等待TXE=1,即等待发送完成
break;
}
return (ch);
}
//函数功能:串口2中断服务程序
void USART2_IRQHandler(void)
{
uint8_t RX_temp;
uint32_t isrflags;
(void)RX_temp;//防止RX_temp不使用而产生警告
isrflags = READ_REG(USART2->SR);
//读"串口状态寄存器(USART_SR)"
if( (isrflags & USART_SR_RXNE) != RESET )//接收到新数据
{//在串口状态寄存器中,发现RXNE=1,且串口控制寄存器1允许接收数据
RX_temp = (uint8_t)(USART2->DR & (uint8_t)0x00FF);//读串口数据
//软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将ORE位(Overrun错误标志)清零;
//软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将NE位(噪声错误标志)清零;
//软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将FE位(帧错误标志)清零;
//软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将PE位(奇偶校验值错误)清零;
//软件读"串口数据寄存器USART_DR",就可以将RXNE位清零
}
if( (isrflags & USART_SR_TXE) != RESET )//串口发送数据寄存器为空,Transmit Data Register empty interrupt
{
CLEAR_BIT(USART2->CR1, UART_IT_TXE);
//将"串口控制寄存器1(USART_CR1)中的TXEIE位"设置为0
//串口发丝数据时,不使能"串口发送数据寄存器为空"产生中断(位TXEIE=0)
//Disable the UART Transmit Complete Interrupt
SET_BIT(USART2->CR1, UART_IT_TC);
//将"串口控制寄存器1(USART_CR1)中的TCIE位"设置为1
//串口发丝数据时,使能"串口发送完成"产生中断(位TCIE=1)
//Enable the UART Transmit Complete Interrupt
}
if( (isrflags & UART_IT_TC) != RESET )//Transmission complete interrupt
{
CLEAR_BIT(USART2->CR1, UART_IT_TC);
//将"串口控制寄存器1(USART_CR1)中的TCIE位"设置为0
//串口发丝数据时,不使能"串口发送完成"产生中断(位TCIE=0)
//Disable the UART Transmit Complete Interrupt
SET_BIT(USART2->CR1, UART_IT_TXE);
//将"串口控制寄存器1(USART_CR1)中的TXEIE位"设置为1
//串口发丝数据时,使能"串口发送数据寄存器为空"产生中断(位TXEIE=1)
//Enable the UART Transmit Complete Interrupt
}
}
直接用寄存器干了,看上去有点象寄存器工程,因为HALL库的确写的不太友好。不清楚原因。
#include "py32f0xx_hal.h"
#include "SystemClock.h"
#include "USART2.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "delay.h"
#include "LED.h"
const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{
// HSE_Config();
//初始化"HSI,HSE,LSI振荡器",HSE用作系统时钟(SYSCLK),同时配置"AHB时钟(HCLK)和APB时钟(PCLK)"
delay_init();
HAL_Delay(1000);
USART2_Init(115200);
//PA0是为USART2_TX,PA1是USART2_RX
//中断优先级为0x01
//波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
printf("%s",CPU_Reset_REG);
MCU_LED_Init();
while (1)
{
MCU_LED_Toggle();
delay_ms(500);
printf("\r\n9876543210\r\n");
}
}
4、测试结果