STM32F10x usart数据收发

发布者:WanderlustSoul最新更新时间:2019-03-11 来源: eefocus关键字:STM32F10x  usart  数据收发 手机看文章 扫描二维码
随时随地手机看文章

STM32F10x uart的数据发送接收就三种基本方式,轮询、中断和DMA


1. 轮询(polling)方式

以下是轮询的uart初始化以及发送接收的例子,发送和接收都用轮询的方式。


uint8_t TxBuffer[] = "Buffer Send from USARTy to USARTz using Flags";

uint8_t RxBuffer[TxBufferSize];

int main(void)

{

  /*!< At this stage the microcontroller clock setting is already configured, 

       this is done through SystemInit() function which is called from startup

       file (startup_stm32f10x_xx.s) before to branch to application main.

       To reconfigure the default setting of SystemInit() function, refer to

       system_stm32f10x.c file

     */     


  /* System Clocks Configuration */

  RCC_Configuration();


  /* Configure the GPIO ports */

  GPIO_Configuration();


/* USARTy and USARTz configuration ------------------------------------------------------*/

  /* USARTy and USARTz configured as follow:

        - BaudRate = 230400 baud  

        - Word Length = 8 Bits

        - One Stop Bit

        - Even parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 230400;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_Even;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;


  /* Configure USARTy */

  USART_Init(USARTy, &USART_InitStructure);

  /* Configure USARTz */

  USART_Init(USARTz, &USART_InitStructure);


  /* Enable the USARTy */

  USART_Cmd(USARTy, ENABLE);


  /* Enable the USARTz */

  USART_Cmd(USARTz, ENABLE);


  while(TxCounter < TxBufferSize)

  {   

    /* Send one byte from USARTy to USARTz */

    USART_SendData(USARTy, TxBuffer[TxCounter++]);

    /*

        void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)

        {

          assert_param(IS_USART_ALL_PERIPH(USARTx));

          assert_param(IS_USART_DATA(Data)); 

          USARTx->DR = (Data & (uint16_t)0x01FF); //往DR写发送的数据

        }

    */


    /* Loop until USARTy DR register is empty */ 

    while(USART_GetFlagStatus(USARTy, USART_FLAG_TXE) == RESET)

    {

    }

    //到这里表示数据发送完毕(USART_FLAG_TXE可以参考STM32F10x usart寄存器描述)

    /* Loop until the USARTz Receive Data Register is not empty */

    while(USART_GetFlagStatus(USARTz, USART_FLAG_RXNE) == RESET)

    {

    }

    //到这里表示数据接收完毕(USART_FLAG_RXNE可以参考STM32F10x usart寄存器描述)

    /* Store the received byte in RxBuffer */

    RxBuffer[RxCounter++] = (USART_ReceiveData(USARTz) & 0x7F);  


  } 

  //后面只是看发送接收数据是否一致,这与测试条件有关,不再赘述。

  /* Check the received data with the send ones */

  TransferStatus = Buffercmp(TxBuffer, RxBuffer, TxBufferSize);

  /* TransferStatus = PASSED, if the data transmitted from USARTy and  

     received by USARTz are the same */

  /* TransferStatus = FAILED, if the data transmitted from USARTy and 

     received by USARTz are different */


  while (1)

  {

  }

}


2. 中断方式读写

STM32F10x USART有很多类型的中断,每个中断类型都有一个使能标志位。 

 这里写图片描述 

中断设定以及使用ringbuffer输入输出的流程如下 

(1) 中断的初始化


  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure the NVIC Preemption Priority Bits */  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  /* Enable the USARTy Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USARTy_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);


  /* Enable USARTy Receive and Transmit interrupts */

  USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);

  USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);


一般一个USART端口,输入输出都要设置一个中断位来触发输入输出中断,一般的输入输出只需要设置如下两个中断即可。 

USART_IT_RXNE:Receive Data register not empty interrupt 

USART_IT_TXE: Transmit Data Register empty interrupt


还有其他的中断位解释如下: 

USART_IT_CTS: CTS change interrupt 

USART_IT_LBD: LIN Break detection interrupt 

