在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何利用萬用表測試ADC的精度

科技觀察員 ? 來源:兆易創(chuàng)新GD32 MCU ? 作者:鐘梓銘 ? 2022-04-15 15:00 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

開始

申請開發(fā)板的時候我的開發(fā)目標是基于GD32F310設計一個全雙工串口轉單線半雙工串口的串行舵機控制器,但是這個項目和我本職工作的一個項目比較類似,不方便開源通信部分的代碼,所以臨時改變文章的主題為測試ADC的精度,項目的所有代碼已在github開源,希望文章的內容對朋友們的工作和學習有所幫助;

移植固件庫

到GD32的官網(wǎng)下載文檔三份:GD32F310數(shù)據(jù)手冊/GD32F3x0用戶手冊/GD32F3x0固件庫使用手冊,最新版本固件庫壓縮包一份;固件庫經(jīng)過我的整理,提取了項目開發(fā)的基礎文件并歸類到三個文件夾中,作為基礎空白的工程項目:

bsp:板級支持相關的代碼文件,包含了各個外設模塊的初始化函數(shù)/基本的驅動函數(shù),需要自己實現(xiàn);

user:實現(xiàn)用戶的業(yè)務邏輯代碼,同時也作為系統(tǒng)內核/固件庫和用戶代碼的接口,基礎的接口模板由固件庫壓縮包提供,刪減后可以在其基礎上進行開發(fā),main函數(shù)就在該文件夾的文件中;

device:和芯片內核/外設相關的文件,由固件庫壓縮包提供,內核相關的文件需要刪減,僅保留適合本項目開發(fā)環(huán)境的文件;

實現(xiàn)系統(tǒng)串口

系統(tǒng)串口使用的是USART1在PA2/PA3,由于GD32F310G-START并未提供串口轉USB電路,所以需要使用杜邦線外接一個串口轉USB的模塊與電腦串口軟件進行通信;

進入bsp文件夾,新建文件bsp_uart.c/.h,代碼內容如下:

bsp_uart.h

#ifndef _BSP_UART_H_
#define _BSP_UART_H_

#include "main.h"

#define SYSTEM_UART_PORT            USART1
#define SYSTEM_UART_PERCLK          RCU_USART1
#define SYSTEM_UART_GPIO_PORT       GPIOA
#define SYSTEM_UART_GPIO_PERCLK     RCU_GPIOA
#define SYSTEM_UART_GPIO_TX_PIN     GPIO_PIN_2
#define SYSTEM_UART_GPIO_RX_PIN     GPIO_PIN_3

void System_Uart_Init(void);

#endif

bsp_uart.c

#include "bsp_uart.h"

//系統(tǒng)串口打印初始化
void System_Uart_Init(void)
{
    //初始化串口IO
    rcu_periph_clock_enable(SYSTEM_UART_GPIO_PERCLK);
    gpio_af_set(SYSTEM_UART_GPIO_PORT, GPIO_AF_1, SYSTEM_UART_GPIO_TX_PIN);
    gpio_af_set(SYSTEM_UART_GPIO_PORT, GPIO_AF_1, SYSTEM_UART_GPIO_RX_PIN);
    gpio_mode_set(SYSTEM_UART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SYSTEM_UART_GPIO_TX_PIN);
    gpio_output_options_set(SYSTEM_UART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, SYSTEM_UART_GPIO_TX_PIN);
    gpio_mode_set(SYSTEM_UART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SYSTEM_UART_GPIO_RX_PIN);
    gpio_output_options_set(SYSTEM_UART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, SYSTEM_UART_GPIO_RX_PIN);
    //初始化串口外設
    rcu_periph_clock_enable(SYSTEM_UART_PERCLK);
    usart_deinit(SYSTEM_UART_PORT);
    usart_word_length_set(SYSTEM_UART_PORT, USART_WL_8BIT);
    usart_stop_bit_set(SYSTEM_UART_PORT, USART_STB_1BIT);
    usart_parity_config(SYSTEM_UART_PORT, USART_PM_NONE);
    usart_baudrate_set(SYSTEM_UART_PORT, 115200U);
    usart_receive_config(SYSTEM_UART_PORT, USART_RECEIVE_ENABLE);
    usart_transmit_config(SYSTEM_UART_PORT, USART_TRANSMIT_ENABLE);
    usart_enable(SYSTEM_UART_PORT);
}

實現(xiàn) ADC

