STM32F10x 利用环形缓冲区的串口驱动程序

转载原文:http://blog.csdn.net/liyuanbhu/article/details/8886407


这次讲讲利用串口收发中断来进行串口通讯。STM32 上为每个串口分配了一个中断。也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断。程序需在中断处理函数中读取状态寄存器(USART_SR)来判断当前的是什么中断。下面的中断映像图给出了这些中断源是如何汇合成最终的中断信号的。图中也给出了如何控制每一个单独的中断源是否起作用。

另外,Cortex-M3 内核中还有个NVIC,可以控制这里的中断信号是否触发中断处理函数的执行,还有这些外部中断的级别。关于NVIC 可以参考《ARM CortexM3 权威指南》,里面讲解的非常详细。

简单的说,为了开启中断,我们需要如下的代码:

[cpp]  view plain  copy
  1. NVIC_InitTypeDef NVIC_InitStructure;  
  2. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  
  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  6. NVIC_Init(&NVIC_InitStructure);  
  7.   
  8. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断  
  9. USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断  

这里多说一句,串口的发送中断有两个,分别是:

  1. l发送数据寄存器空中断(TXE
  2. l发送完成中断(TC

一般来说我们会使用发送数据寄存器空中断,用这个中断发送的效率会高一些。

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

[cpp]  view plain  copy
  1. void USART1_IRQHandler(void)  
  2. {  
  3.     unsigned int data;  
  4.   
  5.     if(USART1->SR & 0x0F)   
  6.     {  
  7.         // See if we have some kind of error, Clear interrupt     
  8.         data = USART1->DR;  
  9.     }  
  10.     else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  
  11.     {    
  12.         data = USART1->DR;  
  13.         // 对收到的数据进行处理,或者干些其他的事    
  14.     }  
  15.     else if(USART1->SR & USART_FLAG_TXE)   
  16.     {  
  17.         { // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断  
  18.             USART1->DR =  something;        // Yes, Send character                        
  19.         }                                             
  20.     }    
  21. }      

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

[cpp]  view plain  copy
  1. #ifndef _COM_BUFFERED_H_  
  2. #define _COM_BUFFERED_H_  
  3.   
  4. #define  COM1                   0  
  5. #define  COM2                   1  
  6.   
  7. #define  COM_RX_BUF_SIZE        64                /* Number of characters in Rx ring buffer             */  
  8. #define  COM_TX_BUF_SIZE        64                /* Number of characters in Tx ring buffer             */  
  9.   
  10. #define  COM_NO_ERR             0                /* Function call was successful                       */  
  11. #define  COM_BAD_CH             1                /* Invalid communications port channel                */  
  12. #define  COM_RX_EMPTY           2                /* Rx buffer is empty, no character available         */  
  13. #define  COM_TX_FULL            3                /* Tx buffer is full, could not deposit character     */  
  14. #define  COM_TX_EMPTY           4                /* If the Tx buffer is empty.                         */  
  15.   
  16.   
  17. /************************************************************ 
  18.  * function : COMGetCharB  
  19.  * parameter: char port, port can be COM1 / COM2 
  20.  * parameter: char* err   is a pointer to where an error code will be placed: 
  21.  *                   *err is set to COM_NO_ERR   if a character is available 
  22.  *                   *err is set to COM_RX_EMPTY if the Rx buffer is empty 
  23.  *                   *err is set to COM_BAD_CH   if you have specified an invalid channel 
  24.  * return   : char 
  25.  * usage    : This function is called by your application to obtain a character from the communications 
  26.  *               channel. 
  27.  * changelog:  
  28.  *************************************************************/  
  29. unsigned char  COMGetCharB (unsigned char ch, unsigned char *err);  
  30.   
  31. /************************************************************ 
  32.  * function : COMPutCharB  
  33.  * parameter: char port, port can be COM1 / COM2 
  34.  * return   :    COMM_NO_ERR   if the function was successful (the buffer was not full) 
  35.  *               COMM_TX_FULL  if the buffer was full 
  36.  *               COMM_BAD_CH   if you have specified an incorrect channel 
  37.  
  38.  * usage    : This function is called by your application to send a character on the communications 
  39.  *               channel.  The character to send is first inserted into the Tx buffer and will be sent by 
  40.  *               the Tx ISR.  If this is the first character placed into the buffer, the Tx ISR will be 
  41.  *               enabled.  If the Tx buffer is full, the character will not be sent (i.e. it will be lost) 
  42.  * changelog:  
  43.  *************************************************************/  
  44. unsigned char COMPutCharB (unsigned char port, unsigned char c);  
  45.   
  46. /************************************************************ 
  47.  * function : COMBufferInit  
  48.  * parameter:  
  49.  * return   :     
  50.  * usage    : This function is called by your application to initialize the communications module.  You 
  51.  *             must call this function before calling any other functions. 
  52.  * changelog:  
  53.  *************************************************************/  
  54. void  COMBufferInit (void);  
  55.   
  56. /************************************************************ 
  57.  * function : COMBufferIsEmpty  
  58.  * parameter: char port, port can be COM1 / COM2 
  59.  * return   : char 
  60.  * usage    : This function is called by your application to see  
  61.  *            if any character is available from the communications channel. 
  62.  *            If at least one character is available, the function returns 
  63.  *            FALSE(0) otherwise, the function returns TRUE(1). 
  64.  * changelog:  
  65.  *************************************************************/  
  66. unsigned char  COMBufferIsEmpty (unsigned char port);  
  67.   
  68. /************************************************************ 
  69.  * function : COMBufferIsFull  
  70.  * parameter: char port, port can be COM1 / COM2 
  71.  * return   : char 
  72.  * usage    : This function is called by your application to see if any more characters can be placed 
  73.  *             in the Tx buffer.  In other words, this function check to see if the Tx buffer is full. 
  74.  *             If the buffer is full, the function returns TRUE otherwise, the function returns FALSE. 
  75.  * changelog:  
  76.  *************************************************************/  
  77. unsigned char COMBufferIsFull (unsigned char port);  
  78.   
  79. #endif  

[cpp]  view plain  copy
  1. /* 
  2.  * file: com_buffered.c 
  3.  * author: Li Yuan 
  4.  * platform: STM32F107 
  5.  * date: 2013-5-5 
  6.  * version: 0.0.1 
  7.  * description: UART Ring Buffer                             
  8. **/  
  9.   
  10. #include "stm32f10x_usart.h"  
  11. #include "com_buffered.h"  
  12.   
  13. #define OS_ENTER_CRITICAL()     __set_PRIMASK(1)  
  14. #define OS_EXIT_CRITICAL()      __set_PRIMASK(0)     
  15.       
  16. /** 
  17.  *  Enables Transmiter interrupt. 
  18. **/  
  19. static void COMEnableTxInt(unsigned char port)  
  20. {  
  21.     static USART_TypeDef* map[2] = {USART1, USART2};  
  22.     USART_ITConfig(map[port], USART_IT_TXE, ENABLE);      
  23. }  
  24. /* 
  25. ********************************************************************************************************* 
  26. *                                               DATA TYPES 
  27. ********************************************************************************************************* 
  28. */  
  29. typedef struct {  
  30.     short  RingBufRxCtr;                   /* Number of characters in the Rx ring buffer              */  
  31.     unsigned char  *RingBufRxInPtr;                 /* Pointer to where next character will be inserted        */  
  32.     unsigned char  *RingBufRxOutPtr;                /* Pointer from where next character will be extracted     */  
  33.     unsigned char   RingBufRx[COM_RX_BUF_SIZE];     /* Ring buffer character storage (Rx)                      */  
  34.     short  RingBufTxCtr;                   /* Number of characters in the Tx ring buffer              */  
  35.     unsigned char  *RingBufTxInPtr;                 /* Pointer to where next character will be inserted        */  
  36.     unsigned char  *RingBufTxOutPtr;                /* Pointer from where next character will be extracted     */  
  37.     unsigned char   RingBufTx[COM_TX_BUF_SIZE];     /* Ring buffer character storage (Tx)                      */  
  38. } COM_RING_BUF;  
  39.   
  40. /* 
  41. ********************************************************************************************************* 
  42. *                                            GLOBAL VARIABLES 
  43. ********************************************************************************************************* 
  44. */  
  45.   
  46. COM_RING_BUF  COM1Buf;  
  47. COM_RING_BUF  COM2Buf;  
  48.   
  49.   
  50. /************************************************************ 
  51.  * function : COMGetCharB  
  52.  * parameter: char port, port can be COM1 / COM2 
  53.  * parameter: char* err   is a pointer to where an error code will be placed: 
  54.  *                   *err is set to COM_NO_ERR   if a character is available 
  55.  *                   *err is set to COM_RX_EMPTY if the Rx buffer is empty 
  56.  *                   *err is set to COM_BAD_CH   if you have specified an invalid channel 
  57.  * return   : char 
  58.  * usage    : This function is called by your application to obtain a character from the communications 
  59.  *               channel. 
  60.  * changelog:  
  61.  *************************************************************/  
  62. unsigned char  COMGetCharB (unsigned char port, unsigned char *err)  
  63. {  
  64. //    unsigned char cpu_sr;  
  65.       
  66.     unsigned char c;  
  67.     COM_RING_BUF *pbuf;  
  68.   
  69.     switch (port)   
  70.     {                                          /* Obtain pointer to communications channel */  
  71.         case COM1:  
  72.              pbuf = &COM1Buf;  
  73.              break;  
  74.   
  75.         case COM2:  
  76.              pbuf = &COM2Buf;  
  77.              break;  
  78.   
  79.         default:  
  80.              *err = COM_BAD_CH;  
  81.              return (0);  
  82.     }  
  83.     OS_ENTER_CRITICAL();  
  84.     if (pbuf->RingBufRxCtr > 0)                            /* See if buffer is empty                   */  
  85.     {                                                        
  86.         pbuf->RingBufRxCtr--;                              /* No, decrement character count            */  
  87.         c = *pbuf->RingBufRxOutPtr++;                      /* Get character from buffer                */  
  88.         if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])   
  89.         {        
  90.             pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];   /* Wrap OUT pointer     */  
  91.         }  
  92.         OS_EXIT_CRITICAL();  
  93.         *err = COM_NO_ERR;  
  94.         return (c);  
  95.     } else {  
  96.         OS_EXIT_CRITICAL();  
  97.         *err = COM_RX_EMPTY;  
  98.         c    = 0;                                        /* Buffer is empty, return 0              */  
  99.         return (c);  
  100.     }  
  101. }  
  102.   
  103.   
  104. /************************************************************ 
  105.  * function : COMPutCharB  
  106.  * parameter: char port, port can be COM1 / COM2 
  107.  * return   :    COMM_NO_ERR   if the function was successful (the buffer was not full) 
  108.  *               COMM_TX_FULL  if the buffer was full 
  109.  *               COMM_BAD_CH   if you have specified an incorrect channel 
  110.  
  111.  * usage    : This function is called by your application to send a character on the communications 
  112.  *               channel.  The character to send is first inserted into the Tx buffer and will be sent by 
  113.  *               the Tx ISR.  If this is the first character placed into the buffer, the Tx ISR will be 
  114.  *               enabled.  If the Tx buffer is full, the character will not be sent (i.e. it will be lost) 
  115.  * changelog:  
  116.  *            1.first implimented by liyuan 2010.11.5 
  117.  *************************************************************/  
  118. unsigned char COMPutCharB (unsigned char port, unsigned char c)  
  119. {  
  120. //    unsigned char cpu_sr;  
  121.       
  122.     COM_RING_BUF *pbuf;  
  123.     switch (port)   
  124.     {                                                     /* Obtain pointer to communications channel */  
  125.         case COM1:  
  126.              pbuf = &COM1Buf;  
  127.              break;  
  128.   
  129.         case COM2:  
  130.              pbuf = &COM2Buf;  
  131.              break;  
  132.   
  133.         default:  
  134.              return (COM_BAD_CH);  
  135.     }  
  136.   
  137.     OS_ENTER_CRITICAL();  
  138.     if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {           /* See if buffer is full                    */  
  139.         pbuf->RingBufTxCtr++;                              /* No, increment character count            */  
  140.         *pbuf->RingBufTxInPtr++ = c;                       /* Put character into buffer                */  
  141.         if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) { /* Wrap IN pointer           */  
  142.             pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];  
  143.         }  
  144.         if (pbuf->RingBufTxCtr == 1) {                     /* See if this is the first character       */  
  145.             COMEnableTxInt(port);                          /* Yes, Enable Tx interrupts                */  
  146.             OS_EXIT_CRITICAL();  
  147.         } else {  
  148.             OS_EXIT_CRITICAL();  
  149.         }  
  150.         return (COM_NO_ERR);  
  151.     } else {  
  152.         OS_EXIT_CRITICAL();  
  153.         return (COM_TX_FULL);  
  154.     }  
  155. }  
  156.   
  157. /************************************************************ 
  158.  * function : COMBufferInit  
  159.  * parameter:  
  160.  * return   :     
  161.  * usage    : This function is called by your application to initialize the communications module.  You 
  162.  *             must call this function before calling any other functions. 
  163.  * changelog:  
  164.  *************************************************************/  
  165. void  COMBufferInit (void)  
  166. {  
  167.     COM_RING_BUF *pbuf;  
  168.   
  169.     pbuf                  = &COM1Buf;                     /* Initialize the ring buffer for COM0     */  
  170.     pbuf->RingBufRxCtr    = 0;  
  171.     pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];  
  172.     pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];  
  173.     pbuf->RingBufTxCtr    = 0;  
  174.     pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];  
  175.     pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];  
  176.   
  177.     pbuf                  = &COM2Buf;                     /* Initialize the ring buffer for COM1     */  
  178.     pbuf->RingBufRxCtr    = 0;  
  179.     pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];  
  180.     pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];  
  181.     pbuf->RingBufTxCtr    = 0;  
  182.     pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];  
  183.     pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];  
  184. }  
  185.   
  186. /************************************************************ 
  187.  * function : COMBufferIsEmpty  
  188.  * parameter: char port, port can be COM1 / COM2 
  189.  * return   : char 
  190.  * usage    : This function is called by your application to see  
  191.  *            if any character is available from the communications channel. 
  192.  *            If at least one character is available, the function returns 
  193.  *            FALSE(0) otherwise, the function returns TRUE(1). 
  194.  * changelog:  
  195.  *************************************************************/  
  196. unsigned char  COMBufferIsEmpty (unsigned char port)  
  197. {  
  198. //    unsigned char cpu_sr;  
  199.       
  200.     unsigned char empty;  
  201.     COM_RING_BUF *pbuf;  
  202.     switch (port)   
  203.     {                                                     /* Obtain pointer to communications channel */  
  204.         case COM1:  
  205.              pbuf = &COM1Buf;  
  206.              break;  
  207.   
  208.         case COM2:  
  209.              pbuf = &COM2Buf;  
  210.              break;  
  211.   
  212.         default:  
  213.              return (1);  
  214.     }  
  215.     OS_ENTER_CRITICAL();  
  216.     if (pbuf->RingBufRxCtr > 0)  
  217.     {                                                      /* See if buffer is empty                   */  
  218.         empty = 0;                                         /* Buffer is NOT empty                      */  
  219.     }   
  220.     else   
  221.     {  
  222.         empty = 1;                                         /* Buffer is empty                          */  
  223.     }  
  224.     OS_EXIT_CRITICAL();  
  225.     return (empty);  
  226. }  
  227.   
  228.   
  229. /************************************************************ 
  230.  * function : COMBufferIsFull  
  231.  * parameter: char port, port can be COM1 / COM2 
  232.  * return   : char 
  233.  * usage    : This function is called by your application to see if any more characters can be placed 
  234.  *             in the Tx buffer.  In other words, this function check to see if the Tx buffer is full. 
  235.  *             If the buffer is full, the function returns TRUE otherwise, the function returns FALSE. 
  236.  * changelog:  
  237.  *************************************************************/  
  238. unsigned char COMBufferIsFull (unsigned char port)  
  239. {  
  240. //    unsigned char cpu_sr;  
  241.       
  242.     char full;  
  243.     COM_RING_BUF *pbuf;  
  244.     switch (port)   
  245.     {                                                     /* Obtain pointer to communications channel */  
  246.         case COM1:  
  247.              pbuf = &COM1Buf;  
  248.              break;  
  249.   
  250.         case COM2:  
  251.              pbuf = &COM2Buf;  
  252.              break;  
  253.   
  254.         default:  
  255.              return (1);  
  256.     }  
  257.     OS_ENTER_CRITICAL();  
  258.     if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {           /* See if buffer is full                    */  
  259.         full = 0;                                      /* Buffer is NOT full                       */  
  260.     } else {  
  261.         full = 1;                                       /* Buffer is full                           */  
  262.     }  
  263.     OS_EXIT_CRITICAL();  
  264.     return (full);  
  265. }  
  266.   
  267.   
  268. // This function is called by the Rx ISR to insert a character into the receive ring buffer.  
  269. static void  COMPutRxChar (unsigned char port, unsigned char c)  
  270. {  
  271.     COM_RING_BUF *pbuf;  
  272.   
  273.     switch (port)   
  274.     {                                                     /* Obtain pointer to communications channel */  
  275.         case COM1:  
  276.              pbuf = &COM1Buf;  
  277.              break;  
  278.   
  279.         case COM2:  
  280.              pbuf = &COM2Buf;  
  281.              break;  
  282.   
  283.         default:  
  284.              return;  
  285.     }  
  286.     if (pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) {           /* See if buffer is full                    */  
  287.         pbuf->RingBufRxCtr++;                              /* No, increment character count            */  
  288.         *pbuf->RingBufRxInPtr++ = c;                       /* Put character into buffer                */  
  289.         if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) { /* Wrap IN pointer           */  
  290.             pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];  
  291.         }  
  292.     }  
  293. }  
  294.   
  295.   
  296. // This function is called by the Tx ISR to extract the next character from the Tx buffer.  
  297. //    The function returns FALSE if the buffer is empty after the character is extracted from  
  298. //    the buffer.  This is done to signal the Tx ISR to disable interrupts because this is the  
  299. //    last character to send.  
  300. static unsigned char COMGetTxChar (unsigned char port, unsigned char *err)  
  301. {  
  302.     unsigned char c;  
  303.     COM_RING_BUF *pbuf;  
  304.   
  305.     switch (port)   
  306.     {                                          /* Obtain pointer to communications channel */  
  307.         case COM1:  
  308.              pbuf = &COM1Buf;  
  309.              break;  
  310.   
  311.         case COM2:  
  312.              pbuf = &COM2Buf;  
  313.              break;  
  314.   
  315.         default:  
  316.              *err = COM_BAD_CH;  
  317.              return (0);  
  318.     }  
  319.     if (pbuf->RingBufTxCtr > 0) {                          /* See if buffer is empty                   */  
  320.         pbuf->RingBufTxCtr--;                              /* No, decrement character count            */  
  321.         c = *pbuf->RingBufTxOutPtr++;                      /* Get character from buffer                */  
  322.         if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])   
  323.         {       
  324.             pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];   /* Wrap OUT pointer     */  
  325.         }  
  326.         *err = COM_NO_ERR;  
  327.         return (c);                                        /* Characters are still available           */  
  328.     } else {  
  329.         *err = COM_TX_EMPTY;  
  330.         return (0);                                      /* Buffer is empty                          */  
  331.     }  
  332. }  
  333.   
  334.   
  335. void USART1_IRQHandler(void)  
  336. {  
  337.     unsigned int data;  
  338.     unsigned char err;  
  339.   
  340.     if(USART1->SR & 0x0F)   
  341.     {  
  342.         // See if we have some kind of error     
  343.         // Clear interrupt (do nothing about it!)      
  344.         data = USART1->DR;  
  345.     }  
  346.     else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  
  347.     {    
  348.         data = USART1->DR;  
  349.         COMPutRxChar(COM1, data);                    // Insert received character into buffer       
  350.     }  
  351.     else if(USART1->SR & USART_FLAG_TXE)   
  352.     {  
  353.         data = COMGetTxChar(COM1, &err);             // Get next character to send.                 
  354.         if (err == COM_TX_EMPTY)   
  355.         {                                            // Do we have anymore characters to send ?     
  356.                                                      // No,  Disable Tx interrupts                  
  357.             //USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);  
  358.             USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;  
  359.         }   
  360.         else   
  361.         {  
  362.             USART1->DR = data;        // Yes, Send character                        
  363.         }                                             
  364.     }    
  365. }      
  366.   
  367. void USART2_IRQHandler(void)  
  368. {  
  369.     unsigned int data;  
  370.     unsigned char err;  
  371.   
  372.     if(USART2->SR & 0x0F)   
  373.     {  
  374.         // See if we have some kind of error     
  375.         // Clear interrupt (do nothing about it!)      
  376.         data = USART2->DR;  
  377.     }  
  378.     else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag  
  379.     {    
  380.         data = USART2->DR;  
  381.         COMPutRxChar(COM2, data);                    // Insert received character into buffer       
  382.     }  
  383.     else if(USART2->SR & USART_FLAG_TXE)   
  384.     {  
  385.         data = COMGetTxChar(COM2, &err);             // Get next character to send.                 
  386.         if (err == COM_TX_EMPTY)   
  387.         {                                            // Do we have anymore characters to send ?     
  388.                                                      // No,  Disable Tx interrupts                  
  389.             //USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);  
  390.             USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;  
  391.         }   
  392.         else   
  393.         {  
  394.             USART2->DR = data;        // Yes, Send character                        
  395.         }                                             
  396.     }    
  397. }  

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