USART_IT_TC: Transmission complete interrupt 

USART_IT_IDLE: Idle line detection interrupt 

USART_IT_PE: Parity Error interrupt 

USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)


设置完USART_IT_RXNE和USART_IT_TXE中断之后,读写都会触发中断。 

这里我们一般不用USART_IT_TC中断,因为一般来说使用发送数据寄存器空中断(USART_IT_TXE) 

发送的效率会高一些。


下面用一个使用ringbuffer,且使用中断方式的例子来熟悉一下中断读写。 

(参考http://blog.csdn.net/liyuanbhu/article/details/8886407) 

中断处理函数的框架如下,如果检测到错误就清除错误,收到数了就处理。发完当前数据了就发下一个。


void USART1_IRQHandler(void)  

{  

    unsigned int data;  


    if(USART1->SR & 0x0F)   

    {  

        // See if we have some kind of error, Clear interrupt     

        data = USART1->DR;  

    }  

    else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  

    {    

        data = USART1->DR;  

        // 对收到的数据进行处理,或者干些其他的事    

    }  

    else if(USART1->SR & USART_FLAG_TXE)   

    {  

        { // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断  

            USART1->DR =  something;        // Yes, Send character                        

        }                                             

    }    

}      


下面给一个利用环形缓冲区的串口驱动程序。


#ifndef _COM_BUFFERED_H_  

#define _COM_BUFFERED_H_  


#define  COM1                   0  

#define  COM2                   1  


#define  COM_RX_BUF_SIZE        64                /* Number of characters in Rx ring buffer             */  

#define  COM_TX_BUF_SIZE        64                /* Number of characters in Tx ring buffer             */  


#define  COM_NO_ERR             0                /* Function call was successful                       */  

#define  COM_BAD_CH             1                /* Invalid communications port channel                */  

#define  COM_RX_EMPTY           2                /* Rx buffer is empty, no character available         */  

#define  COM_TX_FULL            3                /* Tx buffer is full, could not deposit character     */  

#define  COM_TX_EMPTY           4                /* If the Tx buffer is empty.                         */  



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

 * function : COMGetCharB  

 * parameter: char port, port can be COM1 / COM2 

 * parameter: char* err   is a pointer to where an error code will be placed: 

 *                   *err is set to COM_NO_ERR   if a character is available 

 *                   *err is set to COM_RX_EMPTY if the Rx buffer is empty 

 *                   *err is set to COM_BAD_CH   if you have specified an invalid channel 

 * return   : char 

 * usage    : This function is called by your application to obtain a character from the communications 

 *               channel. 

 * changelog:  

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

unsigned char  COMGetCharB (unsigned char ch, unsigned char *err);  


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

 * function : COMPutCharB  

 * parameter: char port, port can be COM1 / COM2 

 * return   :    COMM_NO_ERR   if the function was successful (the buffer was not full) 

 *               COMM_TX_FULL  if the buffer was full 

 *               COMM_BAD_CH   if you have specified an incorrect channel 


 * usage    : This function is called by your application to send a character on the communications 

 *               channel.  The character to send is first inserted into the Tx buffer and will be sent by 

 *               the Tx ISR.  If this is the first character placed into the buffer, the Tx ISR will be 

 *               enabled.  If the Tx buffer is full, the character will not be sent (i.e. it will be lost) 

 * changelog:  

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

unsigned char COMPutCharB (unsigned char port, unsigned char c);  


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

 * function : COMBufferInit  

 * parameter:  

 * return   :     

 * usage    : This function is called by your application to initialize the communications module.  You 

 *             must call this function before calling any other functions. 

 * changelog:  

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

void  COMBufferInit (void);  


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

 * function : COMBufferIsEmpty  

 * parameter: char port, port can be COM1 / COM2 

 * return   : char 

 * usage    : This function is called by your application to see  

 *            if any character is available from the communications channel. 

 *            If at least one character is available, the function returns 

 *            FALSE(0) otherwise, the function returns TRUE(1). 

 * changelog:  

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

unsigned char  COMBufferIsEmpty (unsigned char port);  


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

 * function : COMBufferIsFull  

 * parameter: char port, port can be COM1 / COM2 

 * return   : char 

 * usage    : This function is called by your application to see if any more characters can be placed 

 *             in the Tx buffer.  In other words, this function check to see if the Tx buffer is full. 

 *             If the buffer is full, the function returns TRUE otherwise, the function returns FALSE. 

 * changelog:  

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

unsigned char COMBufferIsFull (unsigned char port);  


#endif 




/* 

 * file: com_buffered.c 

 * author: Li Yuan 

 * platform: STM32F107 

 * date: 2013-5-5 

 * version: 0.0.1 

 * description: UART Ring Buffer                             

**/  


#include "stm32f10x_usart.h"  

#include "com_buffered.h"  


#define OS_ENTER_CRITICAL()     __set_PRIMASK(1)  

#define OS_EXIT_CRITICAL()      __set_PRIMASK(0)     


/** 

 *  Enables Transmiter interrupt. 

**/  

static void COMEnableTxInt(unsigned char port)  

{  

    static USART_TypeDef* map[2] = {USART1, USART2};  

    USART_ITConfig(map[port], USART_IT_TXE, ENABLE);      

}  

/* 

********************************************************************************************************* 

*                                               DATA TYPES 

********************************************************************************************************* 

*/  

typedef struct {  

    short  RingBufRxCtr;                   /* Number of characters in the Rx ring buffer              */  

    unsigned char  *RingBufRxInPtr;                 /* Pointer to where next character will be inserted        */  

    unsigned char  *RingBufRxOutPtr;                /* Pointer from where next character will be extracted     */  

    unsigned char   RingBufRx[COM_RX_BUF_SIZE];     /* Ring buffer character storage (Rx)                      */  

    short  RingBufTxCtr;                   /* Number of characters in the Tx ring buffer              */  

    unsigned char  *RingBufTxInPtr;                 /* Pointer to where next character will be inserted        */  

    unsigned char  *RingBufTxOutPtr;                /* Pointer from where next character will be extracted     */  

    unsigned char   RingBufTx[COM_TX_BUF_SIZE];     /* Ring buffer character storage (Tx)                      */  

} COM_RING_BUF;  


/* 

********************************************************************************************************* 

*                                            GLOBAL VARIABLES 

********************************************************************************************************* 

*/  


COM_RING_BUF  COM1Buf;  

COM_RING_BUF  COM2Buf;  



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

 * function : COMGetCharB  

 * parameter: char port, port can be COM1 / COM2 

 * parameter: char* err   is a pointer to where an error code will be placed: 

 *                   *err is set to COM_NO_ERR   if a character is available 

 *                   *err is set to COM_RX_EMPTY if the Rx buffer is empty 

 *                   *err is set to COM_BAD_CH   if you have specified an invalid channel 

 * return   : char 

 * usage    : This function is called by your application to obtain a character from the communications 

 *               channel. 

 * changelog:  

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

unsigned char  COMGetCharB (unsigned char port, unsigned char *err)  

{  

//    unsigned char cpu_sr;  


    unsigned char c;  

    COM_RING_BUF *pbuf;  


    switch (port)   

    {                                          /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             *err = COM_BAD_CH;  

             return (0);  

    }  

    OS_ENTER_CRITICAL();  

    if (pbuf->RingBufRxCtr > 0)                            /* See if buffer is empty                   */  

    {                                                        

        pbuf->RingBufRxCtr--;                              /* No, decrement character count            */  

        c = *pbuf->RingBufRxOutPtr++;                      /* Get character from buffer                */  

        if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])   

        {        

            pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];   /* Wrap OUT pointer     */  

        }  

        OS_EXIT_CRITICAL();  

        *err = COM_NO_ERR;  

        return (c);  

    } else {  

        OS_EXIT_CRITICAL();  

        *err = COM_RX_EMPTY;  

        c    = 0;                                        /* Buffer is empty, return 0              */  

        return (c);  

    }  

}  



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

 * function : COMPutCharB  

 * parameter: char port, port can be COM1 / COM2 

 * return   :    COMM_NO_ERR   if the function was successful (the buffer was not full) 

 *               COMM_TX_FULL  if the buffer was full 

 *               COMM_BAD_CH   if you have specified an incorrect channel 


 * usage    : This function is called by your application to send a character on the communications 

 *               channel.  The character to send is first inserted into the Tx buffer and will be sent by 

 *               the Tx ISR.  If this is the first character placed into the buffer, the Tx ISR will be 

 *               enabled.  If the Tx buffer is full, the character will not be sent (i.e. it will be lost) 

 * changelog:  

 *            1.first implimented by liyuan 2010.11.5 

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

