单片机
返回首页

stm32固件库UART操作

2025-01-14 来源:jianshu

来源: 野火<零死角玩转STM32-F407>  407USART2—USART2接发

//中断 _it.c

extern uint8_t Rxflag;

extern uint8_t ucTemp;

void RS232_USART_IRQHandler(void)

{

    if(USART_GetITStatus( RS232_USART, USART_IT_RXNE ) != RESET)

    {       

      Rxflag=1;     

        ucTemp = USART_ReceiveData( RS232_USART );

    } 

     

}   


====================

//引脚定义

/*******************************************************/

#define RS232_USART                             USART2

#define RS232_USART_CLK                         RCC_APB1Periph_USART2


#define RS232_USART_RX_GPIO_PORT                GPIOA

#define RS232_USART_RX_GPIO_CLK                 RCC_AHB1Periph_GPIOA

#define RS232_USART_RX_PIN                      GPIO_Pin_3

#define RS232_USART_RX_AF                       GPIO_AF_USART2

#define RS232_USART_RX_SOURCE                   GPIO_PinSource3


#define RS232_USART_TX_GPIO_PORT                GPIOA

#define RS232_USART_TX_GPIO_CLK                 RCC_AHB1Periph_GPIOA

#define RS232_USART_TX_PIN                      GPIO_Pin_2

#define RS232_USART_TX_AF                       GPIO_AF_USART2

#define RS232_USART_TX_SOURCE                   GPIO_PinSource2



#define RS232_USART_IRQHandler                   USART2_IRQHandler

#define RS232_USART_IRQ                                     USART2_IRQn

/************************************************************/



//串口波特率

#define RS232_USART_BAUDRATE                    115200      //25M晶体   在8M上面实际波特率38400 可以(实际36864)   



==========================

/**

  * @brief  配置嵌套向量中断控制器NVIC

  * @param  无

  * @retval 无

  */

static void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  /* Configure one bit for preemption priority */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  

  /* 配置中断源 */

  NVIC_InitStructure.NVIC_IRQChannel = RS232_USART_IRQ;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  

}



 /**

  * @brief  RS232_USART GPIO 配置,工作模式配置。115200 8-N-1 ,中断接收模式

  * @param  无

  * @retval 无

  */

void Debug_USART_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  USART_InitTypeDef USART_InitStructure;

        

  RCC_AHB1PeriphClockCmd( RS232_USART_RX_GPIO_CLK|RS232_USART_TX_GPIO_CLK, ENABLE);


  /* 使能 UART 时钟 */

  RCC_APB1PeriphClockCmd(RS232_USART_CLK, ENABLE);

  

  /* 连接 PXx 到 USARTx_Tx*/

  GPIO_PinAFConfig(RS232_USART_RX_GPIO_PORT,RS232_USART_RX_SOURCE, RS232_USART_RX_AF);


  /*  连接 PXx 到 USARTx__Rx*/

  GPIO_PinAFConfig(RS232_USART_TX_GPIO_PORT,RS232_USART_TX_SOURCE,RS232_USART_TX_AF);


  /* 配置Tx引脚为复用功能  */

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;


  GPIO_InitStructure.GPIO_Pin = RS232_USART_TX_PIN  ;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(RS232_USART_TX_GPIO_PORT, &GPIO_InitStructure);


  /* 配置Rx引脚为复用功能 */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Pin = RS232_USART_RX_PIN;

  GPIO_Init(RS232_USART_RX_GPIO_PORT, &GPIO_InitStructure);

            

  /* 配置串口RS232_USART 模式 */

  USART_InitStructure.USART_BaudRate = RS232_USART_BAUDRATE;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No ;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(RS232_USART, &USART_InitStructure); 

    

    NVIC_Configuration();

    /*配置串口接收中断*/

    USART_ITConfig(RS232_USART, USART_IT_RXNE, ENABLE);

    

  USART_Cmd(RS232_USART, ENABLE);

}




/*****************  发送一个字符 **********************/

static void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch )

{

    /* 发送一个字节数据到USART1 */

    USART_SendData(pUSARTx,ch);

        

    /* 等待发送完毕 */

    while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);  

}

/*****************  指定长度的发送字符串 **********************/

void Usart_SendStr_length( USART_TypeDef * pUSARTx, uint8_t *str,uint32_t strlen )

{

    unsigned int k=0;

    do 

    {

        Usart_SendByte( pUSARTx, *(str + k) );

        k++;

    } while(k < strlen);

}


/*****************  发送字符串 **********************/

void Usart_SendString( USART_TypeDef * pUSARTx, uint8_t *str)

{

    unsigned int k=0;

    do 

    {

        Usart_SendByte( pUSARTx, *(str + k) );

        k++;

    } while(*(str + k)!='');

}





///重定向c库函数printf到串口RS232_USART,重定向后可使用printf函数

int fputc(int ch, FILE *f)

{

        /* 发送一个字节数据到串口RS232_USART */

        USART_SendData(RS232_USART, (uint8_t) ch);

        

        /* 等待发送完毕 */

        while (USART_GetFlagStatus(RS232_USART, USART_FLAG_TXE) == RESET);      

    

        return (ch);

}


///重定向c库函数scanf到串口RS232_USART,重写向后可使用scanf、getchar等函数

int fgetc(FILE *f)

{

        /* 等待串口输入数据 */

        while (USART_GetFlagStatus(RS232_USART, USART_FLAG_RXNE) == RESET);


        return (int)USART_ReceiveData(RS232_USART);

}



==========================================

//main.c


uint8_t Rxflag=0;

uint8_t ucTemp;


/**

  * @brief  主函数

  * @param  无

  * @retval 无

  */

int main(void)

{

    uint8_t ucaRxBuf[256];

    uint16_t usRxCount=0; 

    

  /*初始化USART 配置模式为 115200 8-N-1,中断接收*/

  Debug_USART_Config();

 

    /*调用printf函数,因为重定向了fputc,printf的内容会输出到串口*/

    printf('rnPrintf方式输出:这是一个串口中断接收回显实验 rn');   


    

    /*自定义函数方式*/

    Usart_SendString( RS232_USART, (uint8_t *)'自定义函数输出:这是一个串口中断接收回显实验n' );

    Usart_SendString( RS232_USART, (uint8_t *)'输入数据并以回车键结束n' );

    

    /*STM32串口接收到字符后会进入stm32f4xx_it.c文件的中断服务函数,

    *接收该数据,并标记Rxflag标志位。*/


  while(1)

    {   

        /* 

            接收DEBUG_USART口的数据,分析并处理 

            可以将此段代码封装为一个函数,在主程序其它流程调用

        */

        if(Rxflag)

        {

            if (usRxCount < sizeof(ucaRxBuf))

            {

                ucaRxBuf[usRxCount++] = ucTemp;

            }

            else

            {

                usRxCount = 0;

            }

            

            /* 简单的通信协议,遇到回车换行符认为1个命令帧,可自行加其它判断实现自定义命令 */

            /* 遇到换行字符,认为接收到一个命令 */

            if (ucTemp == 0x0A) /* 换行字符 */

            {       

                /*检测到有回车字符就把数据返回给上位机*/

                Usart_SendStr_length( RS232_USART, ucaRxBuf, usRxCount );

                //Usart_SendString();

                usRxCount = 0;

            }

            Rxflag=0;

        }

    }   



}


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • 12V转110V/220V 500W逆变器

  • DS1669数字电位器

    相关电子头条文章