一、DMA配置
串口的配置在上一篇博客已经交代过,此篇在上一篇的基础上添加DMA功能。 点此跳转.
void USART_DMA_Init(void)
{
dma_parameter_struct dma_init_struct;
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA);
rcu_periph_clock_enable(RCU_CFGCMP);
syscfg_dma_remap_enable(SYSCFG_DMA_REMAP_USART0TX);
/* deinitialize DMA channel1 */
dma_deinit(DMA_CH3);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_addr = (uint32_t)RS485_TX_BUF;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = 11;
dma_init_struct.periph_addr = USART0_TDATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
dma_init(DMA_CH3,&dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH3);
dma_memory_to_memory_disable(DMA_CH3);
}
二、DMA发送数据
void MYDMA_Send(uint8_t *buffer,uint16_t size)
{
DMA_CHCTL(DMA_CH3) &= ~DMA_CHXCTL_CHEN;//失能DMA
DMA_CHMADDR(DMA_CH3) = (uint32_t)buffer; //设置要发送的数据地址
DMA_CHCNT(DMA_CH3) = size ; //设置要发送的字节数目
DMA_CHCTL(DMA_CH3) |= DMA_CHXCTL_CHEN;//使能DMA
}
为了加快代码运行速度,我没有使用库函数方法,直接操作寄存器。
在发送DMA时需要先失能DMA,之后设置发送的数组的地址和要发送的数据字节数,再使能DMA。
void RS_485_SEND(uint8_t *psrc_data,int num)
{
GPIO_BOP(GPIOA) = (uint32_t)GPIO_PIN_8;
MYDMA_Send(psrc_data,num);
while(RESET == usart_flag_get(USART0, USART_FLAG_TC));
GPIO_BC(GPIOA) = (uint32_t)GPIO_PIN_8;
}
因为我使用的RS485接口发送数据,所以这里需要操作485的使能口,使能完485后运行MYDMA_Send()函数。数据就发送到DMA的缓存里面,后面的就交给DMA去发送数据就行了,检查USART_FLAG_TC标志,保证数据发送完成失能485的使能口。