unsigned char COMPutCharB (unsigned char port, unsigned char c)  

{  

//    unsigned char cpu_sr;  


    COM_RING_BUF *pbuf;  

    switch (port)   

    {                                                     /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             return (COM_BAD_CH);  

    }  


    OS_ENTER_CRITICAL();  

    if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {           /* See if buffer is full                    */  

        pbuf->RingBufTxCtr++;                              /* No, increment character count            */  

        *pbuf->RingBufTxInPtr++ = c;                       /* Put character into buffer                */  

        if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) { /* Wrap IN pointer           */  

            pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];  

        }  

        if (pbuf->RingBufTxCtr == 1) {                     /* See if this is the first character       */  

            COMEnableTxInt(port);                          /* Yes, Enable Tx interrupts                */  

            OS_EXIT_CRITICAL();  

        } else {  

            OS_EXIT_CRITICAL();  

        }  

        return (COM_NO_ERR);  

    } else {  

        OS_EXIT_CRITICAL();  

        return (COM_TX_FULL);  

    }  

}  


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

 * function : COMBufferInit  

 * parameter:  

 * return   :     

 * usage    : This function is called by your application to initialize the communications module.  You 

 *             must call this function before calling any other functions. 

 * changelog:  

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

void  COMBufferInit (void)  

