lugl4313820 发表于 2022-4-15 14:35

【平头哥RVB2601创意应用开发】模拟UART之三 实现FIFO接收

<p>硬件的串口是有FIFO功能的,这样接收进来的数据会放到缓冲区里。由于GPIO摸拟的没有缓冲,所以就自己&ldquo;抄&rdquo;了一个FIFO的作品。</p>

<p>fifi.c</p>

<pre>
<code>/**************FIFO Begin**************************************************/
/*溢出标志:0-正常,-1-溢出*/
#include &lt;board.h&gt;
#include &lt;aos/aos.h&gt;


#define TAG "FFO:"
#define FLAGS_OVERRUN 0x0001
aos_mutex_t test_mutex;
/*
      buf- 缓冲区地址
      size- 大小
      free- 空余容量
      putP- 下一个数据写入位置
      getP- 下一个数据独处位置
*/
struct FIFO8{
         char *buf;
         int putP,getP,size,free,flags;
               aos_mutex_t mutex;
};

struct FIFO8 _FIFO8;
int fifo8_init(struct FIFO8 *fifo,int size);
int fifo8_putPut(struct FIFO8 *fifo, char data);//not mutiply thread safe
int fifo8_get(struct FIFO8 *fifo);   //not mutiply thread safe
void fifo8_status(struct FIFO8 *fifo,int *len);
void fifo8_free(struct FIFO8 *fifo,int *len);
int fifo8_write(struct FIFO8 *fifo,char *data,int len);
int fifo8_read(struct FIFO8 *fifo,char *data,int len);

/*初始化*/
intfifo8_init(struct FIFO8 *fifo,int size) {
       
        int ret=0;

        fifo-&gt;flags=0;            
        fifo-&gt;free=size;
        fifo-&gt;size=size;
        fifo-&gt;putP=0;                     
        fifo-&gt;getP=0;
       
        fifo-&gt;buf=(char *)malloc(size);
        if(fifo-&gt;buf == NULL){
                LOGD(TAG,"malloc fifo buffer failed!\n");
                return -1;
        }
       
        ret =aos_mutex_is_valid(&amp;fifo-&gt;mutex);
        if(ret &lt;0){
                LOGD(TAG,"init mutex failed!\n");
                return -1;
        }
        LOGD(TAG,"init mutex OK!\n");
        return 0;   
}

/*向FIFO 中写入1个数据 */
int fifo8_putPut(struct FIFO8 *fifo, char data){
        if(fifo-&gt;free==0){
                fifo-&gt;flags |= FLAGS_OVERRUN;
                return -1;
        }
        fifo-&gt;buf = data;
        fifo-&gt;putP++;
        //循环队列缓冲区
        if(fifo-&gt;putP == fifo-&gt;size){
                fifo-&gt;putP = 0;
        }
        fifo-&gt;free--;

        return 0;
}
/*从FIFO 中取出一个数据 */
int fifo8_get(struct FIFO8 *fifo){
        int data;
        if(fifo-&gt;free == fifo-&gt;size){
                return -1;
        }
       
        data = fifo-&gt;buf;
        //fifo-&gt;getP++;
        if(fifo-&gt;getP == fifo-&gt;size){//用来实现循环
                fifo-&gt;getP = 0;
        }
        fifo-&gt;free++;
        return data;
}
/*写入len个字节,返回写入的字节数*/
int fifo8_write(struct FIFO8 *fifo,char *data,int len){
       
        int i=0;
        aos_mutex_lock(&amp;(fifo-&gt;mutex), AOS_WAIT_FOREVER);
       
        if(fifo-&gt;free &lt; len) {
                aos_mutex_unlock(&amp;(fifo-&gt;mutex));       
                LOGD(TAG,"the free size in not enough!\n");
                return 0;
        }
        else {
                LOGI(TAG,"current fifo-&gt;putP =%d \n",fifo-&gt;putP);
                for(i=0;i&lt;len;i++){
                        fifo-&gt;buf = *(data+i);
                        //循环队列缓冲区
                        if(fifo-&gt;putP == fifo-&gt;size){
                                fifo-&gt;putP = 0;
                        }
                        fifo-&gt;free--;
                }
        }
        aos_mutex_unlock(&amp;(fifo-&gt;mutex));       
       
        return len;
}
/*读出len个字节,返回读出的字节数*/
int fifo8_read(struct FIFO8 *fifo,char *data,int len){
        int i=0;
        aos_mutex_lock(&amp;(fifo-&gt;mutex),AOS_WAIT_FOREVER);
       
        if(fifo-&gt;size!=fifo-&gt;free){
                LOGD(TAG,"current fifo-&gt;getP =%d \n",fifo-&gt;getP);
                for(i=0;; i++){
                        *(data+i) =fifo-&gt;buf;
                        if(fifo-&gt;getP == fifo-&gt;size){//用来实现循环
                                fifo-&gt;getP = 0;
                        }
                        fifo-&gt;free++;
                        if(fifo-&gt;size==fifo-&gt;free){
                                LOGD(TAG,"the buffer is no data left!\n");
                                aos_mutex_unlock(&amp;(fifo-&gt;mutex));
                                return i+1;
                        }
                        if(i+1==len){
                                LOGD(TAG,"read data finish!\n");
                                break;
                        }
                }
        }
        else{
                LOGI(TAG,"the buffer is empty!\n");
                aos_mutex_unlock(&amp;(fifo-&gt;mutex));       
                return 0;
        }
       
        aos_mutex_unlock(&amp;(fifo-&gt;mutex));       
       
        return len;
}

/*缓冲区被使用容量*/
void fifo8_status(struct FIFO8 *fifo,int *used){
        aos_mutex_lock(&amp;(fifo-&gt;mutex),AOS_WAIT_FOREVER);
        *used = fifo-&gt;size - fifo-&gt;free;
        aos_mutex_unlock(&amp;(fifo-&gt;mutex));       
}
/*缓冲区剩余容量*/
void fifo8_free(struct FIFO8 *fifo ,int *free){
        aos_mutex_lock(&amp;(fifo-&gt;mutex),AOS_WAIT_FOREVER);
        *free = fifo-&gt;free;
        aos_mutex_unlock(&amp;(fifo-&gt;mutex));
}</code></pre>

<p>2、初始化缓冲区:fifo8_init(&amp;_FIFO8,64);</p>

<p>3、向缓冲区压入数据:</p>

<pre>
<code>                        fifo8_putPut(&amp;_FIFO8,io_uart_para.vm_uart_rx_byte);//将接收的数据压入缓冲区
//                        io_uart_para.vm_uart_rx_buf = io_uart_para.vm_uart_rx_byte;
//                        io_uart_para.vm_uart_rx_flag = io_uart_para.vm_uart_rx_flag +1;                        </code></pre>

<p>4、取出数据,输出到模拟串口:</p>

<pre>
<code>                while(1)
                {
                        i = fifo8_get(&amp;_FIFO8);
                        if(i == -1)
                        {
                                break;
                        }
                        else{
                                send_Char(i);
                        }
                }
                aos_msleep(1);</code></pre>

<p>实验结果:还不是很理想,每200ms 发送一次,有丢包或者数据不对的方。可能接收的数据要做CRC,这样安全稳靠一些。</p>

<p>&nbsp;如果是一秒钟一次,是没问题,有精力再调一下,或者哪位高手帮忙看一下。</p>

<p>&nbsp;至此接串口模拟工程完一段落。下一辑,读取电流传感器。</p>
页: [1]
查看完整版本: 【平头哥RVB2601创意应用开发】模拟UART之三 实现FIFO接收