精华内容
下载资源
问答
  • 程序需在中断处理函数中读取状态寄存器(USART_SR)来判断当前的是什么中断。下面的中断映像图给出了这些中断源是如何汇合成最终的中断信号的。图中也给出了如何控制每一个单独的中断源是否起作用。另外,Cortex-M3 ...

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

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

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

    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

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

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

    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. }      

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

    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  

    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. }  

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

    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. }  
    展开全文
  • 驱动程序是什么.

    千次阅读 2007-09-05 16:32:00
    其实公司里的串口通讯程序只是一个操作串口的应用程序,而驱动程序是由操作系统管理的,由操作系统调用的,有同事问我,什么是应用程序? 我说,应用程序就是调用windows API来实现本身功能的程序.而操作系统要

    我目前所在的部门叫做驱动组,而做的东西本质上不是驱动程序来的.

    所在研发部门把串口通讯程序叫作驱动程序, 我觉得不妥的,今天和同事们讨论了一下.很多同事对驱动程序的概念感到模糊。

    其实公司里的串口通讯程序只是一个操作串口的应用程序,而驱动程序是由操作系统管理的,由操作系统调用的,

    有同事问我,什么是应用程序? 我说,应用程序就是调用windows API来实现本身功能的程序.

    而操作系统要实现本身的某些功能就要调用到驱动程序里的功能.

    调用关系如下:

    Application -----调用--> windows API ----调用----> Driver,

    举个例子,比如应用程序要访问打印机,打印文档,其实就是调用标准的windows   API 函数WriteFile(Handle printer....), 而WriteFile要实现把数据发送到打印机的时候,就需要调用打印机的驱动程序了,这个调用过程,是有操作系统来实现的,我们应用层是不知道的。

     

    展开全文
  • 可能感兴趣的项目设计: USB虚拟串口的资料汇总(包括USB虚拟串口例程) (分享)USB 虚拟串口程序+PC驱动,亲测可用 串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出。...官方demo+驱动程序截图:
  • 自我介绍作为Arduino初学者,程序下载前的第一道门槛就是驱动安装,这个问题难倒了绝大多数的初学者,像...安装的是什么驱动呢?实际上我们的开发板与电脑通信,这中间的工作则是由一块专门的芯片负责:串口芯片,...
    0de1a996c9c6800f5944e0cae9f78ae4.png1a7b6a5328aa31e8226432328ed95921.png自我介绍69b76397be558c8069b2bbd98b25af15.png

    作为Arduino初学者,程序下载前的第一道门槛就是驱动安装,这个问题难倒了绝大多数的初学者,像如何打开设备管理器、如何下载驱动、驱动安装过程出现“感叹号”等等,形形色色的问题一大推,今天呢,特意抽时间给大家整理一篇驱动的正确安装方式,让我们赶快开始吧!

    0de1a996c9c6800f5944e0cae9f78ae4.pngfdc953db70721af1a9c5e26b1fb78977.png如何获取驱动芯片名称69b76397be558c8069b2bbd98b25af15.pngc46a25258fcc4662ccd4df3e712a72f0.png

    安装驱动?安装的是什么驱动呢?实际上我们的开发板与电脑通信,这中间的工作则是由一块专门的芯片负责:串口芯片,主要负责程序的下载、调试,所安装的驱动也是针对它的。不同的开发板所使用的的串口芯片也不同,比如常用的Arduino uno(国产)则使用的CH340系列,而UNO意大利原版的则是用ATmega16U2,再比如ESP8266开发板的驱动芯片型号则为CP2102。驱动芯片的位置一外形参照下图所示:

    f11b6bb2cda932e79d3aa192beee7ce1.png8709d43f939e747c3cce1d841a0f4223.png91fc7d14a87465f0298b2ce27e6a330d.png

    该芯片所在位置,正常情况下都会靠近USB接口,芯片的正面可以清晰的看到型号名称,如果很模糊,则有很大可能性这颗芯片不是正版的,除了CH340系列、CP210X系列还有FT232、PL2303等等,下图有个简单的参数对比,可以了解下:

    53beaf3c5b7bc3a99513fdac11b9dc2e.png

    价格最贵的好像是FT232,童鞋们也可以在taobao搜索相对应的串口驱动模块,价格一目了然

    72c7ad5d4ccb2ecc85b016ba05a124c7.png0de1a996c9c6800f5944e0cae9f78ae4.png86642120691badf2b6d7f01f6e4fdcb9.png正确获取官网正版驱动69b76397be558c8069b2bbd98b25af15.png

    确定了芯片名称,获取驱动文件的方法,同学们第一想到的就是在baidu输入对应的驱动芯片关键词搜索,殊不知这种方式存在诸多不利,其一:你不能保证这个驱动文件安全无毒,用心之人有没有对它做二次“加工”,其二就要吐槽下了,下载一个驱动文件通常会给你下个某某软件的“全家桶”,再或者下载按钮特别隐蔽,比如像下图这种的,你是选高速下载还是普通或本地下载呢?

    6c204b456801413c5187e79d29b4ca45.png

    第二则是向有经验的人请教,比如我啦,问我有没有这个驱动文件(我肯定是有的,也非常愿意为大家答疑解惑,微信:xutoubee),第三通过第三方的驱动软件,如驱动精灵、鲁大师等等,都具备自动识别驱动并安装的功能,这种方式如果你稍微不注意,也会给你来个“全家桶”,最后则是寻求芯片官方的帮助——上官网,这种方式,最安全,最靠谱

    1、CH340系列官网 —— 网址为超链接(点击即可打开)

    ef7ec8f18e47de5203eccf7903daaaa9.png

    这个驱动文件,Windows系统几乎全盘通吃

    2、CP210X —— 网址为超链接(点击即可打开)

    39d59a57b005158e1358f0d33f39a642.png

    网页进去后,点击“DOWNLOADS”,网页最下方找到上图信息,选择红框位置进行下载,还能看到最新版的是20年9月份更新

    3、FT232 —— 网址为超链接(点击即可打开)(非官网网站,但驱动源自官网)

    fa40a42842de69c9856fe62bc5136f1f.png

    4、这个网站很神奇,在这里能找到常用的串口芯片下载:https://www.usb-drivers.org/category/usb-to-serial

    02656cadc44750a080dfc6c6a4f0cadf.png

    打开之后,选择USB to Serial(USB转串口),就能看到很多的驱动文件

    0de1a996c9c6800f5944e0cae9f78ae4.png2c3baaaa2addd9c4f57d4351f4645cd6.png最后69b76397be558c8069b2bbd98b25af15.pngb21ca792a1094371681d322e0d06dd86.png8cd024d61c3ab89f7dcf80128bf8daa2.png

    只要文件没选错,都能够正常安装,最后,好像漏了如何打开设备管理器,win7电脑,鼠标右键我的电脑-属性,在弹出的窗口中,窗口的左上角位置就有“设备管理器”,如下图所示:

    6739ba7c5f64172342d6d2d82718ba52.png

    win10电脑,就最简单了,鼠标移动到屏幕的左下角,然后鼠标右键,从上往下数第六个就是了

    b913a955a509cf5ce3eab9f70fb1eb79.png

    驱动成功安装好的标注,在设备管理器中能看到对顶的COM+数字

    861664ed3543e92de724f8ace9218da2.png0de1a996c9c6800f5944e0cae9f78ae4.pngf6c03d30fafb4a9e2b920beb640efc80.png广告时间69b76397be558c8069b2bbd98b25af15.png

    212261b42777ff98afd7fb0654116c8d.png

    a6cf887f584c08d4af006ac32ed5f6d5.gif
    展开全文
  • virtualcomport驱动支持win7系统的USB转串口线的驱动程序,此工具可以虚拟出COMPort,程式开发者的好帮手!安装好之后可以识别虚拟串口,欢迎大家在下载通用最新版!为什么需要转串口随着电脑技术的发展,并口和...
  • 自我介绍作为Arduino初学者,程序下载前的第一道门槛就是驱动安装,这个问题难倒了绝大多数的初学者,像...安装的是什么驱动呢?实际上我们的开发板与电脑通信,这中间的工作则是由一块专门的芯片负责:串口芯片,...
    204e6a1c66fe7785f473da75c2b1d8ef.pngf1c899ba472e8a4b25bb1ec5796f5c78.png自我介绍169e797e02876d59e6c036b09af0a837.png

    作为Arduino初学者,程序下载前的第一道门槛就是驱动安装,这个问题难倒了绝大多数的初学者,像如何打开设备管理器、如何下载驱动、驱动安装过程出现“感叹号”等等,形形色色的问题一大推,今天呢,特意抽时间给大家整理一篇驱动的正确安装方式,让我们赶快开始吧!

    204e6a1c66fe7785f473da75c2b1d8ef.pngce2fbb8f96cbba8c21d1c44f4167045a.png如何获取驱动芯片名称169e797e02876d59e6c036b09af0a837.pngb2b3e5caa066772d86dc7576ed9c34c4.png

    安装驱动?安装的是什么驱动呢?实际上我们的开发板与电脑通信,这中间的工作则是由一块专门的芯片负责:串口芯片,主要负责程序的下载、调试,所安装的驱动也是针对它的。不同的开发板所使用的的串口芯片也不同,比如常用的Arduino uno(国产)则使用的CH340系列,而UNO意大利原版的则是用ATmega16U2,再比如ESP8266开发板的驱动芯片型号则为CP2102。驱动芯片的位置一外形参照下图所示:

    6a615cd0fc68be131dab5429d45fad28.png9b465d1d257704cffb627ae51d22b0cf.png9cf14b8d9b780dec9860840210a1c4c2.png

    该芯片所在位置,正常情况下都会靠近USB接口,芯片的正面可以清晰的看到型号名称,如果很模糊,则有很大可能性这颗芯片不是正版的,除了CH340系列、CP210X系列还有FT232、PL2303等等,下图有个简单的参数对比,可以了解下:

    3c2707b4dc03a0ad50cdcc7cd08513b7.png

    价格最贵的好像是FT232,童鞋们也可以在taobao搜索相对应的串口驱动模块,价格一目了然

    81c5f24dc0ba4a76d39fdea6bf7e5eb9.png204e6a1c66fe7785f473da75c2b1d8ef.png61bafab3428446ce186a6de9c64a395a.png正确获取官网正版驱动169e797e02876d59e6c036b09af0a837.png

    确定了芯片名称,获取驱动文件的方法,同学们第一想到的就是在baidu输入对应的驱动芯片关键词搜索,殊不知这种方式存在诸多不利,其一:你不能保证这个驱动文件安全无毒,用心之人有没有对它做二次“加工”,其二就要吐槽下了,下载一个驱动文件通常会给你下个某某软件的“全家桶”,再或者下载按钮特别隐蔽,比如像下图这种的,你是选高速下载还是普通或本地下载呢?

    ac359dbb732f7cc47d67052093eb8534.png

    第二则是向有经验的人请教,比如我啦,问我有没有这个驱动文件(我肯定是有的,也非常愿意为大家答疑解惑,微信:xutoubee),第三通过第三方的驱动软件,如驱动精灵、鲁大师等等,都具备自动识别驱动并安装的功能,这种方式如果你稍微不注意,也会给你来个“全家桶”,最后则是寻求芯片官方的帮助——上官网,这种方式,最安全,最靠谱

    1、CH340系列官网 —— 网址为超链接(点击即可打开)

    b35317c8facee30dd21a82861a1cab3b.png

    这个驱动文件,Windows系统几乎全盘通吃

    2、CP210X —— 网址为超链接(点击即可打开)

    4fce8e1b093716c7ced3e217e1c67801.png

    网页进去后,点击“DOWNLOADS”,网页最下方找到上图信息,选择红框位置进行下载,还能看到最新版的是20年9月份更新

    3、FT232 —— 网址为超链接(点击即可打开)(非官网网站,但驱动源自官网)

    13c6ea7dd91620589f73700549033c9e.png

    4、这个网站很神奇,在这里能找到常用的串口芯片下载:https://www.usb-drivers.org/category/usb-to-serial

    01514bb9b8e54097b23e222c4f278495.png

    打开之后,选择USB to Serial(USB转串口),就能看到很多的驱动文件

    204e6a1c66fe7785f473da75c2b1d8ef.png05a81f64d9e1d721d94360bc6cab585d.png最后169e797e02876d59e6c036b09af0a837.pnge5e9027ee0911268112ec6d9f9c5a122.png3a158c68e4636b80470698a0d1a87aaa.png

    只要文件没选错,都能够正常安装,最后,好像漏了如何打开设备管理器,win7电脑,鼠标右键我的电脑-属性,在弹出的窗口中,窗口的左上角位置就有“设备管理器”,如下图所示:

    1fe40ee7ae88da195d480899134afbe4.png

    win10电脑,就最简单了,鼠标移动到屏幕的左下角,然后鼠标右键,从上往下数第六个就是了

    095030a3ad3fe8e4d244894603402b31.png

    驱动成功安装好的标注,在设备管理器中能看到对顶的COM+数字

    644d8e63f01f93ffd127f8f843b2c742.png204e6a1c66fe7785f473da75c2b1d8ef.png5534a8444cc744cad26caa3893b2e4d9.png广告时间169e797e02876d59e6c036b09af0a837.png

    9892bf01fcff46d30a0a9d5890fb1ca6.png

    0d20f3dd0559b34541728744ec8999f5.gif
    展开全文
  • U-Boot源码之串口驱动

    2020-12-09 13:38:22
    (2) 裸机程序直接操控硬件的,操作系统中必须通过驱动来操控硬件。这两个有什么区别?本质区别就是分层。 2.uboot的虚拟地址对硬件操作的影响 (1) 操作系统(指的linux)下MMU肯定开启的,也就是说linux...
  • 程序是基于,ARM11(6410)的触摸屏和串口驱动程序,环境是RVDS2.2,关于触摸屏,我在博客上也有说明,如有疑问请看我的博客,以下是博客地址:http://blog.mcuol.com/TKWTKW/index.htm 如果你有什么成果,希望也能...
  • 最近在做强电的驱动控制电路,驱动电路暂且不谈,控制电路用51单片机控制的,这就涉及到程序的下载,于是就用到串口下载程序。 我的51单片机最小系统用AC220V转DC5V,给单片机最小系统供电,但是利用串口下载...
  • 1)实验平台:正点原子Linux开发板2)摘自《正点原子I.MX6U嵌入式Linux驱动开发指南》关注官方微信号公众号,获取更多资料:正点原子...不管是什么样的接口电平,其驱动程序都是一样的,通过外接RS485这样的芯片就可以...
  • c#没用过,但是对方提供的打印机的DEMO却C#的例程,本来想着DLL跨语言的,应该没什么问题,但是我用vc++编写了一个测试程序,确没有任何数据输出,很简单的例程,我按流程在上面加了打开串口,设置串口,发送...
  • ITOP4412裸机编程-串口驱动

    千次阅读 2018-11-02 18:00:39
    文章目录前言: 前言: &amp;...我在这里说明一下,因为后面可能要移植UBoot最新的程序,而UBoot的程序在最初的一段用汇编写的,所以我们这里也用汇编写,后期移植UBoot就很方便了。 ...
  • 文/Edward“这个STM32开发板...我过去一看就说“这个DTR和RTSRS232串口独有的,我们没有用到。”小明疑惑地又问我“我们不是用的串口吗?怎么会没有?而且我之前用串口的时候,也不记得有用到这两根线啊?”。“你...
  • 安卓 hal 串口驱动学习。。。

    千次阅读 2014-12-16 17:32:03
    最底层的内核 其实并没有什么变化,开发安卓的驱动,最底层的跟linux没有任何分别。差别就在这个驱动要让java虚拟机里面跑的应用程序调用,并且正常使用。在安卓里实现的方法 hal jni server 然后客户端。这个...
  • 内核空间实现的驱动程序,它使用内核资源,内核栈。它包括可加载的内核驱动模块。在这里我想主要说说用户空间驱动程序的编写。 用户空间驱动程序 就是指在用户空间实现的驱动程序。可以认为,它跟普通的用户程序...
  • 内核空间实现的驱动程序,它使用内核资源,内核栈。它包括可加载的内核驱动模块。在这里我想主要说说用户空间驱动程序的编写。 l 用户空间驱动程序 就是指在用户空间实现的驱动程序。可以认为,它跟普通的用户...
  • 位与的作用究竟是什么.为什么要这么做 void CAAT_DriverDlg::OnBnClickedButton1() { //这一部分 是打开串口按键控件 下的程序 // TODO: 在此添加控件通知处理程序代码 UINT uart1, uart2; uart1 = ...
  • 在虚拟机设置中把打印机移除后再添加串行端口该端是服务器,另一端是应用程序,这是什么意思呢?NT式的驱动就是以服务的方式,用工具SRVINSTW来安装开始设置vs2019中的调试设备禁用驱动程序强制签名 远程配置虚拟机...
  • linux驱动程序ioctl函数用法

    千次阅读 2015-04-14 17:58:27
     ioctl设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: int ioctl(int fd, ind cmd, …);  ...
  • 我这里说的ioctl函数驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围。为什么要写篇文章呢,因为我前一阵子被ioctl给搞混 了,这几天才弄明白它,于是在这里清理一下...
  • 我这里说的ioctl函数驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围。写这篇文章因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑。 一、 什么...
  • 2)我怀疑在第二次和以后 ,虽然数据按时写入缓冲区了,但是没能启动发送中断,导致发送不成功,但我查看BSP和驱动程序,感觉都没问题,哎,难道虚拟串口不能这样通过中断操作发送和接收吗? ![图片说明]...
  • 一、 什么是ioctl ioctl设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: <br /...
  • 第一章 设备驱动程序简介 driver在于提供机制,而不是策略。要提供什么功能,如何使用这些功能。 内核功能: 进程管理,内存管理,文件系统,设备控制,网络 设备类型:字符模块、块模块、网络模块 ...
  • 在刚开始的时候,我定义了很多个函数,在发送完数据后立马就接收驱动器回复的数据,在后期想用多线程的时候很容易产生错误,导致驱动器不知道我发送的是什么指令需要使用线程锁来编写,又导致程序非常的复杂。...
  • 一个智能手机的安装驱动程序,有了它,你的智能手机就能结合像“掌中蝶”“玩转手机”之类的软件使用。 很多朋友都很羡慕周围的“玩家”,竟然能把智能手机和计算机通过蓝牙连接以后,在计算机上收发短信。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 415
精华内容 166
关键字:

串口驱动程序是什么