ADC的模擬輸入端口需要注意,PA0作為UserKey已經(jīng)通過10k電阻下拉到地,PA2/PA3已作為串口TX/RX使用,它們都不太適合作為本應浮空的ADC通道,故選擇PA1作為ADC的輸入通道;在bsp文件夾內新建文件bsp_adc.c/.h文件,代碼如下:

bsp_adc.h

#ifndef _BSP_ADC_H_
#define _BSP_ADC_H_

#include "main.h"

#define TEST_ADC_GPIO_PERCLK                RCU_GPIOA
#define TEST_ADC_GPIO_PORT                  GPIOA
#define TEST_ADC_GPIO_PIN                   GPIO_PIN_1
#define TEST_ADC_CHANNEL                    ADC_CHANNEL_1
#define TEST_ADC_PERCLK                     RCU_ADC

#define TEST_ADC_SAMPLES_REPEATED_NUMBER    100

void Test_Adc_Init(void);
uint16_t Test_Adc_Init_Sample(void);
void Test_Adc_Value_Update_Thread(void);
void Test_Adc_Value_Update_Thread_Init(void);
uint16_t Test_Adc_Get_Raw(void);
float Test_Adc_Get_Voltage(void);

#endif

bsp_adc.c

#include "bsp_adc.h"

uint16_t adc_test_raw_data = 0 ;    //adc測試輸出原始結果(平均值)
float adc_test_voltage = 0.0 ;      //adc測試輸出電壓值(平均值)

void Test_Adc_Init(void)
{
    //設置模擬輸入IO
    rcu_periph_clock_enable(TEST_ADC_GPIO_PERCLK);
    gpio_mode_set(TEST_ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, TEST_ADC_GPIO_PIN);     //設置測試通道的GPIO為模擬模式
    //設置ADC外設
    rcu_periph_clock_enable(TEST_ADC_PERCLK);
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);                                                  //ADC時鐘源設置
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);                                             //數(shù)據(jù)對齊模式:右對齊
    adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);                                         //規(guī)則轉換通道長度:1
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);          //觸發(fā)源設置:軟件觸發(fā)
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);                                   //觸發(fā)設置:開啟規(guī)則轉換觸發(fā)
    adc_enable();                                                                               //ADC啟動
    rt_thread_mdelay(1);                                                                        //延時穩(wěn)定
    adc_calibration_enable();                                                                   //ADC使用內部校準
}
INIT_BOARD_EXPORT(Test_Adc_Init);

//開始一次AD轉換
uint16_t Test_Adc_Sample(void)
{
    adc_regular_channel_config(0U, TEST_ADC_CHANNEL, ADC_SAMPLETIME_239POINT5);                 //設置測試通道至規(guī)則轉換隊列頭,設置采樣時間
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);                                           //軟件觸發(fā)使能,ADC開始轉換
    while(!adc_flag_get(ADC_FLAG_EOC));                                                         //等待轉換結束
    adc_flag_clear(ADC_FLAG_EOC);
    return (adc_regular_data_read());                                                           //返回轉換結果
}

//獲取原始結果
uint16_t Test_Adc_Get_Raw(void)
{
    return adc_test_raw_data ;
}

//獲取轉換電壓值
float Test_Adc_Get_Voltage(void)
{
    return adc_test_voltage ;
}

移植操作系統(tǒng)

GD32F310只有8k的RAM個人認為是不適合移植操作系統(tǒng)的,內存比較小,沒辦法寫很復雜的線程代碼,其實這個簡單的測試項目也用不上多線程調度,我就是純屬吃飽了撐著了,把F303移植好的RT-Thread直接拖過來用,關于RT-Thread移植的教程在網(wǎng)絡上有非常多,所以我就寫一些大致流程細節(jié)我就不方便展開講了;RT-Thread是一款非常優(yōu)秀好用的國產RTOS,國產硬件配國產軟件實在般配;

新建rtos文件夾,整理rt-thread nano源碼包提供的文件,復制到rtos文件夾中;

main.h內添加 #include "rtthread.h"

找到gd32f3x0_it.c,注釋掉以下幾個函數(shù),使其失效

// void HardFault_Handler(void)
// {
//     /* if Hard Fault exception occurs, go to infinite loop */
//     while(1) {
//     }
// }

// void SVC_Handler(void)
// {
// }

// void PendSV_Handler(void)
// {
// }

// void SysTick_Handler(void)
// {
//     delay_decrement();
// }

