久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2231|回復: 0
打印 上一主題 下一主題
收起左側

基于FwLib_STC8的模數轉換ADC介紹和演示用例說明

[復制鏈接]
跳轉到指定樓層
樓主
ID:912806 發表于 2022-1-10 01:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 michaelchain 于 2022-1-10 01:10 編輯

STC8G和STC8H的ADC部分在寄存器設置上基本上一致, 但是不同型號對應的通道編號, 通道數量和精度有區別

通道數量和精度
對應STC8G/STC8H的各個系列的通道數量和精度如下.
[td]
產品線ADC 分辨率ADC 通道數
STC8H1K08 系列10 位9 通道
STC8H1K28 系列10 位12 通道
STC8H3K64S4 系列12 位12 通道
STC8H3K64S2 系列12 位12 通道
STC8H8K64U 系列12 位15 通道
STC8H2K64T 系列12 位15 通道
STC8H4K64TLR 系列12 位15 通道
STC8H4K64TLCD 系列12 位15 通道
STC8H4K64LCD 系列12 位15 通道

通道的選擇使用寄存器ADC_CONTR的低4位, 對應STC8G/STC8H的各個系列, 這個寄存器的數值對應的通道如下
[td]
STC8H1K28STC8H1K08STC8H3K64S4
STC8H3K64S2
STC8H8K64U
STC8H2K64T
STC8H4K64TLR
STC8H4K64TLCD
STC8H4K64LCD
STC8G1K08ASTC8G1K08
STC8G1K08T
STC8G2K64S4
STC8G2K64S2
0000P1.0/ADC0P1.0/ADC0P1.0/ADC0P1.0/ADC0P1.0/ADC0P3.0/ADC0P1.0/ADC0P1.0/ADC0
0001P1.1/ADC1P1.1/ADC1P1.1/ADC1P1.1/ADC1P1.1/ADC1P3.1/ADC1P1.1/ADC1P1.1/ADC1
0010P1.2/ADC2N/AP1.2/ADC2P5.4/ADC2P5.4/ADC2P3.2/ADC2P1.2/ADC2P1.2/ADC2
0011P1.3/ADC3N/AN/AP1.3/ADC3P1.3/ADC3P3.3/ADC3P1.3/ADC3P1.3/ADC3
0100P1.4/ADC4N/AN/AP1.4/ADC4P1.4/ADC4P5.4/ADC4P1.4/ADC4P1.4/ADC4
0101P1.5/ADC5N/AN/AP1.5/ADC5P1.5/ADC5P5.5/ADC5P1.5/ADC5P1.5/ADC5
0110P1.6/ADC6N/AP1.6/ADC6P1.6/ADC6P6.2/ADC6N/AP1.6/ADC6P1.6/ADC6
0111P1.7/ADC7N/AP1.7/ADC7P1.7/ADC7P6.3/ADC7N/AP1.7/ADC7P1.7/ADC7
1000P0.0/ADC8P3.0/ADC8P0.0/ADC8P0.0/ADC8P0.0/ADC8N/AP3.0/ADC8P0.0/ADC8
1001P0.1/ADC9P3.1/ADC9P0.1/ADC9P0.1/ADC9P0.1/ADC9N/AP3.1/ADC9P0.1/ADC9
1010P0.2/ADC10P3.2/ADC10P0.2/ADC10P0.2/ADC10P0.2/ADC10N/AP3.2/ADC10P0.2/ADC10
1011P0.3/ADC11P3.3/ADC11P0.3/ADC11P0.3/ADC11P0.3/ADC11N/AP3.3/ADC11P0.3/ADC11
1100N/AP3.4/ADC12P0.4/ADC12P0.4/ADC12P0.4/ADC12N/AP3.4/ADC12P0.4/ADC12
1101N/AP3.5/ADC13P0.5/ADC13P0.5/ADC13P0.5/ADC13N/AP3.5/ADC13P0.5/ADC13
1110N/AP3.6/ADC14P0.6/ADC14P0.6/ADC14P0.6/ADC14N/AP3.6/ADC14P0.6/ADC14
11111.19Vref1.19Vref1.19Vref1.19Vref1.19Vref1.19Vref1.19Vref1.19Vref