{  

    COM_RING_BUF *pbuf;  


    pbuf                  = &COM1Buf;                     /* Initialize the ring buffer for COM0     */  

    pbuf->RingBufRxCtr    = 0;  

    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];  

    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];  

    pbuf->RingBufTxCtr    = 0;  

    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];  

    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];  


    pbuf                  = &COM2Buf;                     /* Initialize the ring buffer for COM1     */  

    pbuf->RingBufRxCtr    = 0;  

    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];  

    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];  

    pbuf->RingBufTxCtr    = 0;  

    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];  

    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];  

}  


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

 * function : COMBufferIsEmpty  

 * parameter: char port, port can be COM1 / COM2 

 * return   : char 

 * usage    : This function is called by your application to see  

 *            if any character is available from the communications channel. 

 *            If at least one character is available, the function returns 

 *            FALSE(0) otherwise, the function returns TRUE(1). 

 * changelog:  

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

unsigned char  COMBufferIsEmpty (unsigned char port)  

{  

//    unsigned char cpu_sr;  


    unsigned char empty;  

    COM_RING_BUF *pbuf;  

    switch (port)   

    {                                                     /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             return (1);  

    }  

    OS_ENTER_CRITICAL();  

    if (pbuf->RingBufRxCtr > 0)  

    {                                                      /* See if buffer is empty                   */  

        empty = 0;                                         /* Buffer is NOT empty                      */  

    }   

    else   

    {  

        empty = 1;                                         /* Buffer is empty                          */  

    }  

    OS_EXIT_CRITICAL();  

    return (empty);  

}  



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

 * function : COMBufferIsFull  

 * parameter: char port, port can be COM1 / COM2 

 * return   : char 

 * usage    : This function is called by your application to see if any more characters can be placed 

 *             in the Tx buffer.  In other words, this function check to see if the Tx buffer is full. 

 *             If the buffer is full, the function returns TRUE otherwise, the function returns FALSE. 

 * changelog:  

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

unsigned char COMBufferIsFull (unsigned char port)  

{  

//    unsigned char cpu_sr;  


    char full;  

    COM_RING_BUF *pbuf;  

    switch (port)   

    {                                                     /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             return (1);  

    }  

    OS_ENTER_CRITICAL();  

    if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {           /* See if buffer is full                    */  

        full = 0;                                      /* Buffer is NOT full                       */  

    } else {  

        full = 1;                                       /* Buffer is full                           */  

    }  

    OS_EXIT_CRITICAL();  

    return (full);  

}  