找到rtconfig.h,刪掉MDK管理相關的宏,并添加如下代碼

#include "main.h"            //使得RT-Thread能夠找到其他被項目include的文件
#include "finsh_config.h"    //使用控制臺msh功能需要引用此文件
#define RT_USING_FINSH        //使用控制臺
#define RT_USING_HEAP        //取消這個宏的注釋使其有效

找到finsh_port.c,修改和添加我們的串口接口代碼,供控制臺使用

RT_WEAK char rt_hw_console_getchar(void)
{
    /* Note: the initial value of ch must < 0 */
    int ch = -1;
    if(usart_flag_get(SYSTEM_UART_PORT, USART_FLAG_RBNE))
        ch = usart_data_receive(SYSTEM_UART_PORT);
    return ch;
}

void rt_hw_console_output(const char *str)
{
    rt_size_t i = 0, size = 0;
    char a = '\r';
    size = rt_strlen(str);
    for (i = 0; i < size; i++)
    {
        if (*(str + i) == '\n')
        {
            usart_data_transmit(SYSTEM_UART_PORT, a);
            while(RESET == usart_flag_get(SYSTEM_UART_PORT, USART_FLAG_TBE));
        }
        usart_data_transmit(SYSTEM_UART_PORT, *(str + i));
        while(RESET == usart_flag_get(SYSTEM_UART_PORT, USART_FLAG_TBE));
    }
}

如果我沒有遺漏什么細節(jié)的話,此時編譯代碼并下載運行程序,能夠在串口軟件里收到RT-Thread的系統(tǒng)信息打印的內容:

 \ | /
- RT -     Thread Operating System
 / | \     3.1.5 build Apr 10 2022
 2006 - 2020 Copyright by rt-thread team
msh >

擁有了操作系統(tǒng),我們就可以利用RT-Thread的自動初始化功能,運行我們的串口/ADC外設初始化代碼:

INIT_BOARD_EXPORT(Test_Adc_Init);        //ADC初始化函數(shù)加入RTT板級自動初始化隊列
INIT_BOARD_EXPORT(System_Uart_Init);    //系統(tǒng)串口初始化函數(shù)加入RTT板級自動初始化隊列

添加ADC測試代碼

在bsp_adc.c文件中,實現(xiàn)一個RTOS線程代碼,其功能是循環(huán)采集ADC的電壓數(shù)據(jù)并且保存到一個變量中;

//ADC自動轉換線程入口
void Test_Adc_Value_Update_Thread(void)
{
    //轉換次數(shù)記錄,轉換結果累加
    uint32_t count = 0, data_count = 0;
    while (1)
    {
        if(count < TEST_ADC_SAMPLES_REPEATED_NUMBER)//轉換次數(shù)未滿
        {
            data_count += Test_Adc_Sample();//進行一次轉換并累加結果原始數(shù)據(jù)
            count ++;//轉換次數(shù) +1
        }
        else//轉換次數(shù)已滿
        {
            adc_test_raw_data = data_count/TEST_ADC_SAMPLES_REPEATED_NUMBER ;//累加原始數(shù)據(jù)求平均
            adc_test_voltage = 3.3 / 4096 * adc_test_raw_data ;//平均的累加數(shù)據(jù)轉換為電壓值
            data_count = 0 ;//重新開始下一輪轉換
            count = 0 ;
            rt_thread_mdelay(100);//釋放線程
        }
    }
}

//上電后開啟ADC自動轉換線程
void Test_Adc_Value_Update_Thread_Init(void)
{
    rt_thread_t i = rt_thread_create("ADC", Test_Adc_Value_Update_Thread, RT_NULL, 512, 4, 10);
    rt_thread_startup(i);
}
//開機后自動生成并啟動ADC轉換線程
INIT_APP_EXPORT(Test_Adc_Value_Update_Thread_Init);

運行后,adc_test_raw_data/adc_test_voltage這兩個變量每隔100ms更新一次測量的ADC數(shù)值;

到main.c添加如下代碼,使系統(tǒng)控制臺每2s打印輸出一次ADC的測量結果:

#include 

//打印ADC數(shù)據(jù)線程
void App_Print_Adc_Data_Thread(void)
{
    uint8_t str[32];
    while(1)
    {
        rt_thread_mdelay(2000);
        sprintf(str, "RAW:%d VOL:%f\r\n", Test_Adc_Get_Raw(), Test_Adc_Get_Voltage());
        rt_kprintf(str);
    }
}

