×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-12-29 发布时间:
|

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

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


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


NVIC_InitTypeDef NVIC_InitStructure;  

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);  

  

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断  

USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断  

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


l发送数据寄存器空中断(TXE)

l发送完成中断(TC)

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


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


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  


[cpp] view plain copy

/* 

 * file: com_buffered.c 

 * author: Li Yuan 

 * platform: STM32F107 

 * date: 2013-5-5 

*


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会