#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的发送要保证内存的连续。之后配置读函数,如果没有数据直接返回,有数据则读数据,就这样将接收到的数据放到缓冲区里面,然后在将缓冲区里面的数据发送出去。