串口dma高速发送

#ifndef buffer_queue_h
#define buffer_queue_h

typedef struct{
	unsigned char * addr;
	unsigned int len;
}tagbufferqueuelist;

typedef struct {
	unsigned char * pbuffer;
	unsigned int bufferlen;
	volatile unsigned int bufferpos;
	tagbufferqueuelist list[20];
	volatile unsigned int listposw;
	volatile unsigned int listposr;
}tagbufferqueueinfo;

extern void bufferqueueinit(tagbufferqueueinfo* pinfo,unsigned char*addr,unsigned int nlen);
extern void bufferqueueset(tagbufferqueueinfo* pinfo,unsigned char*data,unsigned int nlen);
extern int bufferqueueget(tagbufferqueueinfo* pinfo,unsigned char**pdata);




#endif
 #include"stdio.h"
    #include"gd32f30x.h"
    #include"keydiver.h"
		#include"buffer_queue.h"
		#include"stdlib.h"
		tagbufferqueueinfo bufferqueue;
    unsigned char recvbuff[128]={0};
    unsigned char data0[10]={1,2,3,4,5,6,7,8,9,0};
		unsigned char data1[10]={0};
		volatile int dmasending=0;
		dma_parameter_struct dmatxcfg;
		dma_parameter_struct dmarxcfg;
		dma_parameter_struct dmacfg;
		unsigned char* pdata=0;
		unsigned char data2[10]={0};
	  void usartdmasend(unsigned char *pdata,int nlen)
		{
			bufferqueueset(&bufferqueue,pdata,nlen);
			if(!dmasending){
			dmasending=1;
      bufferqueueget(&bufferqueue,&pdata);
			dma_channel_disable(DMA0,DMA_CH3);
			dmatxcfg.memory_addr=(uint32_t)pdata;
			dmatxcfg.number=nlen;
			dma_init(DMA0,DMA_CH3,&dmatxcfg);
			dma_channel_enable(DMA0,DMA_CH3);
			}
			}
		void DMA0_Channel3_IRQHandler()
{	unsigned char*pdata;
	  int nlen=bufferqueueget(&bufferqueue,&pdata);
		if(dma_interrupt_flag_get(DMA0,DMA_CH3,DMA_INT_FLAG_FTF))
			{
			dma_interrupt_flag_clear(DMA0,DMA_CH3,DMA_INT_FLAG_FTF);
				if(nlen>0){
					dma_channel_disable(DMA0,DMA_CH3);
					dmatxcfg.memory_addr=(uint32_t)pdata;
					dmatxcfg.number=nlen;
					dma_init(DMA0,DMA_CH3,&dmatxcfg);
					dma_channel_enable(DMA0,DMA_CH3);
		  }	else{
			
			dmasending=0;
}}}
void DMA0_Channel4_IRQHandler()
{
		if(dma_interrupt_flag_get(DMA0,DMA_CH4,DMA_INT_FLAG_FTF))
		{
			dma_interrupt_flag_clear(DMA0,DMA_CH4,DMA_INT_FLAG_FTF);
			usartdmasend(recvbuff,128);
			dma_channel_disable(DMA0,DMA_CH4);
			dma_init(DMA0,DMA_CH4,&dmarxcfg);
			dma_channel_enable(DMA0,DMA_CH4);
			usartdmasend(recvbuff,128);
		}
}
void USART0_IRQHandler()
{
		int n=128-dma_transfer_number_get(DMA0,DMA_CH4);
	  if(usart_interrupt_flag_get(USART0,USART_INT_FLAG_IDLE))
    {
		usart_interrupt_flag_clear(USART0,USART_INT_FLAG_IDLE);
    usart_data_receive(USART0);
    usartdmasend(recvbuff,n);
    dma_channel_disable(DMA0,DMA_CH4);
    dma_init(DMA0,DMA_CH4,&dmarxcfg);
    dma_channel_enable(DMA0,DMA_CH4);
	  usartdmasend(recvbuff,n);
    }
}
		void usartdma()
		{
		  rcu_periph_clock_enable(RCU_AF);
			rcu_periph_clock_enable(RCU_GPIOA);
			gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_9);
			gpio_init(GPIOA,GPIO_MODE_IPU,GPIO_OSPEED_10MHZ,GPIO_PIN_10);
			rcu_periph_clock_enable(RCU_USART0);
			usart_deinit(USART0);
			usart_baudrate_set(USART0,115200);
			usart_parity_config(USART0,USART_PM_NONE);
			usart_word_length_set(USART0,USART_WL_8BIT);
			usart_stop_bit_set(USART0,USART_STB_1BIT);
			usart_transmit_config(USART0,USART_TRANSMIT_ENABLE);
			usart_receive_config(USART0,USART_RECEIVE_ENABLE);
			usart_dma_transmit_config(USART0,USART_DENT_ENABLE);
			usart_dma_receive_config(USART0,USART_DENR_ENABLE);
			usart_interrupt_enable(USART0,USART_INT_IDLE);
			nvic_irq_enable(USART0_IRQn,2,2);
			usart_enable(USART0);
			rcu_periph_clock_enable(RCU_DMA0);
			dma_deinit(RCU_DMA0,DMA_CH3);
			dmatxcfg.periph_addr  =USART0+0x04;//shift addrss (uint32_t)
      dmatxcfg.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; 
      dmatxcfg.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
      //dmatxcfg.memory_addr  = (uint32_t)data1;
      dmatxcfg.memory_width = DMA_MEMORY_WIDTH_8BIT;
      dmatxcfg.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
      //dmatxcfg.number       = 10U;
      dmatxcfg.direction    = DMA_MEMORY_TO_PERIPHERAL;
      dmatxcfg.priority     = DMA_PRIORITY_LOW;
			dma_interrupt_enable(DMA0,DMA_CH3,DMA_INT_FTF);
			nvic_irq_enable(DMA0_Channel3_IRQn,0,2);
			dma_init(DMA0,DMA_CH3,&dmatxcfg);		
			dma_deinit(RCU_DMA0,DMA_CH4);
			dmarxcfg.periph_addr  =USART0+0x04;
      dmarxcfg.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; 
      dmarxcfg.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
      dmarxcfg.memory_addr  = (uint32_t)recvbuff;//shift addrss (uint32_t)
      dmarxcfg.memory_width = DMA_MEMORY_WIDTH_8BIT;
      dmarxcfg.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
      dmarxcfg.number       = 128U;
      dmarxcfg.direction    = DMA_PERIPHERAL_TO_MEMORY;
      dmarxcfg.priority     = DMA_PRIORITY_LOW;
      dma_interrupt_enable(DMA0,DMA_CH4,DMA_INT_FTF);
			nvic_irq_enable(DMA0_Channel4_IRQn,2,2);
			dma_init(DMA0,DMA_CH4,&dmarxcfg);
    	dma_channel_enable(DMA0,DMA_CH4);
		}
