杰發科技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);}
}

轉換率公式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167865.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167865.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167865.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一文學會qml自定義組件

文章目錄 最簡單的自定義控件:自定義按鈕組件添加自定義信號在QML中,自定義組件通常是通過創建一個新的QML文件來實現的,這個文件定義了組件的屬性、信號、槽以及界面。你可以將這個組件看作是一個可重用的模塊,它可以在不同的QML場景中使用,而不需要重復編寫代碼。 以下…

洛谷P1157組合的輸出 遞歸:我他又來辣

沒沒沒沒沒沒沒錯&#xff0c;這是一道簡單的遞歸&#xff08;其實是深搜加回溯) 我不管&#xff0c;我說是遞歸就是遞歸。 上題干&#xff1a; 題目描述 排列與組合是常用的數學方法&#xff0c;其中組合就是從 n 個元素中抽出 r個元素&#xff08;不分順序且 r≤n&#x…

查swap內存使用

查詢linux的swap被什么使用了 查詢centos的swap被什么進程使用了 swap內存被什么程序占用&#xff0c;什么程序使用了swap分區&#xff0c;占用swap內存的進程 查系統使用swap內存前10個進程&#xff1a; for i in $( cd /proc;ls |grep "^[0-9]"|awk $0 >10…

大數據技術之數據安全與網絡安全——CMS靶場實訓

大數據技術之數據安全與網絡安全——CMS靶場實訓 在當今數字化時代&#xff0c;大數據技術的迅猛發展帶來了前所未有的數據增長&#xff0c;同時也催生了對數據安全和網絡安全的更為迫切的需求。本篇博客將聚焦于大數據技術背景下的數據安全與網絡安全&#xff0c;并通過CMS&a…

C語言-指針講解(3)

文章目錄 1.字符指針變量1.1 字符指針變量類型是什么1.2字符指針變量的兩種使用方法&#xff1a;1.3字符指針筆試題講解1.3.1 代碼解剖 2.數組指針變量2.1 什么是數組指針2.2 數組指針變量是什么&#xff1f;2.2.3 數組指針變量的舉例 2.3數組指針和指針數組的區別是什么&#…

npm ERR! node-sass@4.13.0 postinstall: `node scripts/build.js`

npm ERR! node-sass4.13.0 postinstall: node scripts/build.js npm config set sass_binary_sitehttps://npm.taobao.org/mirrors/node-sass npm install npm run dev Microsoft Windows [版本 10.0.19045.2965] (c) Microsoft Corporation。保留所有權利。C:\Users\Administr…

4.操作系統常見面試題(2)

3.4 虛擬內存 直接使?物理內存會產??些問題 1. 內存空間利?率的問題&#xff1a;各個進程對內存的使?會導致內存碎?化&#xff0c;當要? malloc 分配?塊很?的內存空間時&#xff0c;可能會出現雖然有?夠多的空閑物理內存&#xff0c;卻沒有?夠?的連續空閑內存這種…

手動實現 git 的 git diff 功能

這是 git diff 后的效果&#xff0c;感覺挺簡單的&#xff0c;不就是 比較新舊版本&#xff0c;新增了就用 "" 顯示新加一行&#xff0c;刪除了就用 "-" 顯示刪除一行&#xff0c;修改了一行就用 "-"、"" 顯示將舊版本中的該行干掉了并…

騰訊云AMD服務器標準型SA5實例AMD EPYC Bergamo處理器

騰訊云服務器標準型SA5實例是最新一代的標準型實例&#xff0c;CPU采用AMD EPYC? Bergamo全新處理器&#xff0c;采用最新DDR5內存&#xff0c;默認網絡優化&#xff0c;最高內網收發能力達4500萬pps。騰訊云百科txybk.com分享騰訊云標準型SA5云服務器CPU、內存、網絡、性能、…

Python 忽略warning警告錯誤 + 跳過報錯繼續執行程序

