PY32F003F18串口printf功能

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_TC) != RESET)//如果TC=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_TC) != RESET)//等待TC=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 & 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
	}
}

 直接用寄存器干了,看上去有点象寄存器工程,因为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、测试结果 

PY32F003F18串口printf功能_第1张图片

你可能感兴趣的:(产品研发,PY32F003F18,普冉,检验分享,嵌入式硬件,KEIL,ARM,单片机)