// This function is called by the Rx ISR to insert a character into the receive ring buffer.  

static void  COMPutRxChar (unsigned char port, unsigned char c)  

{  

    COM_RING_BUF *pbuf;  


    switch (port)   

    {                                                     /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             return;  

    }  

    if (pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) {           /* See if buffer is full                    */  

        pbuf->RingBufRxCtr++;                              /* No, increment character count            */  

        *pbuf->RingBufRxInPtr++ = c;                       /* Put character into buffer                */  

        if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) { /* Wrap IN pointer           */  

            pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];  

        }  

    }  

}  



// This function is called by the Tx ISR to extract the next character from the Tx buffer.  

//    The function returns FALSE if the buffer is empty after the character is extracted from  

//    the buffer.  This is done to signal the Tx ISR to disable interrupts because this is the  

//    last character to send.  

static unsigned char COMGetTxChar (unsigned char port, unsigned char *err)  

{  

    unsigned char c;  

    COM_RING_BUF *pbuf;  


    switch (port)   

    {                                          /* Obtain pointer to communications channel */  

        case COM1:  

             pbuf = &COM1Buf;  

             break;  


        case COM2:  

             pbuf = &COM2Buf;  

             break;  


        default:  

             *err = COM_BAD_CH;  

             return (0);  

    }  

    if (pbuf->RingBufTxCtr > 0) {                          /* See if buffer is empty                   */  

        pbuf->RingBufTxCtr--;                              /* No, decrement character count            */  

        c = *pbuf->RingBufTxOutPtr++;                      /* Get character from buffer                */  

        if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])   

        {       

            pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];   /* Wrap OUT pointer     */  

        }  

        *err = COM_NO_ERR;  

        return (c);                                        /* Characters are still available           */  

    } else {  

        *err = COM_TX_EMPTY;  

        return (0);                                      /* Buffer is empty                          */  

    }  

}  



void USART1_IRQHandler(void)  

{  

    unsigned int data;  

    unsigned char err;  


    if(USART1->SR & 0x0F)   

    {  

        // See if we have some kind of error     

        // Clear interrupt (do nothing about it!)      

        data = USART1->DR;  

    }  

    else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  

    {    

        data = USART1->DR;  

        COMPutRxChar(COM1, data);                    // Insert received character into buffer       

    }  

    else if(USART1->SR & USART_FLAG_TXE)   

    {  

        data = COMGetTxChar(COM1, &err);             // Get next character to send.                 

        if (err == COM_TX_EMPTY)   

        {                                            // Do we have anymore characters to send ?     

                                                     // No,  Disable Tx interrupts                  

            //USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);  

            USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;  

        }   

        else   

        {  

            USART1->DR = data;        // Yes, Send character                        

        }                                             

    }    

}      


void USART2_IRQHandler(void)  

{  

    unsigned int data;  

    unsigned char err;  


    if(USART2->SR & 0x0F)   

    {  

        // See if we have some kind of error     

        // Clear interrupt (do nothing about it!)      

        data = USART2->DR;  

    }  

    else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  

    {    

        data = USART2->DR;  

        COMPutRxChar(COM2, data);                    // Insert received character into buffer       

    }  

    else if(USART2->SR & USART_FLAG_TXE)   

    {  

        data = COMGetTxChar(COM2, &err);             // Get next character to send.                 

        if (err == COM_TX_EMPTY)   

        {                                            // Do we have anymore characters to send ?     

                                                     // No,  Disable Tx interrupts                  

            //USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);  

            USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;  

        }   

        else   

        {  

            USART2->DR = data;        // Yes, Send character                        

        }                                             

    }    

}  




下面给个例子主程序,来演示如何使用上面的串口驱动代码。


#include "misc.h"  

#include "stm32f10x.h"  

#include "com_buffered.h"  


void UART_PutStrB (unsigned char port, uint8_t *str)  

{  

    while (0 != *str)  

    {  

        COMPutCharB(port, *str);  

        str++;  

    }  

}  


