IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 复旦微FM33LE0x单片机之多通道ADC DMA -> 正文阅读

[嵌入式]复旦微FM33LE0x单片机之多通道ADC DMA

一、简介

??本例程以FM33LE026为例,已经过验证,其他型号不保证适用。
??工欲善其事必先利其器,官方手册就是利器,在接触新开发平台时,仔细阅读手册能大幅提升开发进度,避免很多掉头发事件,光头强除外。

  1. FM33LE0系列带有2Msps 12bit SAR-ADC,可实现温度、内部基准和外部输入信号的测量功能。主要特点为:
  • 工作电压 1.65~5.5V;
  • 输入信号幅度 0~ VREF+;
  • 最高采样率 2Msps(FADC=32MHz);
  • 16 个单端输入通道, 包含温度传感器、 内部基准电压、 12 个外部通道;
  • 12 个外部通道(最大 2Msps), 2 个内部通道(温度传感器通道、 AVREF 采样通道);
  • 可配置的采样保持时间;
  • 支持单次转换和连续转换;
  • 支持 DMA;
  • 支持过采样硬件平均, 最高 16bit 输出(256 次平均);

ADC模块框图

  1. ADC 支持以下转换模式:
  • 单次转换
    • 半自动触发(SEMI-AUTOMATIC);
    • 全自动触发(AUTOMATIC);
  • 连续转换

??转换启动可以由软件或事件触发,通过寄存器选择多个事件触发源。

  1. 在多通道转换或连续转换时,使用 DMA 进行转换结果搬移是高效的解决方案。在使能了 DMAEN 的情况下,当每次转换完成后(EOC),ADC controller 模块会产生一个 DMA 请求,通知 DMA 将数据寄存器中的结果搬运到指定的 SRAM 地址。 ADC 的 DMA 接口支持单次模式和循环模式:
    ??在全自动触发模式下(ADC_CFGR2.SEMI=0)和半自动触发模式下(ADC_CFGR2.SEMI=1), ADC 的 DMA接口都可以支持单次模式和循环模式。
  • 单次模式
    转换完成后发起数据搬运,此过程会一直重复,直到软件配置的 DMA 传输长度完成,然后 ADC 控制器会自动停止转换(通过接收 DMA 的传输完成中断标志信号),关闭 ADC,不再向 DMA 发起请求。此模式主要用于对特定模拟信号进行一定长度的采样。
  • 循环模式
    与 DMA 的循环模式相配合, ADC 不断循环转换并发起 DMA 请求,直到软件停止转换。此模式可以用于处理连续不断模拟信号采样。
  1. FM33LE0 系列 DMA 主要特点为:
  • 7通道外设 PDMA,支持 Peripherals<>RAM 传输;
  • 1通道存储器 MDMA,支持 Flash<>RAM 传输;
  • 外设 DMA 传输由外设请求触发, DMA 工作期间不影响 CPU 运行;
  • 外设通道最大传输长度65536字节(64KB),支持 byte/half-word/word 传输;
  • Flash->RAM 通道最大传输长度8192字节,只支持 word 传输;
  • 支持 Flash 连续编程(RAM->Flash),需要预先进行擦除,一次编程固定为256字节;
  • RAM 指针递增、递减;
  • 可产生半程中断和全程中断;
  • 通道优先级可配置(4级优先级);
  1. DMA 工作流程如图所示:
    在这里插入图片描述
  2. 外设 DMA 通道支持循环模式(Circular mode)。循环模式下,当 CHxTSIZE 寄存器定义的传输长度完成后, DMA 不会自动停止,而是返回 RAM 指针寄存器定义的起始地址,继续传输。 DMA 的半程中断和全程中断还是会正常置起, DMA 不会终止传输,直到软件关闭通道。

??结合手册描述和框图可知,ADC 支持 DMA 搬运,为了能够随时取值,ADC 应配置成连续转换模式。同时 DMA 应配置为循环模式,以实时刷新指定的 RAM 区域。

二、代码实现

??可以明确 ADC 工作在连续转换模式下,DMA 工作在循环模式下。

  1. ADC 配置
static void adc_gpio_init(void)
{
    FL_GPIO_InitTypeDef       GPIO_InitStruct;
    FL_ADC_InitTypeDef        Sampling_InitStruct;
    FL_ADC_CommonInitTypeDef  CommonInitStruct;

    /* 初始化 ADC IO */ 
    GPIO_InitStruct.pin = ADC_S1_PIN | ADC_S2_PIN | ADC_S3_PIN;
    GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull = FL_DISABLE;
    GPIO_InitStruct.remapPin = FL_DISABLE;
    FL_GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStruct);
    
    /* ADC 时钟设置 */
    CommonInitStruct.clockSource = FL_RCC_ADC_CLK_SOURCE_RCHF;
    CommonInitStruct.clockPrescaler = FL_RCC_ADC_PSC_DIV8;
    FL_ADC_CommonInit(&CommonInitStruct );

    /* ADC 寄存器设置 */
    Sampling_InitStruct.conversionMode = FL_ADC_CONV_MODE_CONTINUOUS;   // 连续转换
    Sampling_InitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO;
    Sampling_InitStruct.waitMode = FL_DISABLE;
    Sampling_InitStruct.overrunMode = FL_DISABLE;                       
    Sampling_InitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_FORWARD;
    Sampling_InitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_NONE;
    Sampling_InitStruct.triggerSource = FL_ADC_TRGI_PA8;
    Sampling_InitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_16_ADCCLK;
    Sampling_InitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_16_ADCCLK;
    Sampling_InitStruct.oversamplingMode = FL_DISABLE;
    Sampling_InitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_16X;
    Sampling_InitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_4B;
    FL_ADC_Init(ADC, &Sampling_InitStruct);

    FL_ADC_EnableSequencerChannel(ADC, ADC_S1_CH);
    FL_ADC_EnableSequencerChannel(ADC, ADC_S2_CH);
    FL_ADC_EnableSequencerChannel(ADC, ADC_S3_CH);    
       
    FL_ADC_EnableDMAReq(ADC);  
}
  1. DMA 配置
#define  ADC_CH_NUM    3
uint16_t adc_temp[ADC_CH_NUM] = {0};       // 单次转换缓存

static void adc_dma_init(void)
{
    FL_DMA_InitTypeDef      DMA_InitStruct = {0};
    FL_DMA_ConfigTypeDef    DMA_ConfigStruct = {0};  
    
    DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;             // 配置DMA通道功能
    DMA_InitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;                // 配置DMA通道方向
    DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;  // 配置RAM的增减方向
    DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_16B;                         // 配置DMA传输位宽
    DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH;                         // 配置DMA通道优先级
    DMA_InitStruct.circMode = FL_ENABLE;                                    // 配置DMA通道循环缓存
    FL_DMA_Init(DMA, &DMA_InitStruct, DMA_ADC_CH);

    DMA_ConfigStruct.memoryAddress = (uint32_t)&adc_temp;                   // 配置DMA_RAM地址
    DMA_ConfigStruct.transmissionCount = ADC_CH_NUM - 1;                    // 配置DMA传输长度
    FL_DMA_StartTransmission(DMA, &DMA_ConfigStruct, DMA_ADC_CH);  
}
  1. 全局初始化
void adc_init(void)
{
    adc_gpio_init();
    adc_dma_init();
    
    FL_ADC_Enable(ADC);                 // 启动ADC
    FL_DMA_Enable(DMA);                 // 配置DMA全局开关
    FL_ADC_EnableSWConversion(ADC);     // 开始转换
}

??配置完成后,可随时读取 ADC 值,果然拿来主义就是爽。当系统中使用了其他 DMA 功能,需注意 DMA 通道的优先级,以避免重要用户数据丢失。That’s all!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:27:45  更:2022-09-04 01:31:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:05:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计