int main(void)
{
    rt_thread_t i = rt_thread_create("test", App_Print_Adc_Data_Thread, RT_NULL, 1024, 4, 10);
    rt_thread_startup(i);
}

如圖所示,燒錄運行后,可以從串口控制臺得到打印的數(shù)據(jù):

poYBAGJZGAmAJ5fvAAXvo2C3wko080.png

測量電壓

如圖所示,將可調穩(wěn)壓電源的輸出線與開發(fā)板的GND/PA1相連,并且把萬用表的表筆一同并聯(lián)到線路上,以萬用表的讀數(shù)為基準,測量GD32F310的ADC轉換精度:

pYYBAGJZGAWAMND0AAhxmPKFMCA688.png

我這里使用ADC對電源的輸出電壓進行100次采樣后求取平局值,得到的結果如下表所示:

poYBAGJZGAGAWxuGAAawqOeJ2Ko718.png

從表中可以看出,延長ADC采樣時間對ADC精度是有一定幫助的,在低電壓時,ADC的讀數(shù)似乎非常差,原始數(shù)據(jù)會在0-6之間跳動,幾乎無法準確的讀取穩(wěn)定的數(shù)值,直到把輸入電壓提升到50mV才有所穩(wěn)定,個人認為這個情況是電源端的問題,可能可調電源在低壓輸出時不夠穩(wěn)定,手里暫時沒有找到其他可以構成分壓的電路降低電壓去測試,所以0.05V以下的電壓測量結果沒有太大的參考價值,電壓上升到1V以上后ADC的測量就比較穩(wěn)定了,雖然進行100次累加求平均后讀數(shù)依然有跳動的情況,但精度已經(jīng)基本滿足大部分工程的要求

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 萬用表
    +關注

    關注

    88

    文章

    2121

    瀏覽量

    130612
  • adc
    adc
    +關注

    關注

    99

    文章

    6672

    瀏覽量

    548736
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    如何選擇數(shù)字萬用表

    眾所周知,萬用表是電子測試領域最基本的工具,也是一種使用廣泛的儀器,由于其價格低廉、操作簡單、功能齊全、使用廣泛等特點,專業(yè)電子工程師使用上往往忽略以下問題:1、由于萬用表精度、分辨
    發(fā)表于 09-12 09:22

    數(shù)字萬用表使用教程下載

    數(shù)字萬用表使用教程有數(shù)字萬用表的測量技巧,數(shù)字萬用表綜述,數(shù)字萬用表的擴展應用,使用數(shù)字萬用表的注意事項,
    發(fā)表于 09-06 22:09 ?0次下載
    數(shù)字<b class='flag-5'>萬用表</b>使用教程下載

    普通萬用表與數(shù)字萬用表的優(yōu)缺點

    普通萬用表與數(shù)字萬用表的優(yōu)缺點 指針式與數(shù)字式萬用表各有優(yōu)缺點.   指針萬用表是一
    發(fā)表于 11-23 11:03 ?4610次閱讀

    萬用表,萬用表是什么意思

    萬用表,萬用表是什么意思 萬用表具有用途多,量程廣,使用方便等優(yōu)點,是電子測量中最常用的工具。它可以用來測量電阻,交直流電壓和直流電
    發(fā)表于 03-03 10:59 ?7087次閱讀

    萬用表使用技巧

    萬用表使用技巧,輕松學會如何使用萬用表。手把手教你使用萬用表
    發(fā)表于 02-17 11:11 ?0次下載

    數(shù)字萬用表測電流原理_數(shù)字萬用表怎么測電流_數(shù)字萬用表測電流圖解

    使用數(shù)字萬用表測電流有兩種方式。第一種方法是直接使用數(shù)字式萬用表進行電流測量,需要將萬用表與被測電路串聯(lián),這就意味著要將電路斷開,并用數(shù)字式萬用表
    發(fā)表于 11-30 15:18 ?6.2w次閱讀

    萬用表測量電壓原理_萬用表怎么測電壓_萬用表測量電壓的方法

    萬用表是我們常用的測試工具,主要用來測試電壓、電阻、電流等參數(shù),在電子產品的測試、維修及產品制作上起到很大的作用。萬用表的主要組成是由電流
    發(fā)表于 11-30 17:56 ?9.2w次閱讀
    <b class='flag-5'>萬用表</b>測量電壓原理_<b class='flag-5'>萬用表</b>怎么測電壓_<b class='flag-5'>萬用表</b>測量電壓的方法

    如何使用萬用表測試電壓詳細方法和原理說明

    萬用表是我們常用的測試工具,主要用來測試電壓、電阻、電流等參數(shù),在電子產品的測試、維修及產品制作上起到很大的作用。萬用表的主要組成是由電流
    發(fā)表于 02-11 08:00 ?19次下載
    如何使用<b class='flag-5'>萬用表</b><b class='flag-5'>測試</b>電壓詳細方法和原理說明

    數(shù)字萬用表能夠取代模擬萬用表

    毋庸置疑,萬用表可以說是電工最常用的電子測量儀器,但是選擇數(shù)字萬用表還是模擬(指針式)萬用表這是一個問題~有人說數(shù)字萬用表已經(jīng)漸漸取代模擬萬用表
    發(fā)表于 08-07 17:38 ?6964次閱讀

    模擬萬用表與數(shù)字萬用表有什么區(qū)別

    萬用表是一種用于測量電壓、電流、電阻等電氣參數(shù)的電氣測量儀器。萬用表并非都一樣,不同的萬用表尺寸、精度、準確度和測量參數(shù)都各不相同。萬用表
    的頭像 發(fā)表于 10-15 11:00 ?1.5w次閱讀

    萬用表使用與原理 萬用表ADC的原理

      數(shù)字萬用表是高精度儀器。數(shù)字萬用表的雙積分ADC是讓萬用表達到高精度的關鍵器件。   
    發(fā)表于 01-15 15:04 ?1377次閱讀

    萬用表小電阻測試精度的差異

    萬用表小電阻測試精度的差異? 萬用表是一種常用的電子測試儀器,它可以測量電壓、電流和電阻等電學量。在電子電路設計、故障排除和科學實驗等方面,
    的頭像 發(fā)表于 12-11 16:44 ?1474次閱讀

    萬用表的使用方法步驟 萬用表的hFE功能怎么

    萬用表是電子工程中常用的測量儀器,廣泛應用于電路測試、電阻測量、電流測量等方面。下面將詳細介紹萬用表的使用方法步驟以及萬用表的hFE功能使用方法。
    的頭像 發(fā)表于 01-31 13:37 ?7774次閱讀

    勝利萬用表的各個型號

    勝利萬用表是一款非常受歡迎的電子測量工具,廣泛應用于電子、電氣、通信、自動化等領域。在選擇勝利萬用表時,我們需要考慮多個因素,如測量范圍、精度、功能、價格等。 勝利萬用表的分類 勝利
    的頭像 發(fā)表于 07-14 14:27 ?5324次閱讀

    數(shù)字萬用表與模擬萬用表的區(qū)別

    的區(qū)別在于它們的顯示方式。數(shù)字萬用表使用數(shù)字顯示屏來顯示測量結果,而模擬萬用表則使用指針和刻度盤來顯示。 數(shù)字萬用表: 直觀性 :數(shù)字萬用表的讀數(shù)直觀,用戶可以直接從顯示屏上讀取精確的
    的頭像 發(fā)表于 11-01 10:20 ?1609次閱讀
    主站蜘蛛池模板: 国模人体一区二区三区 | 久久女人网 | 好爽~~~~嗯~~~再快点明星 | 亚洲无线视频 | 三级黄色免费网站 | 天天透天天干 | 欧美成人影院免费观 | 亚州一级毛片 | 自拍偷拍福利视频 | 日本黄色的视频 | 午夜欧美视频 | 久久久免费 | 国产99热| 国产精品高清一区二区三区不卡 | 免费被视频网站在线观看 | 亚洲天天综合 | 天天干天天夜 | 91精品福利视频 | 国产一级特黄在线视频 | 热久久这里只有精品 | 日韩一区二区视频在线观看 | 性欧美1819 | 曰本女人一级毛片看一级毛 | 婷婷色网| 午夜免费影视 | 日韩三| 免费一级特黄特色大片在线观看看 | 一区二区三区在线免费 | 99久久国产免费 - 99久久国产免费 | 免费毛片大全 | 日本最色视频 | 久久久久久毛片免费播放 | 亚洲高清日韩精品第一区 | 久久99精品久久久久久野外 | 天天干天天舔 | 狠狠狠操 | 性做久久久久久 | 久热国产精品视频 | 国产高清在线精品 | 男人的天堂网在线 | 在线免费观看一级毛片 |