打印

ADC采样

[复制链接]
1318|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丙丁先生|  楼主 | 2024-9-25 06:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************** (C) COPYRIGHT *******************************
* File Name          : Main.c
* Author             : WCH
* Version            : V1.0
* Date               : 2018/12/15
* Description                  : adc采样示例,包括温度检测、单通道检测、差分通道检测、TouchKey检测、中断方式采样。
*******************************************************************************/

#include "CH57x_common.h"

UINT16 abcBuff[40];
volatile UINT8  adclen;

void DebugInit(void)               
{
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
}

int main()
{
    UINT8 i;
    signed short  RoughCalib_Value=0;                // ADC粗调偏差值

/* 配置串口调试 */   
    DebugInit();
    PRINT( "Start @ChipID=%02X\n", R8_CHIP_ID );

/* 温度采样并输出, 包含数据粗校准 */
    PRINT( "\n1.Temperature sampling...\n");
    ADC_InterTSSampInit();
    RoughCalib_Value = ADC_DataCalib_Rough();  // 用于计算ADC内部偏差,记录到变量 RoughCalib_Value中,注意这个变量需要定义为有符号变量
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("\n");

/* 单通道采样:选择adc通道9做采样,对应 PA0引脚, 带数据校准功能 */   
    PRINT( "\n2.Single channel sampling...\n");
    GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_Floating);
    ADC_ExtSingleChSampInit( SampleFreq_3_2, ADC_PGA_0 );

/*
    注意:数据校准包括 粗调和细调:
    ADC_DataCalib_Rough() 是粗调函数,调用前需保证PA5引脚配置浮空输入模式,外部没有电压信号,在ADC初始化之后调用,一般调用一次,除非更改了ADC模式(增益改变)
    ADC_DataCalib_Fine() 是细调函数,对于粗调过的数据进行拟合算法运算,得到更精确数据
*/   
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);
    RoughCalib_Value = ADC_DataCalib_Rough();  // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中  
    PRINT("=%d \n", RoughCalib_Value);   

    ADC_ChannelCfg( 9 );        
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;      // 连续采样20次
        ADC_DataCalib_Fine( &abcBuff[i], ADC_PGA_0 );
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("\n");

/* 差分通道采样:选择adc通道0做采样,对应 PA4(AIN0)、PA12(AIN2) */  
    PRINT( "\n3.Diff channel sampling...\n");   
    GPIOA_ModeCfg(GPIO_Pin_4|GPIO_Pin_12, GPIO_ModeIN_Floating);   
    ADC_ExtDiffChSampInit( SampleFreq_3_2, ADC_PGA_0 );
    ADC_ChannelCfg( 0 );
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver();      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("\n");