轉換結果的對齊格式

ADC采樣的精度實際上是不能設置的, 采樣都是用的當前型號的最大精度, 結果存儲在[ADC_RES, ADC_RESL]這兩個寄存器. 為方便不同場合使用不同精度的結果, 可以將結果設置為左對齊或右對齊.
  • 當設置為左對齊時, 可以只取ADC_RES的值(8位), 忽略最后兩位.
  • 當設置位右對齊時, 根據實際的精度, 可以取ADC_RES的低4位(12位精度)或低2位(10位精度), 加上ADC_RESL得到最終結果.


轉換的時間消耗

一個完整的 ADC 轉換時間為 = Tsetup + Tduty + Thold + Tconvert
  • Tsetup: 轉換的通道切換時間, 可以設置為1個或2個ADC時鐘周期
  • Tduty: 轉換的采樣時間, 默認是最低的11個ADC時鐘, 最高為32個ADC時鐘周期
  • Thold: 通道選擇的保持時間, 可以選擇1, 2, 3, 4個ADC時鐘周期
  • Tconvert: 轉換時間是固定的, 10bit精度是10個ADC時鐘, 12bit精度是12個ADC時鐘


以上的時間單位都是ADC時鐘周期, 每個ADC時鐘周期占用系統時鐘(SYSCLK)的數量是可以設置的, 使用ADCCFG寄存器的低三位, 可以設置為最低2個系統時鐘周期到最高32個系統時鐘周期
對于轉換的最高頻率, DS上寫了全局限制

  • 10 位 ADC 的速度不能高于 500KHz
  • 12 位 ADC 的速度不能高于 800KHz
  • 轉換的采樣時間不能小于 10,建議設置為 15



硬件連線

STC8G/STC8H的ADC硬件連線有兩種: 帶AVcc,AGrnd和不帶AVcc,AGrnd

帶 AVcc,AGrnd

高端型號STC8H3K64S2系列, 例如會帶這兩個pin腳, 分別對應的是轉換目標的電壓參考值和對地參考值. 對于普通使用, 這兩個可以直接接到VCC和GND, 連線為
  1.    AGrnd   -> GND
  2.    AVcc    -> VCC
  3.    AVref   -> VCC
  4.    Vcc     -> VCC
  5.    Gnd     -> GND
  6.    ADC1    -> 采樣點
復制代碼

不帶 AVcc,AGrnd

低端型號以及STC8G系列不帶這兩個pin, 只需要接AVref, 采樣點與MCU共地連接, 連線為
  1.    AVref   -> VCC
  2.    Vcc     -> VCC
  3.    Gnd     -> GND
  4.    ADC1    -> Test voltage
復制代碼

演示用例說明

以下演示用例, 基于 FwLib_STC8, 源代碼位于 FwLib_STC8/demo/adc 目錄, 可以自行下載或查看. 因為版本演變, 代碼可能與倉庫中的代碼有出入, 以倉庫中的最新版本為準.

關于如何運行演示用例, 可以參考前面介紹的Keil C51和VSCode PlatformIO的配置說明

使用ADC1進行8位ADC轉換, 主動查詢(polling)方式

下面的例子, 使用主動查詢的方式每隔0.1秒對P1.1口進行ADC轉換, 精度8位, 將結果輸出至串口
main.c代碼
  1. #include "fw_hal.h"

  2. void main(void)
  3. {
  4.     uint8_t res;
  5.     // 調整系統頻率, 如果使用STC-ISP設定頻率, 需要將這行注釋掉
  6.     SYS_SetClock();
  7.     // 用于結果輸出
  8.     UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200);
  9.     // 將 ADC1(GPIO P1.1) 設為高阻輸入
  10.     GPIO_P1_SetMode(GPIO_Pin_1, GPIO_Mode_Input_HIP);
  11.     // 使用通道: ADC1
  12.     ADC_SetChannel(0x01);
  13.     // 設置ADC時鐘 = SYSCLK / 2 / (1+1) = SYSCLK / 4
  14.     ADC_SetClockPrescaler(0x01);
  15.     // 設置結果左對齊, 只需要取值 ADC_RES
  16.     ADC_SetResultAlignmentLeft();
  17.     // 開啟ADC電源
  18.     ADC_SetPowerState(HAL_State_ON);

  19.     while(1)
  20.     {
  21.         // 開始轉換
  22.         ADC_Start();
  23.         // 等待兩個系統時鐘
  24.         NOP();
  25.         NOP();
  26.         // 檢查轉換結果標志位是否置位
  27.         while (!ADC_SamplingFinished());
  28.         // 清除結果標志位
  29.         ADC_ClearInterrupt();
  30.         // 讀取結果
  31.         res = ADC_RES;

  32.         // 通過串口1輸出
  33.         UART1_TxString("Result: ");
  34.         UART1_TxHex(res);
  35.         UART1_TxString("\r\n");
  36.         // 等待100ms后再次進行轉換
  37.         SYS_Delay(100);
  38.     }
  39. }
