CH573-07-ADC——RISC-V内核BLE MCU快速开发教程
1.简介
ch573提供一个 12 位逐次逼近型模拟数字转换器 ADC,提供多达 12 个通道,CH573 支持 10 个外部信号源和 2 个内部信号源,CH571 仅支持前 6 个外部信号源和 2 个内部信号源,支持的引脚为: PA4(AIN0)、PA5(AIN1)、PA12(AIN2)、PA13(AIN3)、PA14(AIN4)、PA15(AIN5)、PB6(AIN9)、PB0(AIN8)、PA8(AIN12)、PA9(AIN13)
2. 新建工程
复制并粘贴“CH573_01_led”工程,并重命名为“CH573_07_ADC”。
3. ADC初始化与采集
1) 精简代码
将与串口无关的LED相关程序删除,如下所示:
2) 串口1初始化
复制上一讲的UART1初始化程序,初始化串口1,仅使用PRINT完成串口字符串发送。
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
PRINT("OK\r\n\r\n");
3) ADC初始化(单通道)
//ADC初始化
/* 单通道采样:选择ADC通道0做采样,对应 PA4引脚, 带数据校准功能 */
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);//3.2M 采样频率,无增益
RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
ADC_ChannelCfg(0); //设置ADC采样通道AIN0(PA4)
除了上述普通单通道方式,还支持中断单通道采样、DMA单通道采样、差分通道采样、TouchKey采样等,详细实现方法可以参考官方资料“\EVT\EXAM\ADC”下的工程文件。
4) ADC采样
首先定义ADC采样数据保存的缓冲区:
uint16_t adcBuff[40];
uint32_t adc_get=0;
#define ADC_COUNT 20 //ADC连续采样次数
连续采样:
// 连续采样ADC_COUNT次
for(i = 0; i < ADC_COUNT; i++)
{
adcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;
/*注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候
可能会出现数据溢出的现象,此处采用伪溢出判断*/
if(adcBuff[i]==65535) adcBuff[i]=0;
}
5) 软件滤波
在上面完成了连续的ADC采样,将结果进行冒泡排序,然后去掉首尾,即去掉最大和最小值,最后再取平均值使数据更加准确。
//冒泡排序,去首尾,求平均
for(i = 0; i < ADC_COUNT; i++)
{
PRINT("%d \n", adcBuff[i]);
}
PRINT("\r\n\r\n", adcBuff[i]);
uint32_t mp_temp=0,mp_i=0,mp_j=0;
for(mp_i = 0; mp_i < ADC_COUNT; mp_i++)
{
for(mp_j = 0; mp_j < ADC_COUNT-1-mp_i; mp_j++)
{
if(adcBuff[mp_j]>adcBuff[mp_j+1])
{
mp_temp=adcBuff[mp_j];
adcBuff[mp_j]=adcBuff[mp_j+1];
adcBuff[mp_j+1]=mp_temp;
}
}
}
//排序后
PRINT("adc get %d times:",ADC_COUNT);
for(i = 0; i < ADC_COUNT; i++)
{
PRINT("%d \n", adcBuff[i]);
}
PRINT("\r\n", adcBuff[i]);
//去首尾求和
for(i = 1; i < ADC_COUNT-1; i++)
{
adc_get+=adcBuff[i];
}
//求平均
adc_get=adc_get/(ADC_COUNT-2);
PRINT("adc_get=%d\r\n",adc_get);
4. main.c完整内容
/********************************** (C) COPYRIGHT *******************************
* File Name : Main.c
* Author : FUNIOT.XYZ
* Version : V1.0
* Date : 2020/08/06
* Description : 实验01-LED闪烁
* Copyright : WeChat official accounts "IOT趣制作"
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "CH57x_common.h"
uint16_t adcBuff[40];
uint32_t adc_get=0;
#define ADC_COUNT 20 //ADC连续采样次数
/*********************************************************************
* @fn main
*
* @brief 主函数
*
* @return none
*/
int main()
{
SetSysClock(CLK_SOURCE_PLL_60MHz);
//串口1初始化
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
PRINT("OK\r\n\r\n");
signed short RoughCalib_Value = 0; // ADC粗调偏差值
uint16_t i=0;
//ADC初始化
/* 单通道采样:选择ADC通道0做采样,对应 PA4引脚, 带数据校准功能 */
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);//3.2M 采样频率,无增益
RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
ADC_ChannelCfg(0); //设置ADC采样通道AIN0(PA4)
// 连续采样ADC_COUNT次
for(i = 0; i < ADC_COUNT; i++)
{
adcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;
/*注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候
可能会出现数据溢出的现象,此处采用伪溢出判断*/
if(adcBuff[i]==65535) adcBuff[i]=0;
}
//冒泡排序,去首尾,求平均
// for(i = 0; i < ADC_COUNT; i++)
// {
// PRINT("%d \n", adcBuff[i]);
// }
// PRINT("\r\n\r\n", adcBuff[i]);
uint32_t mp_temp=0,mp_i=0,mp_j=0;
for(mp_i = 0; mp_i < ADC_COUNT; mp_i++)
{
for(mp_j = 0; mp_j < ADC_COUNT-1-mp_i; mp_j++)
{
if(adcBuff[mp_j]>adcBuff[mp_j+1])
{
mp_temp=adcBuff[mp_j];
adcBuff[mp_j]=adcBuff[mp_j+1];
adcBuff[mp_j+1]=mp_temp;
}
}
}
//排序后
PRINT("adc get %d times:",ADC_COUNT);
for(i = 0; i < ADC_COUNT; i++)
{
PRINT("%d \n", adcBuff[i]);
}
PRINT("\r\n", adcBuff[i]);
//去首尾求和
for(i = 1; i < ADC_COUNT-1; i++)
{
adc_get+=adcBuff[i];
}
//求平均
adc_get=adc_get/(ADC_COUNT-2);
PRINT("adc_get=%d\r\n",adc_get);
while(1)
{
DelayMs(1500);
}
}
5. 编译烧录运行
完成烧录后,按下复位运行程序,将PA4引脚使用杜邦线分别悬空、连接GND和连接3.3V,并依次按下复位键,完成ADC采集,可以看到ADC读取的具体数据,如下图:
如果ADC采集正常,结果与最后截图所示相类似,即达到本实验的目的,如果异常,请检查源代码,如有疑问可关注公众号 “IOT趣制作”,将您遇到的问题描述出来,平台收到您的留言后会第一时间进行解决。