void USART1_Init(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    USART_InitTypeDef USART_InitStructure;  

    NVIC_InitTypeDef NVIC_InitStructure;  


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);  


    /* Configure USART Tx as alternate function push-pull */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(GPIOA, &GPIO_InitStructure);  


    /* Configure USART Rx as input floating */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

    GPIO_Init(GPIOA, &GPIO_InitStructure);  


    USART_InitStructure.USART_BaudRate = 9600;  

    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(USART1, &USART_InitStructure );   


        USART_Cmd(USART1, ENABLE);  


    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

    NVIC_Init(&NVIC_InitStructure);  

}  


void USART2_Init(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    USART_InitTypeDef USART_InitStructure;  

    NVIC_InitTypeDef NVIC_InitStructure;  


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);  


    /* Configure USART Tx as alternate function push-pull */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(GPIOD, &GPIO_InitStructure);  


    /* Configure USART Rx as input floating */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  

    GPIO_Init(GPIOD, &GPIO_InitStructure);  


    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  


    USART_InitStructure.USART_BaudRate = 9600;  

    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(USART2, &USART_InitStructure );   


        USART_Cmd(USART2, ENABLE);  


    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

    NVIC_Init(&NVIC_InitStructure);  

}  



int main(void)  

{  

    unsigned char c;  

    unsigned char err;  


    USART1_Init();  

    USART2_Init();    

    COMBufferInit();  

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  


    UART_PutStrB(COM1, "Hello World!\n");  

    for(;;)  

    {  

        c = COMGetCharB(COM1, &err);  

        if(err == COM_NO_ERR)  

        {  

            COMPutCharB(COM1, c);  

        }  

    }     

}  

关键字:STM32F10x  usart  数据收发 引用地址:STM32F10x usart数据收发

上一篇:STM32 实现 IAP与APP文件合并
下一篇:使用xmake构建STM32程序

推荐阅读最新更新时间:2024-03-16 16:25