int main()
{
	unsigned char* buffer=malloc(1024);
	bufferqueueinit(&bufferqueue,buffer,1024);
	usartdma();
	while(1){			
		usartdmasend((unsigned char*)123,3);
          }
}
#include"buffer_queue.h"
#include"string.h"
unsigned char *addr;
unsigned char *addr1;
unsigned int len;
int posw;

void bufferqueueinit(tagbufferqueueinfo* pinfo,unsigned char*addr,unsigned int nlen)
{
	pinfo->pbuffer=addr;
	pinfo->bufferlen=nlen;
	pinfo->bufferpos=0;
	memset(pinfo->list,0,sizeof(pinfo->list));
	pinfo->listposw=0;
	pinfo->listposr=0;
}


void bufferqueueset(tagbufferqueueinfo* pinfo,unsigned char*data,unsigned int nlen)
{
	tagbufferqueuelist *plist;
	if(nlen>pinfo->bufferlen){return;}
	 posw=(1+pinfo->listposw)%20;
	while(posw==pinfo->listposr);
	if(pinfo->bufferpos+nlen>pinfo->bufferlen){
		pinfo->bufferpos=0;
	}
	addr=pinfo->pbuffer+pinfo->bufferpos;
	memcpy(addr,data,nlen);
	pinfo->bufferpos+=nlen;
  plist=&pinfo->list[pinfo->listposw];
	plist->addr=addr;
	plist->len=nlen;
	pinfo->listposw=(1+pinfo->listposw)%20;
	
}
int bufferqueueget(tagbufferqueueinfo* pinfo,unsigned char**pdata){
	tagbufferqueuelist *plist;
	if(pinfo->listposw==pinfo->listposr){return 0;}
	plist=&pinfo->list[pinfo->listposr];
	addr1=plist->addr;
	 len=plist->len;
	pinfo->listposr=(pinfo->listposr+1)%128;
	while(pinfo->listposr!=pinfo->listposw)
	{
		plist=&pinfo->list[pinfo->listposr];
		if(plist->addr<addr){break;}
			len+=plist->len;
			pinfo->listposr=(pinfo->listposr+1)%128;
	*pdata=addr;
	return len;
		}}

首先初始化缓冲区,然后编写缓冲区,使用户能将缓冲区里面传入数据,注意下一个写的位置等于读的位置要死等,否则追尾会出错,注意dma的发送要保证内存的连续。之后配置读函数,如果没有数据直接返回,有数据则读数据,就这样将接收到的数据放到缓冲区里面,然后在将缓冲区里面的数据发送出去。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值