1495|0

6960

帖子

11

TA的资源

版主

楼主
 

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

 

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

fifi.c

/**************FIFO Begin**************************************************/
/*溢出标志:0-正常,-1-溢出*/  
#include <board.h>
#include <aos/aos.h>


#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);
 
/*初始化*/ 
int  fifo8_init(struct FIFO8 *fifo,int size) {  
	
	int ret=0;
 
	fifo->flags=0;            
	fifo->free=size;  
	fifo->size=size;  
	fifo->putP=0;                     
	fifo->getP=0;  
	
	fifo->buf=(char *)malloc(size);
	if(fifo->buf == NULL){
		LOGD(TAG,"malloc fifo buffer failed!\n");
		return -1;
	}
	
	ret =  aos_mutex_is_valid(&fifo->mutex);
	if(ret <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->free==0){  
		fifo->flags |= FLAGS_OVERRUN;  
		return -1;  
	}  
	fifo->buf[fifo->putP] = data;  
	fifo->putP++;  
	//循环队列缓冲区  
	if(fifo->putP == fifo->size){  
		fifo->putP = 0;  
	}  
	fifo->free--;  
 
	return 0;  
}  
/*从FIFO 中取出一个数据 */
int fifo8_get(struct FIFO8 *fifo)  {  
	int data;  
	if(fifo->free == fifo->size){  
		return -1;  
	}  
	
	data = fifo->buf[fifo->getP++];  
	//fifo->getP++;  
	if(fifo->getP == fifo->size){//用来实现循环  
		fifo->getP = 0;  
	}  
	fifo->free++;  
	return data;  
}  
/*写入len个字节,返回写入的字节数*/
int fifo8_write(struct FIFO8 *fifo,char *data,int len){
	
	int i=0;
	aos_mutex_lock(&(fifo->mutex), AOS_WAIT_FOREVER);
	
	if(fifo->free < len) {
		aos_mutex_unlock(&(fifo->mutex));	
		LOGD(TAG,"the free size in not enough!\n");
		return 0;
	}
	else {
		LOGI(TAG,"current fifo->putP =%d \n",fifo->putP);
		for(i=0;i<len;i++){
			fifo->buf[fifo->putP++] = *(data+i);  
			//循环队列缓冲区  
			if(fifo->putP == fifo->size){  
				fifo->putP = 0;  
			}  
			fifo->free--;  
		}
	}
	aos_mutex_unlock(&(fifo->mutex));	
	
	return len;
}
/*读出len个字节,返回读出的字节数*/
int fifo8_read(struct FIFO8 *fifo,char *data,int len){
	int i=0;
	aos_mutex_lock(&(fifo->mutex),AOS_WAIT_FOREVER);
	
	if(fifo->size!=fifo->free){
		LOGD(TAG,"current fifo->getP =%d \n",fifo->getP);
		for(i=0;  ; i++){
			*(data+i) =fifo->buf[fifo->getP++];  
			if(fifo->getP == fifo->size){//用来实现循环  
				fifo->getP = 0;  
			}  
			fifo->free++;  
			if(fifo->size==fifo->free){
				LOGD(TAG,"the buffer is no data left!\n");
				aos_mutex_unlock(&(fifo->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(&(fifo->mutex));	
		return 0;
	}
	
	aos_mutex_unlock(&(fifo->mutex));	
	
	return len;
}
 
/*缓冲区被使用容量*/  
void fifo8_status(struct FIFO8 *fifo,int *used)  {  
	aos_mutex_lock(&(fifo->mutex),AOS_WAIT_FOREVER);
	*used = fifo->size - fifo->free; 
	aos_mutex_unlock(&(fifo->mutex));	
}  
/*缓冲区剩余容量*/
void fifo8_free(struct FIFO8 *fifo ,int *free)  { 
	aos_mutex_lock(&(fifo->mutex),AOS_WAIT_FOREVER); 
	*free = fifo->free;  
	aos_mutex_unlock(&(fifo->mutex));
}

2、初始化缓冲区:fifo8_init(&_FIFO8,64);

3、向缓冲区压入数据:

			fifo8_putPut(&_FIFO8,io_uart_para.vm_uart_rx_byte);//将接收的数据压入缓冲区
//			io_uart_para.vm_uart_rx_buf[io_uart_para.vm_uart_rx_flag] = io_uart_para.vm_uart_rx_byte; 
//			io_uart_para.vm_uart_rx_flag = io_uart_para.vm_uart_rx_flag +1;			

4、取出数据,输出到模拟串口:

		while(1)
		{
			i = fifo8_get(&_FIFO8);
			if(i == -1)
			{
				break;
			}
			else{
				send_Char(i);
			}
		}
		aos_msleep(1);

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

 如果是一秒钟一次,是没问题,有精力再调一下,或者哪位高手帮忙看一下。

 至此接串口模拟工程完一段落。下一辑,读取电流传感器。

点赞 关注(1)
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表