復制代碼


使用ADC1進行10位/12位ADC轉換, 中斷(interrupt)方式

下面的例子, 使用中斷的方式對P1.1口進行ADC連續轉換, 精度10位(或12位, MCU型號不同精度不同), 每隔0.1秒將結果輸出至串口
  1. #include "fw_hal.h"

  2. // 16位變量用于記錄轉換結果
  3. uint16_t res;

  4. // 處理中斷的方法, 使用宏定義保證Keil C51和SDCC的兼容性
  5. INTERRUPT(ADC_Routine, EXTI_VectADC)
  6. {
  7.     // 先清除中斷位
  8.     ADC_ClearInterrupt();
  9.     // 結果低8位
  10.     res = ADC_RESL;
  11.     // 結果高8位
  12.     res |= (ADC_RES & 0x0F) << 8;
  13.     // 再次啟動, 使得ADC連續轉換,
  14.     ADC_Start();
  15. }

  16. void main(void)
  17. {
  18.     // 設置系統頻率
  19.     SYS_SetClock();
  20.     // 結果輸出
  21.     UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200);
  22.     // 設置P11高阻輸入模式
  23.     GPIO_P1_SetMode(GPIO_Pin_1, GPIO_Mode_Input_HIP);
  24.     // 使用通道: ADC1
  25.     ADC_SetChannel(0x01);
  26.     // ADC時鐘 = SYSCLK / 2 / (1+15) = SYSCLK / 32
  27.     ADC_SetClockPrescaler(0x0F);
  28.     // 右對齊, 方便轉換為雙字節的結果
  29.     ADC_SetResultAlignmentRight();
  30.     // 開啟全局中斷和ADC中斷
  31.     EXTI_Global_SetIntState(HAL_State_ON);
  32.     EXTI_ADC_SetIntState(HAL_State_ON);
  33.     // 開啟ADC電源
  34.     ADC_SetPowerState(HAL_State_ON);
  35.     // 開始ADC轉換
  36.     ADC_Start();

  37.     while(1)
  38.     {
  39.         // 轉換結果輸出
  40.         UART1_TxString("Result: ");
  41.         UART1_TxHex(res >> 8);
  42.         UART1_TxHex(res & 0xFF);
  43.         UART1_TxString("\r\n");
  44.         SYS_Delay(100);
  45.     }
  46. }
復制代碼

使用ADC1, ADC2雙通道進行轉換, 中斷(interrupt)方式

