OpenCPU 支持两个模拟输入引脚可用于检测外部电压。请参照管脚定义和ADC 硬件特性。 可以检测的电压范围可分四挡,分别是 1V,2V,3V。本文介绍的数据结构和 API 可以参考 SDK 中 Zyf_adc.h 文件。
直接调用 ZYF_AdcRead 接口即可读取 ADC 值,为确认读取 ADC 可靠性,建议读取多次,并做平均处理。
1.3.1 ZYF_AdcRead 取 读取 ADC 值 函数原型 int32_t ZYF_AdcRead(uint8_t adc_channel, uint8_t adc_scale) 参数 adc_channel: [输入] 取样通道,ADC 引脚为 AUXIN4,通道 ID 值为 4 adc_scale: [输入] 量程 返回结果 ZYF_RET_ERR_CHANNEL_OUTRANGE,ADC 通道超出范围。 ZYF_RET_ERR FATAL,读取 ADC 值时出现一些致命错误。 其他,ADC 采样结果。它是一个 10 位 A / D 转换器,输入电压范围为 0〜2800mV。
本章节主要介绍如何在 SDK 中使用 example_adc.c 单独测试 adc 功能。 编译方法:.\examples\build\对应的.bat 文件双击执行或打开就可以编译。 生成文件:.\out\对应目录\hex\M601_example_**.pac
adc 的例程主要是通过创建定时器,在该定时器中根据设置的时间间隔不断 的去读取 adc 采样值。ADC 采样结果。它是一个 10 位 A / D 转换器,输入电压 范围为 0〜2800mV。
#include <stdint.h> #include "zyf_trace.h" #include "zyf_adc.h" #include "zyf_timer.h" #include "zyf_app.h" #include "zyf_uart.h" #include "zyf_thread.h" #define TIMER_INTERVAL 1000 //units ms typedef struct { ZYF_Timer_t *ptTimer; uint32_t wParam; uint32_t runtimes; } AppTimer_t; static AppTimer_t s_tTimer; static Uart_Param_t g_uart1param; static void ZYF_TimerCallback(void *pvArg) { AppTimer_t *ptAppTimer = (AppTimer_t *)pvArg; int32_t value = -1; static uint32_t runcnt = 0; runcnt++; if (ptAppTimer != NULL) { ZYF_LOG("timer run times %d.",runcnt); ZYF_StartTimer(ptAppTimer->ptTimer, TIMER_INTERVAL); } if (runcnt > ptAppTimer->runtimes && ZYF_StopTimer(ptAppTimer->ptTimer) < 0) { runcnt = 0; ZYF_LOG("Failed to delete timer"); } value = ZYF_AdcRead(ZYF_ADC_CHANNEL_0, ZYF_ADC_SCALE_5V000); ZYF_LOG("ADC0: %d", value); value = ZYF_AdcRead(ZYF_ADC_CHANNEL_1, ZYF_ADC_SCALE_5V000); ZYF_LOG("ADC1: %d", value); } void ZYF_ADCTimerInit(void) { s_tTimer.runtimes = 500; s_tTimer.ptTimer = ZYF_CreateTimer(ZYF_TimerCallback, (void *)&s_tTimer); if (s_tTimer.ptTimer != NULL) { ZYF_StartTimer(s_tTimer.ptTimer, TIMER_INTERVAL); } } void ADCThread_Example(void * Param) { ZYF_MsgQ_t *ptMsg; ZYF_AppMsg_t tMsg; int iRet = -1; ptMsg = ZYF_MsgQCreate(10, sizeof(ZYF_AppMsg_t)); ZYF_LOG("thread enter!"); ZYF_ADCTimerInit(); while (1) { ZYF_LOG("in while."); iRet = ZYF_MsgQGet(ptMsg, (void *)&tMsg); if (iRet < 0) { ZYF_LOG("Failed to get msg"); ZYF_ThreadSleep(1000); } } } void UartWriteCallBack(void* Param) // general com { Uart_Param_t *uartparam = (Uart_Param_t *)Param; if(Param == NULL) { return; } ZYF_UartWrite(uartparam->port,(uint8_t *)"UartWrite succeed\r\n",strlen("UartWrite succeed\r\n")); ZYF_UartWriteCallbackSwitch(uartparam->port,false); } void UartReadCallBack(void* Param) // { uint32_t recvlen = 0; Uart_Param_t *uartparam = (Uart_Param_t *)Param; ZYF_LOG("Uart%d recv",uartparam->port); while(ZYF_UartRead(uartparam->port, &(uartparam->uartbuf[recvlen]), 1)) { ZYF_LOG("recv :x",uartparam->uartbuf[recvlen]); recvlen++; } ZYF_UartWrite(uartparam->port,uartparam->uartbuf,recvlen); ZYF_UartWriteCallbackSwitch(uartparam->port,true); } static void AppUartInit(void) { int32_t ret; g_uart1param.port = DEBUG_PORT; ZYF_UartRegister(g_uart1param.port, UartReadCallBack,&g_uart1param); ZYF_UartWriteCbRegister(g_uart1param.port,UartWriteCallBack,&g_uart1param); ZYF_UartOpen(g_uart1param.port, 115200, ZYF_FC_NONE); ZYF_LOG("AppUartInit"); return; } static void prvInvokeGlobalCtors(void) { extern void (*__init_array_start[])(); extern void (*__init_array_end[])(); size_t count = __init_array_end - __init_array_start; for (size_t i = 0; i < count; ++i) __init_array_start[i](); } int appimg_enter(void *param) { AppUartInit(); ZYF_LOG("application image enter, param 0x%x", param); prvInvokeGlobalCtors(); ZYF_ThreadCreate("UartThread_Example", ADCThread_Example, NULL, ZYF_PRIORITY_HIGH, 10*1024); return 0; } void appimg_exit(void) { OSI_LOGI(0, "application image exit"); }