如何主動產生warning錯誤: import warnings def fxn(): warnings.warn("deprecated", DeprecationWarning) with warnings.catch_warnings(): warnings.simplefilter("ignore") fxn() 那么如何來控制警告錯誤的輸出呢? import warnings warnings.fi…

Modown主題v8.12 安裝教程和主題下載

親測」Modown主題v8.12學習版 上傳好主題選擇該主題就好了設置 設置好的首頁 內容頁&#xff1a; WordPress主題Modown和WordPress插件Erphpdown想必正在使用WordPress程序建站的站長都非常熟悉&#xff0c;因為這兩款應用在WordPress站長圈子里還是比較知名的&#xff0c;所以…

計算機畢業設計 基于SpringBoot的無人智慧超市管理系統的設計與實現 Java實戰項目 附源碼+文檔+視頻講解+答疑

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精…

GoLang Filepath.Walk遍歷優化

原生標準庫在文件量過大時效率和內存均表現不好 1400萬文件遍歷Filepath.Walk 1400萬文件重寫直接調用windows api并處理細節 結論 1400萬文件遍歷時對比 對比條目filepath.walkwindows api并觸發黑科技運行時間710秒22秒內存占用480M38M 關鍵代碼 //超級快的文件遍歷 fun…

【HuggingFace Transformer庫學習筆記】基礎組件學習:pipeline

一、Transformer基礎知識 pip install transformers datasets evaluate peft accelerate gradio optimum sentencepiece pip install jupyterlab scikit-learn pandas matplotlib tensorboard nltk rouge在host文件里添加途中信息&#xff0c;可以避免運行代碼下載模型時候報錯…

企業計算機服務器中了360勒索病毒怎么辦,360勒索病毒解密文件恢復

計算機技術的不斷發展&#xff0c;為企業的生產運營提供了極大便利&#xff0c;不僅提升了辦公效率&#xff0c;還促進了企業的發展。企業計算機在日常工作中一定加以防護&#xff0c;減少網絡威脅事件的產生&#xff0c;確保企業的生產生產運營。最近&#xff0c;網絡上的360后…

微信小程序富文本拓展rich-text

微信小程序富文本插件 功能介紹 支持解析<style>標簽中的全局樣式支持自定義默認的標簽樣式支持自動設置標題 若html中存在title標簽,將自動把title標簽的內容設置到頁面的標題上,并在回調bindparse中返回,可以用于轉發支持添加加載提示 可以在Parser標簽內添加加載提…

8:kotlin 類型檢查和轉換(Type checks and casts)

在運行時可以執行類型檢查以檢查對象的類型。類型轉換將對象強制轉換為不同的類型 is 和 !is 可以使用is或者!is來判斷實例是不是指定的類型 fun main() {var obj : Any "cast"if (obj is String) {println(obj.length) // 4}obj 123if (obj !is String) { pr…

動態規劃 之 鋼條切割

自頂向下遞歸實現(Recursive top-down implementation) 程序CUT-ROD對等式(14.2)進行了實現&#xff0c;偽代碼如下&#xff1a; CUT-ROD(p, n)if n 0return 0q -∞for i 1 to nq max{q, p[i] CUT-ROD(p, n - i)}return q上面解決中重復對一個子結構問題重復求解了&#…

Qt無邊框窗口設置陰影

//設置窗體透明this->setAttribute(Qt::WA_TranslucentBackground, true);//設置無邊框this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);QVBoxLayout* pMainLay new QVBoxLayout(this);CLoginRealWidget* pRealWidget new …

VR全景展示,“超前點播”打開娛樂行業線上營銷門戶

如今&#xff0c;人們的生活水平正在逐步提高&#xff0c;這種提高不僅僅是體現在衣食住行上&#xff0c;更多方面是體現在大眾的娛樂活動上。我們可以看到&#xff0c;相比于過去娛樂種類的匱乏&#xff0c;現如今&#xff0c;各種娛樂活動可謂是百家爭鳴&#xff0c;例如溫泉…