下面介紹一個更實用的例子, 中斷形式進行多通道ADC轉換, 可以用于無線小車遙控, 雙聲道音頻采樣等
  1. #include "fw_hal.h"

  2. // 用于記錄當前采樣的通道編號
  3. uint8_t pos;
  4. // 記錄各通道的采樣結果
  5. uint16_t res[2];

  6. // 中斷處理方法
  7. INTERRUPT(ADC_Routine, EXTI_VectADC)
  8. {
  9.     ADC_ClearInterrupt();
  10.     // 記錄采樣結果
  11.     res[pos] = ADC_RESL;
  12.     res[pos] |= (ADC_RES & 0x0F) << 8;
  13.    
  14.     // 切換到下一個通道
  15.     pos = (pos+1) & 0x1;
  16.     if (pos == 0)
  17.     {
  18.         /**
  19.          * 在采樣頻率較高時, 加上這兩句能提高精度. 其機制是切換到開漏模式清除采樣口上的殘留電壓
  20.         GPIO_P1_SetMode(GPIO_Pin_1, GPIO_Mode_InOut_OD);
  21.         GPIO_P1_SetMode(GPIO_Pin_1, GPIO_Mode_Input_HIP);
  22.         */
  23.         ADC_SetChannel(0x01);
  24.     }
  25.     else
  26.     {
  27.         /**
  28.          * Uncomment these lines in high speed ADC
  29.         GPIO_P1_SetMode(GPIO_Pin_2, GPIO_Mode_InOut_OD);
  30.         GPIO_P1_SetMode(GPIO_Pin_2, GPIO_Mode_Input_HIP);
  31.         */
  32.         ADC_SetChannel(0x02);
  33.     }
  34.     ADC_Start();
  35. }

  36. // 下面的代碼和前面的基本上是一樣的, 就不詳細注釋了
  37. void main(void)
  38. {
  39.     SYS_SetClock();
  40.     // For debug print
  41.     UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200);
  42.     // Channel: ADC1
  43.     ADC_SetChannel(0x01);
  44.     // ADC Clock = SYSCLK / 2 / (1+15) = SYSCLK / 32
  45.     ADC_SetClockPrescaler(0x0F);
  46.     // Right alignment, high 2-bit in ADC_RES, low 8-bit in ADC_RESL
  47.     ADC_SetResultAlignmentRight();
  48.     // Enable interrupts
  49.     EXTI_Global_SetIntState(HAL_State_ON);
  50.     EXTI_ADC_SetIntState(HAL_State_ON);
  51.     // Turn on ADC power
  52.     ADC_SetPowerState(HAL_State_ON);
  53.     // Set ADC1(P1.1), ADC2(P1.2) HIP
  54.     GPIO_P1_SetMode(GPIO_Pin_1|GPIO_Pin_2, GPIO_Mode_Input_HIP);
  55.     // Start ADC
  56.     ADC_Start();

  57.     while(1)
  58.     {
  59.         UART1_TxString("Result: ");
  60.         UART1_TxHex(res[0] >> 8);
  61.         UART1_TxHex(res[0] & 0xFF);
  62.         UART1_TxChar(' ');
  63.         UART1_TxHex(res[1] >> 8);
  64.         UART1_TxHex(res[1] & 0xFF);
  65.         UART1_TxString("\r\n");
  66.         SYS_Delay(100);
  67.     }
  68. }
復制代碼


結束


以上就是STC8H使用FwLib_STC8封裝庫進行ADC轉換的演示用例說明. 在實際使用中, 主動查詢(polling)方式下的延時時間精度不高,
如果對采樣的時間間隔精度有要求, 建議使用中斷的形式.




評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费精品久久久久久中文字幕 | 国产精品一区二区在线 | 亚洲精品一| 亚洲一区二区在线播放 | 日韩中文字幕一区 | 久久国产区 | 国内久久精品 | 可以免费观看的av | 黄色免费观看网站 | 黄色国产 | 亚洲成人av | 国产欧美精品区一区二区三区 | 久久综合一区 | 欧美一区永久视频免费观看 | www.yw193.com| 久久国产欧美日韩精品 | 成人欧美一区二区三区黑人孕妇 | 国产精品日韩一区二区 | 久久精品国产久精国产 | 欧美一区视频 | 国产成人精品免费视频大全最热 | 免费成人高清在线视频 | 成人亚洲一区 | 国内av在线 | 欧美 日韩 中文 | 亚洲女人天堂成人av在线 | 精品国产一区二区在线 | 男女网站在线观看 | 日韩一区二区三区精品 | 福利二区| 新91视频网| 日本欧美在线观看视频 | 久久国内精品 | 免费观看色 | 羞羞视频免费在线观看 | 免费观看色 | 五十女人一级毛片 | 久草资源在线视频 | 精品欧美色视频网站在线观看 | 亚洲在线一区二区三区 | 色综合色综合色综合 |