ADC模块示例程序_沁恒CH585EVT
-
CH585/CH584提供了12位模数转换器,支持差分和单端输入,支持14路外部电压采样信号通道,3路内部信号:内部的温度检测通道、内部的电池电压检测通道、内部的 NFC 能量检测通道
-
MounRiver Studio使用PRINT时默认不支持打印浮点数,如果要打印浮点数,需要如图配置
![aa936b8bfba7e3fcf4fd6bf18203cc73]()
-
内部温度采样
PRINT("\n1.Temperature sampling...\n");
ADC_InterTSSampInit();//内置温度传感器采样初始化
ADC_ExcutSingleConver();//时间足够时建议再次转换并丢弃首次ADC数据
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次
}
for(i = 0; i < 20; i++)
{
uint32_t C25 = 0;
C25 = (*((PUINT32)ROM_CFG_TMP_25C));//25°C温度传感器校准值
PRINT("%d %d %d \n", adc_to_temperature_celsius(adcBuff[i]),adcBuff[i],C25);
}
- 单通道采样
/* 单通道采样:选择adc通道0做采样,对应 PA4引脚, 带数据校准功能 */
PRINT("\n2.Single channel sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
// 采样率最高8M
ADC_ExtSingleChSampInit(SampleFreq_8_or_4, ADC_PGA_1_4);
RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
PRINT("RoughCalib_Value =%d \n", RoughCalib_Value);
ADC_ChannelCfg(0);
ADC_ExcutSingleConver();//时间足够时建议再次转换并丢弃首次ADC数据
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value; // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象
float vol = (adcBuff[i]/PGA_DIV_12_ - 3.0f) * VREF;
PRINT("voltage is %.2f mv\n", vol);
}
- ADC_ExtSingleChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga):
- ADC_SampClkTypeDef:采样频率,SampleFreq_8_or_4,4M或8M与时钟源有关,HSI为4M,HSE为8M
ADC_SignalPGATypeDef:PGA增益
![{E3297C15-672E-42E5-8BE2-A1BDC4E8777B}]()
- ADC_SampClkTypeDef:采样频率,SampleFreq_8_or_4,4M或8M与时钟源有关,HSI为4M,HSE为8M
- DMA采样
/* DMA单通道采样:选择adc通道0做采样,对应 PA4引脚 */
PRINT("\n3.Single channel DMA sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_8_or_4, ADC_PGA_1_4);//ADC单通道采样,8M,PGA 1/4倍
ADC_ChannelCfg(0);//chan 0/PA4
ADC_ExcutSingleConver();//时间足够时建议再次转换并丢弃首次ADC数据
ADC_AutoConverCycle(192); // 采样周期为 (256-192)*16个系统时钟
ADC_DMACfg(ENABLE, (uint32_t)&adcBuff[0], (uint32_t)&adcBuff[40], ADC_Mode_Single);//enable DMA, 单次模式(传输完40次后停止)
PFIC_EnableIRQ(ADC_IRQn);
ADC_StartAutoDMA();//启动ADC自动DMA采样(开始连续采样,DMA自动搬运)
while(!DMA_end);
DMA_end = 0;
ADC_DMACfg(DISABLE, 0, 0, 0);//disable DMA
for(i = 0; i < 40; i++)
{
PRINT("%d \n", adcBuff[i]);
float vol = (adcBuff[i]/PGA_DIV_12_ - 3.0f) * VREF;
PRINT("voltage is %.2f mv\n", vol);
}
__INTERRUPT
__HIGH_CODE
void ADC_IRQHandler(void) //adc中断服务程序
{
#if(!ADC_SCAN_MODE_EXAM)
if(ADC_GetDMAStatus())//DMA trans finish
{
ADC_StopAutoDMA();
R32_ADC_DMA_BEG = ((uint32_t)adcBuff) & 0x1ffff;//重置DMA地址
ADC_ClearDMAFlag();
DMA_end = 1;
}
if(ADC_GetITStatus())
{
ADC_ClearITFlag();
}
}
/* 差分通道采样:选择adc通道0做采样,对应 PA4(AIN0)、PA12(AIN2) */
PRINT("\n4.Diff channel sampling...\n");
GPIOA_ModeCfg(GPIO_Pin_4 | GPIO_Pin_12, GPIO_ModeIN_Floating);
ADC_ExtDiffChSampInit(SampleFreq_8_or_4, ADC_PGA_1_4);//8M
ADC_ChannelCfg(0);
ADC_ExcutSingleConver();//时间足够时建议再次转换并丢弃首次ADC数据
for(i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次
}
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]);
float vol = (adcBuff[i]/PGA_DIV_12_ - 4.0f) * VREF;//计算与普通ADC不同
PRINT("voltage is %.2f mv\n", vol);
}

/* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
/* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
PRINT("\n6.Single channel sampling in interrupt mode...\n");
GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);
ADC_ExtSingleChSampInit(SampleFreq_8_or_4, ADC_PGA_1_4);
ADC_ChannelCfg(1);
ADC_ExcutSingleConver();//时间足够时建议再次转换并丢弃首次ADC数据
adclen = 0;
ADC_ClearITFlag();
PFIC_EnableIRQ(ADC_IRQn);
ADC_StartUp();
while(1)
{
if(temp_flag == 1)
{
for(i = 0; i < 20; i++)
{
PRINT("%d \n", adcBuff[i]);
float vol = (adcBuff[i]/PGA_DIV_12_ - 3.0f) * VREF;
PRINT("voltage is %.2f mv\n", vol);
}
ADC_StartUp();
temp_flag = 0;
adclen = 0;
}
};
__INTERRUPT
__HIGH_CODE
void ADC_IRQHandler(void) //adc中断服务程序
{
if(ADC_GetITStatus())
{
ADC_ClearITFlag();
if(adclen < 20)
{
adcBuff[adclen] = ADC_ReadConverValue();
ADC_StartUp(); // 作用清除中断标志并开启新一轮采样
}
adclen++;
}
temp_flag = 1;
}
- 扫描模式
/*********************************************************************
* @fn ADC_Scan
*
* @brief ADC扫描
*
* @return none
*/
void ADC_Scan( void )
{
ADC_RegDeinit(); // 复位ADC寄存器
Touch_RegDeinit(); // 复位Touch寄存器
memset( adcBuff, 0, 200 );//adc buff size is 200
memset( adcBuff1, 0, 200 );
/* 配置全部 22 个 AIN 引脚为浮空输入 */
for ( uint8_t ch = CH_EXTIN_0; ch <= CH_EXTIN_21; ch++ )
{
ADC_AinGpioCfg( ch );//配置浮空,关闭数字输入模式
}
ADC_ExtSingleChSampInit( SAMPLE_CLK_96_OR_124_8, ADC_PGA_1_2);//配置采样频率和增益,注意增益的配置
RoughCalib_Value = ADC_DataCalib_Rough();//校准值
PRINT( "RoughCalib_Value =%d \n", RoughCalib_Value );
ADC_ChannelCfg( scan_ch[ 0 ] );//
R32_ADC_SCAN_CFG4 = 0;
/* 打包通道 1~8 到 SCAN_CFG1(每通道 4 位) */
uint32_t cfg1 = 0;
for ( int i = 0; i < 8; i++ )
{
cfg1 |= ( (uint32_t)( scan_ch[ i + 1 ] ) << ( i * 4 ) );
if ( scan_ch[ i + 1 ] > CH_EXTIN_15 )
R32_ADC_SCAN_CFG4 |= (uint32_t)1 << ( i + 1 - 1 );
}
R32_ADC_SCAN_CFG1 = cfg1;
/* 打包通道 9~13 到 SCAN_CFG2,加上扫描控制位 */
uint32_t cfg2 = 0;
for ( int i = 0; i < 5; i++ )
{
cfg2 |= ( (uint32_t)( scan_ch[ i + 9 ] ) << ( i * 4 ) );
if ( scan_ch[ i + 9 ] > CH_EXTIN_15 )
R32_ADC_SCAN_CFG4 |= (uint32_t)1 << ( i + 9 );
}
R32_ADC_SCAN_CFG2 = cfg2;
/* 打包通道 14~21 到 SCAN_CFG3,加上扫描控制位 */
uint32_t cfg3 = 0;
for ( int i = 0; i < 8; i++ )
{
cfg3 |= ( (uint32_t)( scan_ch[ i + 14 ] ) << ( i * 4 ) );
if ( scan_ch[ i + 14 ] > CH_EXTIN_15 )
R32_ADC_SCAN_CFG4 |= (uint32_t)1 << ( i + 14 );
}
R32_ADC_SCAN_CFG3 = cfg3;
R32_ADC_SCAN_CFG2 |= ( ( ( ADC_SCAN_CH_NUM - 1 ) & 0x0F ) << 24 ); /* scan_num = 22-1=21 ADC_SCAN_CH_NUM - 1*/
R32_ADC_SCAN_CFG2 |= RB_ADC_SCAN_NUM_H; /* SCAN_NUM 高位(支持 >16 通道) */
R32_ADC_SCAN_CFG2 |= RB_ADC_SCAN_SEL; /* 选择 ADC(非 TKEY),扫描由 SCAN_NUM 非零自动激活 */
R32_ADC_SCAN_CFG2 &= ~RB_ADC_IE_SCAN_END; /*扫描结束中断使能*/
R32_ADC_SCAN_CFG2 &= ~RB_EHCH_TIM;//每个通道采样次数复位
R32_ADC_SCAN_CFG2 |= 1 << 20; /* 扫描过程中每个通道采样2次,dma缓冲区需要配置2*scan_num */
R32_ADC_SCAN_CFG2 |= RB_ADC_SCAN_EN; /* 扫描使能 */
R32_ADC_DMA_BEG = (uint32_t)&adcBuff[ 0 ] & 0x3ffff;//DMA 起始缓冲区地址
R32_ADC_DMA_END = (uint32_t)&adcBuff[ ADC_SCAN_CH_NUM * 2 ] & 0x3ffff;
R8_ADC_CTRL_DMA |= RB_ADC_DMA_ENABLE |RB_SCAN_AUTO_TYPE;//连续触发扫描
PFIC_EnableIRQ( ADC_IRQn );
SCAN_end = 0;//end flag
ADC_StartUp();//执行单次转换
while ( !SCAN_end ); /* 等待 DMA 完成 */
SCAN_end = 0;
PFIC_DisableIRQ( ADC_IRQn );
ADC_DMACfg( DISABLE, 0, 0, 0 );
/* 关闭扫描模式 */
R32_ADC_SCAN_CFG2 = 0;
for ( int i = 0; i < ADC_SCAN_CH_NUM; i++ )
{
PRINT( "SCAN_CH%d: %d %d \n", i, adcBuff[ i * 2 ] + RoughCalib_Value, adcBuff[ i * 2 + 1 ] + RoughCalib_Value );
}
}



浙公网安备 33010602011771号