本文將介紹基于 rt-thread studio的 sdk開發(fā) adc的應(yīng)用。本實驗是在昨天的《中科藍訊 AB32VG1開發(fā)板OLED顯示實驗》項目基礎(chǔ)上,增加ADC電壓采集的功能,將模擬量通道7采集到的電壓值顯示在OLED顯示屏。
《中科藍訊 AB32VG1開發(fā)板OLED顯示實驗》文章的地址連接:中科藍訊 AB32VG1開發(fā)板OLED顯示實驗 。
根據(jù)說明書,AB32VG1開發(fā)板上有 16個通道的 10 bit的 ADC模塊,最大采樣速度是 78k/s; ADC模塊時鐘的最大速度是 1MHz,有內(nèi)部 100k的上拉電阻。本文通過 RT-Thread Studio配置 ADC驅(qū)動,完成ADC7通道的電壓采集,并顯示在OLED工作,使開發(fā)板上電,自動采集電壓,OLED顯示兩行字符串:第一行顯示“The Voltage”,第二行顯示電壓值“0.00V”。電路原理如圖所示,
從電路原理圖可知,:使用的是 ADC的第 7個通道,根據(jù)原理圖可知對應(yīng)的是 PE5管腳,所以這里需要用杜邦線將PE5接到3.3V電源上,開發(fā)板實物杜邦線連接如圖所示:其中白色是連接PE5與3.3V電源,其余接線為OLED相關(guān),詳見圖中標注。
步驟說明:
首先啟動RT-Thread Studio,在工程項目中打開AB32VG1_IIC_OLED,(如果還沒有這個工程,請看中科藍訊 AB32VG1開發(fā)板OLED顯示實驗 (qq.com)完成工程創(chuàng)建),展開工程,雙擊打開RT-Thread Settings,如下圖所示
雙擊任意軟件包或者點擊右側(cè)的“<<”,都可以進入的配置界面,彈出軟件包和硬件配置界面,如下圖所示,這里切換到硬件選型,如圖所示開啟名字為ADC0的AD轉(zhuǎn)換設(shè)備,打?qū)μ柤纯?。配置好?ctrl+s?保存配置
2. ADC設(shè)備使用示例
ADC設(shè)備的具體使用方式可以參考rt-thread官方開發(fā)文檔,官網(wǎng)連接:ADC設(shè)備 (rt-thread.org),從官方demo看,示例代碼的主要步驟如下:
首先根據(jù) ADC設(shè)備名稱 “adc1”查找設(shè)備獲取設(shè)備句柄,代碼如下:
/*查找設(shè)備 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if(adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
returnRT_ERROR;
}
這里如果設(shè)備不存在,rt_device_find函數(shù)將返回NULL(RT_NULL),串口控制臺會看到打印adc sample run failed! can't find字樣,程序執(zhí)行結(jié)束。
如果設(shè)備存在,下一步就是使能設(shè)備后讀取 adc1設(shè)備對應(yīng)的通道 5的采樣值,
/*使能設(shè)備 */
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
/*讀取采樣值 */
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is :%d \n", value);
這里rt_kprintf將轉(zhuǎn)換之后的數(shù)字量串口打印輸出。
最后根據(jù)讀取的數(shù)字量,做一個標度變換,將數(shù)字量轉(zhuǎn)為為實際的電壓值。根據(jù)分辨率為 12位,參考電壓為 3.3V計算實際的電壓值。代碼如下:
vol = value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
這里rt_kprintf將標度變換之后的采樣電壓值串口打印輸出。
最后關(guān)閉 ADC設(shè)備對應(yīng)通道。代碼如下:
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
demo例程的最后一行代碼是導出到 msh命令列表中,這樣需要在 finsh命令行輸入 tab鍵,彈出支持的命令,輸入 adc_vol_sample,才可以啟動AD轉(zhuǎn)換。
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
3.修改main函數(shù)代碼
在了解了官方ADC設(shè)備示例代碼之后,下面對main函數(shù)修改。首先將官方代碼拷貝到main函數(shù)中,然后修改ADC設(shè)備名稱、ADC通道、參考電壓、轉(zhuǎn)換位數(shù)如下所示:這里設(shè)備為ADC0,模擬量通道為7,采集3.3V電壓,轉(zhuǎn)換位數(shù)為10位。
#defineADC_DEV_NAME "adc0" /* ADC設(shè)備名稱 */
#defineADC_DEV_CHANNEL 7 /* ADC通道 */
#defineREFER_VOLTAGE 330 /*參考電壓 3.3V,數(shù)據(jù)精度乘以100保留2位小數(shù)*/
#defineCONVERT_BITS (1 << 10)? ?/*?轉(zhuǎn)換位數(shù)為12位 */
修改函數(shù)定義staticintadc_vol_sample(int argc,char*argv[])為staticintadc_vol_sample(),同時將程序最后一句代碼MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);刪除,因為直接在主程序調(diào)用,上電執(zhí)行ADC轉(zhuǎn)換,這個就不要了。修改之函數(shù)后代碼如圖所示:
主程序調(diào)用adc_vol_sample,就可以了。要在主程序添加變量staticintadvlue;
編譯沒有錯誤,就可以將程序下載到開發(fā)板運行,打開downloader下載切換到開發(fā)模式,就可以看到ADC轉(zhuǎn)換的結(jié)果如下圖所示.
4.編寫OLED顯示代碼
上一篇文章,通過OLED實現(xiàn)了字符串顯示,要實現(xiàn)電壓值的顯示,這里首先要將整型的電壓值,分解出每一位,然后轉(zhuǎn)化為字符輸出顯示。轉(zhuǎn)換顯示代碼如下所示。
main函數(shù)完整代碼如下,開發(fā)板實際運行如最后圖片所示。
/*
* Copyright (c) 2020-2021, Bluetrum Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/12/10 greedyhao The first version
*/
/**
* Notice!
* All functions or data that are called during an interrupt need to be in RAM.
* You can do it the way exception_isr() does.
*/
#include
#include
#include
#include
#include"board.h"
#include"ssd1306.h"http://包含SSD1306的頭文件
#defineADC_DEV_NAME "adc0" /* ADC設(shè)備名稱 */
#defineADC_DEV_CHANNEL 7 /* ADC通道 */
#defineREFER_VOLTAGE 330 /*參考電壓 3.3V,數(shù)據(jù)精度乘以100保留2位小數(shù)*/
#defineCONVERT_BITS (1 << 10)? ?/*?轉(zhuǎn)換位數(shù)為12位 */
voiddisplay(inttmp)
{
//330
unsignedcharcount;
unsignedchardatas[] = {0, 0, 0, 0, 0};
datas[0] = tmp / 100;
datas[1] = tmp % 100 / 10;
datas[2] = tmp % 100 % 10;
ssd1306_SetCursor(40, 40);//添加代碼,設(shè)置顯示光標位置
ssd1306_WriteChar('0'+datas[0], Font_11x18,White);
ssd1306_WriteChar('.', Font_11x18,White);
for(count = 1; count != 3; count++)
{
ssd1306_WriteChar('0'+datas[count], Font_11x18,White);
}
ssd1306_WriteChar('V', Font_11x18,White);
ssd1306_UpdateScreen();////添加代碼,更新顯示屏信息
}
staticintadc_vol_sample()
{
rt_adc_device_t adc_dev;
unsignedcharTemp_Disp_Buff[17];
rt_uint32_t value, vol;
rt_err_t ret = RT_EOK;
/*查找設(shè)備 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if(adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
returnRT_ERROR;
}
/*使能設(shè)備 */
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
/*讀取采樣值 */
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is :%d \n", value);
/*轉(zhuǎn)換為對應(yīng)電壓值 */
vol = value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
/*關(guān)閉通道 */
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
display(vol);
returnret;
}
intmain(void)
{
uint8_t pin = rt_pin_get("PE.1");
staticintadvlue;
rt_pin_mode(pin, PIN_MODE_OUTPUT);
rt_kprintf("Hello, world\n");
ssd1306_Init();//添加代碼,顯示屏初始化
ssd1306_SetCursor(2, 6);//添加代碼,設(shè)置顯示光標位置
ssd1306_WriteString("The voltage", Font_11x18,White);//添加代碼,設(shè)置顯示內(nèi)容
ssd1306_SetCursor(40, 40);//添加代碼,設(shè)置顯示光標位置
display(0);
ssd1306_UpdateScreen();////添加代碼,更新顯示屏信息
while(1)
{
rt_pin_write(pin, PIN_LOW);
rt_thread_mdelay(500);
rt_pin_write(pin, PIN_HIGH);
rt_thread_mdelay(500);
advlue=adc_vol_sample();
}
}
下一期文章,等電路板返回,做一下DS18B20測溫實現(xiàn)。
編輯:fqj
-
上拉電阻
+關(guān)注
關(guān)注
5文章
360瀏覽量
30660 -
adc
+關(guān)注
關(guān)注
98文章
6524瀏覽量
545220 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5094瀏覽量
97806 -
SDK
+關(guān)注
關(guān)注
3文章
1042瀏覽量
46077 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1301瀏覽量
40265
發(fā)布評論請先 登錄
相關(guān)推薦
評論