STM32开发实战系列7-数据的搬运工DMA

举报
神龙居市 发表于 2022/03/01 21:28:30 2022/03/01
【摘要】 1. STM32-DMA工作原理 DMA简介ADC的概念DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。STM32F0-DMA简介● 5 个独立的可配置通道 ( 请求 )● 每个...

1. STM32-DMA工作原理

DMA简介

  • ADC的概念
    DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。
    image.png

  • STM32F0-DMA简介
    ● 5 个独立的可配置通道 ( 请求 )
    ● 每个通道都直接连接专用的硬件 DMA 请求
    ● 在同一个 DMA 模块上,多个请求间的优先权可以通过软件编程设置 ( 共有四级:很高、高、
    中等和低 )
    ● 独立数据源和目标数据区的传输宽度 ( 字节、半字、全字 ) 源
    和目标地址必须按数据传输宽度对齐
    ● 支持循环的缓冲器管理
    ● 每个通道都有 3 个事件标志 (DMA 半传输、 DMA 传输完成和 DMA 传输出错 )
    ● 存储器和存储器间的传输
    ● 外设到存储器和存储器到外设,外设到外设间的传输
    ● 闪存、 SRAM 、 APB 和 AHB 外设均可作为访问的源和目标
    ● 可编程的数据传输数目:最大为 65536

  • DMA功能框图和特性
    image.png

STM32F0-DMA通道

  • 各个通道的 DMA 请求一览表
    image.png
    注:
    可修改SYSCFG_CFGR1来配置通道的映射关系
  • STM32F0-DMA通道的优先级
    仲裁器根据优先级管理着通道的请求和启动外设 / 存储器的访问
    优先级管理分两个方面:
    ● 软件:可通过 DMA_CCRx 寄存器配置每个通道的优先级,优先级分4个等级:
    - 最高优先级
    - 高优先级
    - 中等优先级
    - 低优先级
    ● 硬件:如果 2 个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高
    的优先权。举个例子,通道 2 优先于通道 4 。

STM32F0-DMA传输

  • DMA传输模式
    1个DMA控制器,5个可独立配置的通道。所有通道都支持memory to memory的传输、外设到外设的传输、以及外设和memory之间的传输

  • DMA传输的源、目的、长度
    DMA_CPARx 寄存器: 设置外设寄存器地址
    DMA_CMARx 寄存器:设置存储器地址
    DMA_CCRx 寄存器 : 配置数据的传输方向
    如果是存储器到存储器模式,需配置DMA_CCRx的MEM2MEM位
    DMA_CNDTRx 寄存器: 写入需要传输的数据量, (0 到 65535)
    DMA_CCRx 寄存器中的 PSIZE 和 MSIZE 位:
    设置源和目的的数据宽度,两边的位宽尽量保持一致

  • DMA增量设置
    通过设置 DMA_CCRx 寄存器中的 PINC 和 MINC 标志位,外设和存储器的指针在每次传输后可以有选择地完成自动增量
    当设置为增量模式时,下一个要传输的地址将是前一个地址加上增量值,增量值取决与所选的数据宽度为 1 、 2 或 4 。

  • DMA循环模式
    循环模式用于处理循环缓冲区和连续的数据传输 ( 如 ADC 的扫描模式 ) 。在 DMA_CCRx 寄存器中的 CIRC 位用于开启这一功能。
    当启动了循环模式,一组的数据传输完成时,计数寄存器将会自动地被恢复成配置该通道时设置的初值, DMA 操作将会继续进行。
    image.png

STM32F0-DMA中断

  • DMA中断
    每个 DMA 通道都可以在 DMA 传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑,通过设置寄存器的不同位来打开这些中断
    image.png
    注:这些标志位都在中断状态寄存器DMA_ISR中设置

1. ADC_DMA多路采集实例

  • 实例目标:
    利用ADC采集按键以及光照传感器的数据,在按键中断处理程序中启动DMA传输,
    最后在DMA完成中断中打印采集到的数据

  • 代码工作流程
    image.png

  • 电路原理图
    image.png
    image.png

  • CubeMX设置CPU针脚信息
    USART串口波特率115200,
    image.png
    导出代码为ARM-MDK,并生成详细的.c/.h文件

  • Keil代码
    – 在main.c中重写fputc已完成串口输出

/* USER CODE BEGIN 0 */
int fputc(int ch, FILE *f)
{
	while(!(USART1->ISR & (1<<7)));
	USART1->TDR = ch;
	
	return ch;
}
/* USER CODE END 0 */

– gpio.c中重写按键中断回调的实现

/* USER CODE BEGIN 2 */
uint16_t adc_value[2] = {0};
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_8)
	{
		HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_value,2);//
	}
}
/* USER CODE END 2 */

– adc.c中实现DMA中断函数回调的实现

/* USER CODE BEGIN 1 */
extern uint16_t adc_value[2];
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	printf("key adc value = %d\n", adc_value[0]);
	printf("light adc value = %d\n", adc_value[1]);
	memset(adc_value, 0, sizeof(adc_value));
	HAL_ADC_Stop_DMA(hadc);
}
/* USER CODE END 1 */

重要框架代码都通过CubeMX的可视化界面配置后,生成了代码,业务代码只要了解工作逻辑,再关键中断环节上完成工作即可。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。