需求描述
使用寄存器实现把RAM中的数据直接传输到usart1的Tx引脚,然后数据被发送到电脑端。


串口1使能DMA传输
代码
/* 10. 串口1使能 DMA传输 */
USART1->CR3 |= USART_CR3_DMAT;
USART1->CR3 |= USART_CR3_DMAR;


寄存器实现
dma.h
#ifndef __DMA_H
#define __DMA_H
#include "stm32f10x.h"
extern uint8_t isFinished;
// 初始化
void DMA1_Init(void);
// 数据传输
void DMA1_Transmit(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen);
#endif
dma.c
#include "dma.h"
// 初始化
void DMA1_Init(void)
{
// 1. 开启时钟
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// 2. DMA相关配置
// 2.1 数据传输方向: 从存储器读,发往串口外设
DMA1_Channel4->CCR |= DMA_CCR4_DIR;
// 2.2 数据宽度: 8位 - 00
DMA1_Channel4->CCR &= ~DMA_CCR4_PSIZE;
DMA1_Channel4->CCR &= ~DMA_CCR4_MSIZE;
// 2.3 地址自增:开启自增,串口地址不能自增
DMA1_Channel4->CCR &= ~DMA_CCR4_PINC;
DMA1_Channel4->CCR |= DMA_CCR4_MINC;
// 2.4 开启数据传输完成中断标志
DMA1_Channel4->CCR |= DMA_CCR4_TCIE;
// 2.5 使能串口的DMA传输功能
USART1->CR3 |= USART_CR3_DMAT;
// 2.6 开启循环传输功能
DMA1_Channel4->CCR |= DMA_CCR4_CIRC;
// 3. NVIC配置
NVIC_SetPriorityGrouping(3);
NVIC_SetPriority(DMA1_Channel4_IRQn, 2);
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}
// 数据传输
void DMA1_Transmit(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen)
{
// 1. 设置外设地址
DMA1_Channel4->CPAR = destAddr;
// 2. 设置存储器地址
DMA1_Channel4->CMAR = srcAddr;
// 3. 设置传输的数据量
DMA1_Channel4->CNDTR = dataLen;
// 4. 开启通道,开始传输数据
DMA1_Channel4->CCR |= DMA_CCR4_EN;
}
// 中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
// 判断中断标志位
if (DMA1->ISR & DMA_ISR_TCIF4)
{
// 清除中断标志位
DMA1->IFCR |= DMA_IFCR_CTCIF4;
// 关闭DMA通道
// DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
}
}
main.c
#include "usart.h"
#include "dma.h"
#include "delay.h"
// 定义变量数组,放置在RAM中,用来存储接收到的数据
uint8_t src[4] = {'a','b','c','d'};
int main(void)
{
// 初始化
USART_Init();
DMA1_Init();
printf("Hello, world!\n\n");
Delay_ms(1);
// 开启DMA通道进行传输
DMA1_Transmit((uint32_t)src, (uint32_t)&(USART1->DR), 4);
while(1)
{}
}
HAL库实现
HAL库配置

增加的代码
uint8_t src[] = {'a', 'b', 'c', 'd', 'e'};
int main(void)
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit_DMA(&huart1, src, 5);
while (1)
{
}
}