[cpp]  view plain  copy
  1. #include "misc.h"  
  2. #include "stm32f10x.h"  
  3. #include "com_buffered.h"  
  4.   
  5. void UART_PutStrB (unsigned char port, uint8_t *str)  
  6. {  
  7.     while (0 != *str)  
  8.     {  
  9.         COMPutCharB(port, *str);  
  10.         str++;  
  11.     }  
  12. }  
  13.   
  14. void USART1_Init(void)  
  15. {  
  16.     GPIO_InitTypeDef GPIO_InitStructure;  
  17.     USART_InitTypeDef USART_InitStructure;  
  18.     NVIC_InitTypeDef NVIC_InitStructure;  
  19.   
  20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);  
  21.       
  22.     /* Configure USART Tx as alternate function push-pull */  
  23.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  24.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  25.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  26.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  27.       
  28.     /* Configure USART Rx as input floating */  
  29.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  30.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  31.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  32.   
  33.     USART_InitStructure.USART_BaudRate = 9600;  
  34.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  35.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  36.     USART_InitStructure.USART_Parity = USART_Parity_No;  
  37.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  38.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  39.     USART_Init(USART1, &USART_InitStructure );   
  40.   
  41.         USART_Cmd(USART1, ENABLE);  
  42.   
  43.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  
  44.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  45.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  46.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  47.     NVIC_Init(&NVIC_InitStructure);  
  48. }  
  49.   
  50. void USART2_Init(void)  
  51. {  
  52.     GPIO_InitTypeDef GPIO_InitStructure;  
  53.     USART_InitTypeDef USART_InitStructure;  
  54.     NVIC_InitTypeDef NVIC_InitStructure;  
  55.   
  56.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);  
  57.       
  58.     /* Configure USART Tx as alternate function push-pull */  
  59.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  60.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  
  61.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  62.     GPIO_Init(GPIOD, &GPIO_InitStructure);  
  63.       
  64.     /* Configure USART Rx as input floating */  
  65.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  66.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
  67.     GPIO_Init(GPIOD, &GPIO_InitStructure);  
  68.       
  69.     GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  
  70.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  
  71.   
  72.     USART_InitStructure.USART_BaudRate = 9600;  
  73.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  74.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  75.     USART_InitStructure.USART_Parity = USART_Parity_No;  
  76.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  77.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  78.     USART_Init(USART2, &USART_InitStructure );   
  79.   
  80.         USART_Cmd(USART2, ENABLE);  
  81.   
  82.     NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;  
  83.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  84.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  
  85.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  86.     NVIC_Init(&NVIC_InitStructure);  
  87. }  
  88.   
  89.   
  90. int main(void)  
  91. {  
  92.     unsigned char c;  
  93.     unsigned char err;  
  94.       
  95.     USART1_Init();  
  96.     USART2_Init();    
  97.     COMBufferInit();  
  98.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
  99.     USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  
  100.   
  101.     UART_PutStrB(COM1, "Hello World!\n");  
  102.     for(;;)  
  103.     {  
  104.         c = COMGetCharB(COM1, &err);  
  105.         if(err == COM_NO_ERR)  
  106.         {  
  107.             COMPutCharB(COM1, c);  
  108.         }  
  109.     }     
  110. }  
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值