/* TouchKey采样:选择adc通道 2 做采样,对应 PA12 */
    PRINT( "\n4.TouchKey sampling...\n");   
    GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeIN_Floating);
    TouchKey_ChSampInit();
    ADC_ChannelCfg( 2 );   

    for(i=0; i<20; i++)
    {
        abcBuff[i] = TouchKey_ExcutSingleConver(0x20);      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("\n");


/* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
    PRINT( "\n5.Single channel sampling in interrupt mode...\n");   
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);
    ADC_ExtSingleChSampInit( SampleFreq_3_2, ADC_PGA_0 );
    ADC_ChannelCfg( 1 );
    NVIC_EnableIRQ(ADC_IRQn);
    adclen = 0;

    ADC_StartUp();  
    while(adclen < 20);
    NVIC_DisableIRQ(ADC_IRQn);
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("\n");

    while(1);   
}


void ADC_IRQHandler(void)                        //adc中断服务程序
{
    if(ADC_GetITStatus())
    {
        abcBuff[adclen] = ADC_ReadConverValue();
        ADC_StartUp(); // 作用清除中断标志并开启新一轮采样
        adclen ++;
    }
}





这段代码是一个基于CH57x微控制器的ADC采样示例,包括温度检测、单通道检测、差分通道检测、TouchKey检测和中断方式采样。以下是逐行注释:

```c
#include "CH57x_common.h" // 引入CH57x通用头文件

UINT16 abcBuff[40]; // 定义一个数组用于存储ADC采样结果
volatile UINT8 adclen; // 定义一个变量用于记录ADC采样次数

void DebugInit(void)               
{
    GPIOA_SetBits(GPIO_Pin_9); // 设置GPIOA的第9位为高电平
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); // 配置GPIOA的第8位为上拉输入模式
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // 配置GPIOA的第9位为推挽输出模式,电流为5mA
    UART1_DefInit(); // 初始化UART1
}

int main()
{
    UINT8 i;
    signed short RoughCalib_Value=0;                // ADC粗调偏差值

    /* 配置串口调试 */   
    DebugInit();
    PRINT( "Start @ChipID=%02X
", R8_CHIP_ID );

    /* 温度采样并输出, 包含数据粗校准 */
    PRINT( "
1.Temperature sampling...
");
    ADC_InterTSSampInit(); // 初始化内部温度传感器采样
    RoughCalib_Value = ADC_DataCalib_Rough();  // 计算ADC内部偏差,记录到变量 RoughCalib_Value中,注意这个变量需要定义为有符号变量
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("
");

    /* 单通道采样:选择adc通道9做采样,对应 PA0引脚, 带数据校准功能 */   
    PRINT( "
2.Single channel sampling...
");
    GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_Floating); // 配置GPIOA的第0位为浮空输入模式
    ADC_ExtSingleChSampInit( SampleFreq_3_2, ADC_PGA_0 ); // 初始化外部单通道采样,采样频率为3.2MHz,增益为1倍

    /*
    注意:数据校准包括 粗调和细调:
    ADC_DataCalib_Rough() 是粗调函数,调用前需保证PA5引脚配置浮空输入模式,外部没有电压信号,在ADC初始化之后调用,一般调用一次,除非更改了ADC模式(增益改变)
    ADC_DataCalib_Fine() 是细调函数,对于粗调过的数据进行拟合算法运算,得到更精确数据
    */   
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating); // 配置GPIOA的第5位为浮空输入模式
    RoughCalib_Value = ADC_DataCalib_Rough();  // 计算ADC内部偏差,记录到全局变量 RoughCalib_Value中  
    PRINT("=%d
", RoughCalib_Value);   

    ADC_ChannelCfg( 9 );        // 配置ADC通道为9
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value;      // 连续采样20次
        ADC_DataCalib_Fine( &abcBuff[i], ADC_PGA_0 ); // 对采样结果进行细调校准
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("
");

    /* 差分通道采样:选择adc通道0做采样,对应 PA4(AIN0)、PA12(AIN2) */  
    PRINT( "
3.Diff channel sampling...
");   
    GPIOA_ModeCfg(GPIO_Pin_4|GPIO_Pin_12, GPIO_ModeIN_Floating); // 配置GPIOA的第4位和第12位为浮空输入模式   
    ADC_ExtDiffChSampInit( SampleFreq_3_2, ADC_PGA_0 ); // 初始化外部差分通道采样,采样频率为3.2MHz,增益为1倍
    ADC_ChannelCfg( 0 ); // 配置ADC通道为0
    for(i=0; i<20; i++)
    {
        abcBuff[i] = ADC_ExcutSingleConver();      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("
");

    /* TouchKey采样:选择adc通道 2 做采样,对应 PA12 */
    PRINT( "
4.TouchKey sampling...
");   
    GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeIN_Floating); // 配置GPIOA的第12位为浮空输入模式
    TouchKey_ChSampInit(); // 初始化触摸按键通道采样
    ADC_ChannelCfg( 2 ); // 配置ADC通道为2

    for(i=0; i<20; i++)
    {
        abcBuff[i] = TouchKey_ExcutSingleConver(0x20);      // 连续采样20次
    }
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("
");


    /* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
    PRINT( "
5.Single channel sampling in interrupt mode...
");   
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating); // 配置GPIOA的第5位为浮空输入模式
    ADC_ExtSingleChSampInit( SampleFreq_3_2, ADC_PGA_0 ); // 初始化外部单通道采样,采样频率为3.2MHz,增益为1倍
    ADC_ChannelCfg( 1 ); // 配置ADC通道为1
    NVIC_EnableIRQ(ADC_IRQn); // 使能ADC中断
    adclen = 0; // 初始化adclen为0

    ADC_StartUp();  // 启动ADC采样
    while(adclen < 20); // 等待adclen达到20
    NVIC_DisableIRQ(ADC_IRQn); // 禁用ADC中断
    for(i=0; i<20; i++)
    {
        PRINT("%d ", abcBuff[i]);
    }PRINT("
");

    while(1); // 无限循环
}

void ADC_IRQHandler(void)                        //adc中断服务程序
{
    if(ADC_GetITStatus()) // 如果ADC中断标志位被置位
    {
        abcBuff[adclen] = ADC_ReadConverValue(); // 读取ADC转换结果并存入abcBuff数组
        ADC_StartUp(); // 清除中断标志并开启新一轮采样
        adclen ++; // adclen自增1
    }
}
```

使用特权

评论回复
评论
dirtwillfly 2024-9-29 08:39 回复TA
感谢分享 

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

517

主题

1734

帖子

5

粉丝