关于USART很多人都容易忽视的一个问题
Ⅰ、 写在前面 今天这篇文章分享的知识点比较少,但比较重要,是大部分人在实际项目开发中都容易忽视,且容易犯下的低级错误。 本文讲述在项目开发中,或在学习中经常遇到USART发送字符串,对方没有接收完成(最后一两字节),也就是最后字节数据丢失了。具体可以看下面章节实验。 关于本文的更多详情请往下看。 Ⅱ、实例工程 为了方便大家学习,提供实验源代码工程给大家参考。 STM32F10x_USART(验证USART发送字符串): https://yunpan.cn/ckInh8YTwWHVP 访问密码 81f9 提供下载的实例实现的功能比较简单,主要是用于验证不同情况下,发送字符的不同。 实例实现功能可以从
[单片机]
关于<font color='red'>USART</font>很多人都容易忽视的一个问题
STM32F10x GPIO配置 之 位绑定
对GPIO进行未绑定,好处:加快对位操作的速度。 1、位绑定公式(操作不同地址区域的位,用下面不同的公式) 2、下面以GPIOA端口的配置进行讲解: 3、对少量位进行绑定的程序例举: /************************************************************************************************** * 硬件平台:STM32F103VC * 学习重点:GPIOx的位绑定 * 实现功能:对于GPIOA端口的第八位输出 跟随 高八位的输入 **********************************
[单片机]
<font color='red'>STM32F10x</font> GPIO配置 之 位绑定
STM32F10x系列UART中断异常调试经历
硬件环境: STM32F105RCT6 软件环境:FreeRTOSV8 问题描述:采用中断方式接收数据,然后将收到的一帧数据放入消息队列,然后有专门的一个任务用来从消息队列中取数据并处理。jlink调试以及烧录运行都是可以的,但是当随着通信频率的增加以及运行时间的加长,系统会出现“死机”(即,不停的进入中断而致使主程序流程无法执行); 问题分析:根据现象猜测 1、是否为堆栈溢出了呢? 2、是否频率太高了呢? 3、是否标志位忘记没有清除呢? 然后逐项进行测试: 1、查htm文件确定大概需要的堆栈,发现确实存在溢出的可能: 而我分配的为:然后更改为0x00000800,烧录测试,还是存在同样问题,然后在
[单片机]
<font color='red'>STM32F10x</font>系列UART中断异常调试经历
stm32 usart奇偶校验如何配置
stm32 usart奇偶校验如何配置?或许你在stm32 usart奇偶校验过程中会遇到如下一些坑,stm32 usart偶校验错误标志位以及出现偶校验错误,奇偶校验位包含在数据位中等等这些可能是你将错误的数据放到DR寄存器中导致的。 在一般情况下,stm32 usart奇偶校验无校验位时,数据位常用8位,当使用就校验位时,数据位应设置为9位。stm32 usart奇偶校验配置方法主要有以下几种: stm32 usart奇偶校验如何配置?如果stm32 usart开启奇偶校验,应在读取数据寄存器时先查看标志位,或者及时进行应用逻辑代码处理,以免发生校验错误标志则丢弃数据等情况出现造成不必要的损失。
[单片机]
stm32 <font color='red'>usart</font>奇偶校验如何配置
浅谈STM32F10X芯片SysTick系统时钟定时器
如题,正文如下: 1、介绍 实现Cortex-M3系统定时器SysTick的配置,需要具备以下知识:Cortex-M3系统定时器默认频率是HCLK的8分频(如下图所示),因此需要会RCC时钟的配置;然后配置SysTick系统定时器;编写SysTick中断处理函数。 系统时钟及系统定时器时钟(详见手册) 2、寄存器描述 l SysTick控制及状态寄存器STK_CTRL l SysTick重装载数值寄存器STK_LOAD l SysTick当前数值寄存器STK_VAL l SysTick校准数值寄存器STK_CALIB 与SysTick相关的固件库函数有以下几个: l
[单片机]
STM32系统学习——USART(串口通信)
串口通信是一种设备间非常常用的串行通行方式,其简单便捷,大部分电子设备都支持。 一、物理层 常用RS-232标准,主要规定了信号的用途、通信接口以及信号的电平标准。 “DB9接口”之间通过串口信号线建立起连接,串口信号线使用”RS-232标准“传输数据信号,这些信号通过记过电平转换芯片转换成控制器能识别的TLL标准的电平信号,才能实现通信。 1.电平标准 可分为TTL标准以及RS-232标准。 常见的电子电路中常见TTL的电平标准,理想状态使用5V表示二进制逻辑1,0V表示逻辑0;而为了增加串口通信的远距离传输以及抗干扰能力,RS-232使用-15V表示逻辑1,+15V表示逻辑0。
[单片机]
STM32系统学习——<font color='red'>USART</font>(串口通信)
STM32的USART使用DMA--操作
使用STM32的DMA来处理USART3的RX的多数据 注意:DMA的中断产生条件中,TC=transfer complete interrupt产生,需要DMA的buffer满才会产生。 只有当DMA内存中的数据个数达到20个时候才能产生中断。定义如下。DMA_InitStructure.DMA_BufferSize = 20;//sizeof(Ch3DMABuffer); static usart3_dma_config(void) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClo
[单片机]
AVR单片机(学习ing)-ATMEGA16的USART与PC机串行通信
五、ATMEGA16的USART与PC机串行通信 五 (01)、PC机发送字符给单片机控制发光管亮,同时将其传回PC机,其中单片机的发送和接收都采用查询方式(下一篇中有例程~) 1、USART的主要特点 通用同步和异步串行接收器和转发器(USART) 是一个高度灵活的串行通讯设备。主要特 点为: 全双工操作( 独立的串行接收和发送寄存器) 异步或同步操作 主机或从机提供时钟的同步操作 高精度的波特率发生器 支持5, 6, 7, 8, 或9 个数据位和1 个或2 个停止位 硬件支持的奇偶校验操作 数据过速检测 帧错误检测 噪声滤波,包括错误的起始位检测,以及数字低通滤波器 三个独立的中断:发送结束中断, 发送数
[单片机]
AVR单片机(学习ing)-ATMEGA16的<font color='red'>USART</font>与PC机串行通信
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved