当前位置: 首页 > news >正文

杰发科技AC7801——ADC软件触发的简单使用

前言

7801资料读起来不是很好理解,大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器,因此还需要用上DMA方式搬运数据到内存

AC7801的ADC简介

7801的ADC是一种 12 逐次逼近型 模拟数字转换器,拥有 12 路外部通道和 2 路内部通道,支持单次、连续、扫描或间断转换多种模式。模拟监控器特性允许应用程序监测输入电压是否超出设定的电压范围。

特性

12 位分辨率
通道输入电压范围: AVSS < Vin < AVDD
最大转换速率: 1Msps
14 路通道: 12 路外部通道, 1 路内部温度传感器( T-Sensor ), 1 路内部带隙基准(Bandgap ),每路通道可单独配置采样时间
转换序列分为 规则组( regular group )和注入组( injection group
        − 规则组:最多可配置 12 个通道
        − 注入组:最多可配置 4 个通道
8 种操作模式 ( 方便起见,称为 mode x x=1~8)
        − 规则组单通道单次转换 (mode1)
        − 规则组单通道连续转换 (mode2)
        − 规则组扫描 + 注入组扫描模式多通道单次转换 (mode3 注入组扫描模式 )
        − 规则组扫描 + 注入组间隔模式多通道单次转换 (mode3 注入组间隔模式 )
        − 规则组扫描 + 自动触发注入组扫描模式多通道单次转换 (mode4)
        − 规则组扫描 + 注入组扫描模式多通道连续转换 (mode5 注入组扫描模式 )
        − 规则组扫描+注入组间隔模式多通道连续转换(mode5 注入组间隔模式 )
        − 规则组扫描 + 自动触发注入组扫描模式多通道连续转换 (mode6)
        − 规则组子组扫描模式转换 (mode7)
        − 注入组子组扫描模式转换 (mode8)
通过内部软件触发或外部硬件触发启动 ADC
模拟监控器功能:
        − 配置为单个或所有通道电压检查
        − 监控通道电压是否低于低阈值或高于高阈值
中断:
        − 规则或注入组转换结束 (EOC End Of Conversion)
        − 注入组转换结束 (IEOC)
        − 模拟监控器事件 (AMO)
DMA 访问,仅用于规则组通道

典型操作流程

ADC 首先上电,然后可以通过内部 SWSTART 或外部触发源触发 ADC ,该触发来源于其它模块。触发后ADC 转换器单元开始工作,并将选择信号发送至输入通道选择器,根据规则或注入组通道序列逐个选择所需的通道。在一个通道完成转换后,转换结果将根据当前转换通道所属的组存储到 RDR 或 IDRx 中,并且产生相应的 EOC IEOC 标志置位。模拟监控器工作时,如果发生相应的事件则会出现相关的状态标志。

使用DMA

由于规则组通道只有一个数据寄存器,因此建议使用 DMA 功能 ,以避免在有多个规则组通道进行转换时,丢失转换结果。DMA 功能专用于规则组通道。只有规则组通道转换结束标志才会产生 DMA 请求。只有产生了 DMA 请求, DMA 才会将转换数据从ADC_RDR 搬运到用户指定的目标位置。

ADC流程

经典的初始化,DMA初始化。

ADC的初始化,185/186两行注释看的一脸懵逼

ADC的回调

DMA的回调

业务代码

旋转电位器查看打印值

由单个ADC改成多个ADC

AC7801的ADC写的注释相对比较完整,但是没说明软件触发从1个怎么改到多个。

使用时候需要注意下图中红框部分有些DISABLE和ABLE的参数,错了大概率就不可能正常采样。黄框部分就是从1个ADC改成3个需要修改的地方。

读取时候,只需要触发一次ADC0即可

具体代码如下:

#include "adc_sample.h"#define Delay5us                      (APB_BUS_FREQ/200000-1)
#define Delay5ms                      (APB_BUS_FREQ/200-1)
#define Delay1s                       (APB_BUS_FREQ-1)uint8_t g_dmaFinish = 0;     // DMA传输完成
uint8_t g_halfDmaFinish = 0; // DMA传输半完成
uint8_t g_dmaTransError = 0; // DMA传输错误
uint32_t g_ADCValueBuffer[DMA_TRANSFER_NUM + 1] = {0};
uint32_t g_timerCnt = 0;
uint16_t g_regularAverageSampleValue = 0; // 规则组采样平均值
uint16_t g_injectAverageSampleValue = 0;  // 注入组采样平均值
uint16_t g_adcInjectValue[4];
uint8_t g_AMOFlag = 0; // 模拟看门狗事件标志
/*
注意:EOC标志写0或读取ADC_RDR都会清除该标志位。
在进行debug时,如果有打开memory窗口或打开ADC寄存器。
该标志会被debug清除。
*/
uint8_t g_EOCFlag = 0;  // 规则组转换结束标志。
uint8_t g_IEOCFlag = 0; // 注入组转换结束标志。void ADC_Callback(void *device, uint32_t wpara, uint32_t lpara)
{if (wpara & ADC_STR_EOC_Msk) // 规则组中断标志{g_EOCFlag = 1;}if (wpara & ADC_STR_AMO_Msk) // 模拟监控中断标志{g_AMOFlag = 1;}
}void ADC_DMACallback(void *device, uint32_t wpara, uint32_t lpara)
{/*wparam为DMA通道状态,状态含义可参考CHANNELx_STATUS寄存器,CHANNELx_STATUS[2] 传输错误CHANNELx_STATUS[1] 半传输完成(相对设置的transferNum,如果半传输中断有使能,transferNum设为6,则DATA_TRANS_NUM为3时产生中断,进入回调)CHANNELx_STATUS[0] 传输完成*/if ((wpara & 0x01) == 0x1){g_dmaFinish = 1;}if ((wpara & 0x02) == 0x2){g_halfDmaFinish = 1;}if ((wpara & 0x04) == 0x4){g_dmaTransError = 1;}
}void ADC_DMAInit(void)
{uint32_t tmpMemStartAddr = (uint32_t)&g_ADCValueBuffer[0];uint32_t tmpMemEndAddr = (uint32_t)&g_ADCValueBuffer[DMA_TRANSFER_NUM + 1]; ///< Setting memory DMA addressDMA_ConfigType tmpDMAConfig;memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));tmpDMAConfig.memStartAddr = tmpMemStartAddr;             // 设置DMA开始地址tmpDMAConfig.memEndAddr = tmpMemEndAddr;                 // 设置DMA结束地址tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///< Move ADC DR to memorytmpDMAConfig.channelEn = ENABLE;                         ///< 使能DMAx通道tmpDMAConfig.finishInterruptEn = ENABLE;                 ///< 使能DMA传输完成中断tmpDMAConfig.halfFinishInterruptEn = DISABLE;            ///< 去能DMA半传输完成中断tmpDMAConfig.errorInterruptEn = ENABLE;                  ///< 使能DMA传输错误中断tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;   ///< 设置DMA通道优先级,0~3 :优先级由低到高tmpDMAConfig.circular = ENABLE;                          ///< 使能循环模式,如果只想工作一次,设为0即可。tmpDMAConfig.direction = DMA_READ_FROM_PERIPH;           ///< 0: 从外设读取,1:从存储器读取tmpDMAConfig.MEM2MEM = DISABLE;                          ///< 0:在非存储器与存储器之间传输,1:在存储器与存储器之间传输tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME;      ///< MEM字分割传输数,0:32-bit,1:16-bit[15:0]; 2:16-bit[23:16][7:0];3:8-bit。详情可参考AC781X芯片手册  表20-2 可编程数据宽度&数据对齐tmpDMAConfig.memIncrement = ENABLE;                      ///< 1:MEM地址增加tmpDMAConfig.periphIncrement = DISABLE;                  ///< 0:外设地址固定tmpDMAConfig.memSize = DMA_MEM_SIZE_32BIT;               ///< 0:8-bit,1:16-bit,2:32-bittmpDMAConfig.periphSize = DMA_PERIPH_SIZE_16BIT;         ///< 0:8-bit,1:16-bit,2:32-bittmpDMAConfig.transferNum = DMA_TRANSFER_NUM;             ///< DMA通道传输长度tmpDMAConfig.periphSelect = DMA_PEPIRH_ADC0;             // 外设选择tmpDMAConfig.callBack = ADC_DMACallback;                 ///< 设置DMA中断回调DMA_Init(DMA0_CHANNEL0, &tmpDMAConfig); ///< ADC 使用DMA1通道,每个模块对应的DMA通道,可参考 AC781X芯片手册 表20-1 DMA请求列表NVIC_EnableIRQ(DMA0_CHANNEL0_IRQn);     ///< 使能DMA1中断请求
}void ADC_init()
{ADC_ConfigType tempAdcConfig;ADC_ConfigType *adcConfig;adcConfig = &tempAdcConfig;// 配置PINMUXGPIO_SetFunc(GPIOA, GPIO_PIN4, GPIO_FUN2);            ///< ADC_IN6 Analog function enableGPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN2);            ///< ADC_IN7 Analog function enableGPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);            ///< ADC_IN8 Analog function enableadcConfig->clkPsc = ADC_CLK_PRESCALER_1;              ///< Set ADC Clk = 24M/2/(0+1)adcConfig->scanModeEn = ENABLE;                       // 扫描模式adcConfig->continousModeEn = DISABLE;                 // 连续模式adcConfig->regularDiscontinousModeEn = DISABLE;       // 1:打开规则组间断转换模式adcConfig->injectDiscontinousModeEn = DISABLE;        // 1:打开注入组间断转换模式adcConfig->injectAutoModeEn = DISABLE;                // 1:自动注入模式adcConfig->intervalModeEn = DISABLE;                  // 1:注入组为间隔转换模式adcConfig->regularDiscontinousNum = 0;                //adcConfig->EOCInterruptEn = ENABLE;                   // EOC中断使能adcConfig->IEOCInterruptEn = ENABLE;                  // IEOC中断使能adcConfig->interruptEn = ENABLE;                      // 中断使能adcConfig->regularDMAEn = ENABLE;                     // 使能ADC DMAadcConfig->regularTriggerMode = ADC_TRIGGER_INTERNAL; // ADC触发源,内部触发adcConfig->regularSequenceLength = 3;                 // 规则组长度设为3adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT;          // 右对齐adcConfig->callBack = ADC_Callback;                   // 回调adcConfig->powerMode = ADC_POWER_ON;                  // 上电ADC_Init(ADC0, adcConfig);                            ///< ADC works Mode Config// ADC转换率计算公式: 转换时间= 采样时间+转换时间+同步时间  转换时间= (SPT+12)/ADC模块时钟频率+5/APB时钟频率// 备注:1.同步时间为5个APB CLK。2.ADC时钟频率 = APB时钟频率 /(分频系数+1)// 规则组通道设置ADC_SetRegularGroupChannel(ADC0, ADC_CH_7, ADC_SPT_CLK_7, 0); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1usADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 1); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1usADC_SetRegularGroupChannel(ADC0, ADC_CH_6, ADC_SPT_CLK_7, 2); // 采样&转换时间= (7+12)/24000000 + 5/24000000 = 1us
}void ADC_SampleSoftwareTrigerADC(void)
{ADC_init();ADC_DMAInit(); // ADC DMA初始化while (1){// 每次转换数据清零memset(g_ADCValueBuffer, 0x00, sizeof(g_ADCValueBuffer));ADC_SoftwareStartRegularConvert(ADC0); /// 软件触发规则组采样udelay(8); // 需要采样8个通道,延时8us以保证数据采样完成printf("%d %d %d\r\n", g_ADCValueBuffer[0],g_ADCValueBuffer[1],g_ADCValueBuffer[2]);mdelay(100);}
}

转换率公式

相关文章:

杰发科技AC7801——ADC软件触发的简单使用

前言 7801资料读起来不是很好理解&#xff0c;大概率是之前MTK的大佬写的。在此以简单的方式进行描述。我们做一个简单的规则组软件触发Demo。因为规则组通道只有一个数据寄存器&#xff0c;因此还需要用上DMA方式搬运数据到内存。 AC7801的ADC简介 7801的ADC是一种 12 位 逐…...

佳易王个体诊所门诊电子处方软件试用版下载,佳易王电子处方软件的配方模板功能作用与教程

佳易王个体诊所门诊电子处方软件试用版下载&#xff0c;佳易王电子处方软件的配方模板功能作用与教程 1、软件试用版及教程可以点击下方的官网卡片 2、软件中有一个实用的功能&#xff0c;配方模板功能&#xff0c;在开处方单时候可以一键导入配方&#xff0c;节省时间。 而…...

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象&#xff0c;而Rele…...

探索 Vue 中的 bus.$emit:实现组件通信的强大工具

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

2017年五一杯数学建模A题公交车排班问题解题全过程文档及程序

2017年五一杯数学建模 A题 公交车排班问题 原题再现 随着徐州市经济的快速发展&#xff0c;公交车系统对于人们的出行扮演着越来越重要的角色。在公交车资源有限的情况下&#xff0c;合理的编排公交车的行车计划成为公交公司亟待解决的问题。以下给出公交车排班问题中的部分名…...

【c++】——类和对象(下) ——内存管理

作者:chlorine 专栏:c专栏 目录 &#x1f4bb; C/C内存分布 &#x1f4bb;C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free ​编辑 &#x1f4bb;C内存管理方式 &#x1f449;new/delete操作内置类型 &#x1f449;new和delete操作自定义类型 &#x1f…...

大数据平台/大数据技术与原理-实验报告--部署全分布模式Hadoop集群

实验名称 部署全分布模式Hadoop集群 实验性质 &#xff08;必修、选修&#xff09; 必修 实验类型&#xff08;验证、设计、创新、综合&#xff09; 综合 实验课时 2 实验日期 2023.10.16-2023.10.20 实验仪器设备以及实验软硬件要求 专业实验室&#xff08;配有cen…...

Android Gradle 升级到7.x及Maven推送问题

7.0以下的Android插件工程使用Maven上传时脚本如下所示。 plugins {id com.android.libraryid kotlin-androidid maven }// 源代码一起打包 task androidSourcesJar(type: Jar) {archiveClassifier.set(sources)from android.sourceSets.main.java.sourceFiles }uploadArchive…...

【实战】K8S Helm部署Redis Cluster Redisinsight

文章目录 前言部署Redis Cluster安装Redis Insight写在最后 前言 在Web服务的开发过程中&#xff0c;Redis一直以来都有着举足轻重的作用。基本上所有的后端服务都会用这个中间件实现具体的业务场景&#xff0c;比如常作为系统缓存、分布式锁&#xff0c;也可以实现排名、定位…...

3.前端--HTML标签-文本图像链接【2023.11.25】

1.HTML常用标签(文本图像链接&#xff09; 文本标签 标题 <h1> - <h6> 段落<p> 我是一个段落标签 </p> 换行 <br /> <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta ht…...

ctfshow刷题web入门--1--ljcsd

文章目录 ctf.show。信息搜集web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20。爆破。知识1.1 播种随机数生成器-mt_srand。参考web21--重点web22--做不出来web23web24web25web26web27web28。。。命令执行。知识1 绕过正则表达式…...

乘法原理 LeetCode 828. 统计子串中的唯一字符

我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符&#xff0c;并返回唯一字符的个数。 例如&#xff1a;s "LEETCODE" &#xff0c;则其中 "L", "T","C","O","D" 都是唯一字符&#xff0c;…...

python桌面开发PyQt6库和工具库QTDesigner安装和配置

一、安装PyQt6 二、安装pyqt6-tools 三、安装外部工具 四、创建QTDesigner 1.首先查找designer.exe的路径&#xff08;可以自己在窗口中选择&#xff0c;也可以使用Everything搜索&#xff09; 2.使用Everything搜索后会出现多个designer.exe,选中&#xff0c;OpenPath 3.选择…...

火柴棒等式

枚举 只要在保证等式正确的基础上判断火柴棒有没有用完就可以 因为数比较小&#xff0c;而且我不知道最大的等式中的数是多少&#xff0c;索性就设置为999了 还好对效率要求不大&#xff08;doge&#xff09; 要不然就得自己慢慢改最大数来试了 代码如下&#xff1a; #in…...

给定两个字符串 s 和 t ,找不同

题意&#xff1a; 给定两个字符串 s 和 t &#xff0c;它们只包含小写字母。 字符串 t 由字符串 s 随机重排&#xff0c;然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。 示例 1&#xff1a; 输入&#xff1a;s “abcd”, t “abcde” 输出&#xff1a;“e”…...

从权限跳转看Activity的data android:scheme

在应用申请悬浮窗权限的时候&#xff0c;可以跳转到相应的设置界面&#xff0c;并且自动切换到应用的条目&#xff0c;高亮显示一下&#xff0c; android悬浮窗权限怎么申请 在Android中&#xff0c;要申请悬浮窗权限&#xff0c;需要以下步骤&#xff1a; 在 AndroidManifes…...

C++ Qt QFile用法介绍与代码演示

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 打开和关闭文件读取文件写入文件示例代码自定义格式文件解析在Qt 中 QFile 的类用于读写本地文件系统中的文件。它继承自 QIODevice,所以它包含了许多用于数据输入和输出的功…...

Redis面试题:Redis的数据过期策略有哪些?

目录 面试官&#xff1a;Redis的数据过期策略有哪些 ? 惰性删除 定期删除 面试官&#xff1a;Redis的数据过期策略有哪些 ? 候选人&#xff1a; 嗯~&#xff0c;在redis中提供了两种数据过期删除策略 第一种是惰性删除&#xff0c;在设置该key过期时间后&#xff0c;我们…...

1.2.1 C语言结构体初始化方法总结

文章目录 结构体定义通用定义注册事项结构体初始化方法一简述示例方法二简述示例方法三简述示例方法四简述示例方法五简述示例结构体定义 通用定义 常用的结构体定义,有2种形式, 一种是关键字struct 结构体形式,如下...

CentOS 7 安装 Weblogic 14 版本

安装JDK程序 注意&#xff1a;安装weblogic前&#xff0c;先安装JDK&#xff01;&#xff08;要求jdk(1.7以上)&#xff09;&#xff1a; 一、创建用户组weblogic及用户weblogic groupadd weblogic useradd -g weblogic weblogic二、将下载好的jdk及weblogic上传至/home/webl…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...

云原生时代的系统设计:架构转型的战略支点

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、云原生的崛起&#xff1a;技术趋势与现实需求的交汇 随着企业业务的互联网化、全球化、智能化持续加深&#xff0c;传统的 I…...

【Redis】Redis从入门到实战:全面指南

Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...

零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)

经过前面几期的内容我们学习了很多网络安全的知识&#xff0c;而这期内容就涉及到了前面的第六期-RCE模块&#xff0c;第七期-File inclusion模块&#xff0c;第八期-Unsafe Filedownload模块。 什么是"遍历"呢&#xff1a;对学过一些开发语言的朋友来说应该知道&…...

Xcode 16.2 版本 pod init 报错

Xcode 版本升级到 16.2 后&#xff0c;项目执行 pod init 报错&#xff1b; ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchron…...

信息收集:从图像元数据(隐藏信息收集)到用户身份的揭秘 --- 7000

目录 &#x1f310; 访问Web服务 &#x1f4bb; 分析源代码 ⬇️ 下载图片并保留元数据 &#x1f50d; 提取元数据&#xff08;重点&#xff09; &#x1f464; 生成用户名列表 &#x1f6e0;️ 技术原理 图片元数据&#xff08;EXIF 数据&#xff09; Username-Anarch…...