int32_t adc_measure_pm2p5() { // uint16_t val = 0; if((ADC_SC2_REG(adc_ptr) & ADC_SC2_ADACT_MASK) == 0) { /* set once conversion mode */ ADC_SC3_REG(adc_ptr) = (ADC_SC3_REG(adc_ptr) & (~ADC_SC3_ADCO_MASK) | ADCO_SINGLE); /* set sw triger */ ADC_SC2_REG(adc_ptr) = (ADC_SC2_REG(adc_ptr) & (~ADC_SC2_ADTRG_MASK) | ADTRG_SW); ADC_SC1_REG(adc_ptr,0) = ADC_INPUT_CH; while(!(ADC_SC1_REG(adc_ptr,0) & ADC_SC1_COCO_MASK)){ //printf("adc calculating...\n"); //_time_delay(1); } val = (uint16_t) (ADC_R_REG(adc_ptr,0)); } else { printf("Conversion in progress...\n"); _time_delay(50); val = (uint16_t) (ADC_R_REG(adc_ptr,0)); } return val; }
void ADC_Config_Alt(ADC_MemMapPtr adcmap, tADC_ConfigPtr ADC_CfgPtr) { ADC_CFG1_REG(adcmap) = ADC_CfgPtr->CONFIG1; ADC_CFG2_REG(adcmap) = ADC_CfgPtr->CONFIG2; ADC_CV1_REG(adcmap) = ADC_CfgPtr->COMPARE1; ADC_CV2_REG(adcmap) = ADC_CfgPtr->COMPARE2; ADC_SC2_REG(adcmap) = ADC_CfgPtr->STATUS2; ADC_SC3_REG(adcmap) = ADC_CfgPtr->STATUS3; //ADC_PGA_REG(adcmap) = ADC_CfgPtr->PGA; pbd ADC_SC1_REG(adcmap,A)= ADC_CfgPtr->STATUS1A; ADC_SC1_REG(adcmap,B)= ADC_CfgPtr->STATUS1B; }
/****************************************************************************** Function Name : ADC0__Config (from Inga Harris' Nucleus ADC0_ Validation) Engineer : r54940 Date : 04/08/08 Parameters : Returns : NONE Notes : Configures ADC0_ ******************************************************************************/ void ADC_Config(ADC_MemMapPtr adcmap, uint8_t CONFIG1, uint8_t CONFIG2, uint16_t COMPARE1, uint16_t COMPARE2, uint8_t STATUS2, uint8_t STATUS3, uint8_t STATUS1A, uint8_t STATUS1B, uint32_t PGA ) { ADC_CFG1_REG(adcmap) = CONFIG1; ADC_CFG2_REG(adcmap) = CONFIG2; ADC_CV1_REG(adcmap) = COMPARE1; ADC_CV2_REG(adcmap) = COMPARE2; ADC_SC2_REG(adcmap) = STATUS2; ADC_SC3_REG(adcmap) = STATUS3; ADC_SC1_REG(adcmap,A) = STATUS1A; ADC_SC1_REG(adcmap,B) = STATUS1B; ADC_PGA_REG(adcmap) = PGA; }
/************************************************************************* * 野火嵌入式開發工作室 * * 函數名稱:ad_once * 功能說明:采集一次一路模擬量的AD值 * 參數說明:ADCn 模塊號( ADC0、 ADC1) * ADC_Channel 通道號 * ADC_nbit 精度( ADC_8bit,ADC_12bit, ADC_10bit, ADC_16bit ) * 函數返回:無符號結果值 * 修改時間:2012-2-10 * 備 注:參考蘇州大學的例程,B通道不能軟件觸發!!!! *************************************************************************/ u16 ad_once(ADCn adcn,ADC_Ch ch,ADC_nbit bit) //采集某路模擬量的AD值 { u16 result = 0; ASSERT( ((adcn == ADC0) && (ch>=AD8 && ch<=AD18)) || ((adcn == ADC1)&& (ch>=AD4a && ch<=AD17)) ) ; //使用斷言檢測ADCn_CHn是否正常 adc_start(adcn, ch, bit); //啟動ADC轉換 while (( ADC_SC1_REG(ADCx[adcn], 0 ) & ADC_SC1_COCO_MASK ) != ADC_SC1_COCO_MASK); result = ADC_R_REG(ADCx[adcn],0); ADC_SC1_REG(ADCx[adcn],0) &= ~ADC_SC1_COCO_MASK; return result; }
uint8 ADC_Cal (ADC_MemMapPtr adcmap) { /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ unsigned short cal_var; /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ ADC_SC2_REG(adcmap) &= ~ADC_SC2_ADTRG_MASK; // Enable Software Conversion Trigger for Calibration Process - ADC0_SC2 = ADC0_SC2 | ADC_SC2_ADTRGW(0); ADC_SC3_REG(adcmap) &= (~ADC_SC3_ADCO_MASK &~ADC_SC3_AVGS_MASK); // set single conversion, clear avgs bitfield for next writing ADC_SC3_REG(adcmap) |= (ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(AVGS_32)); // Turn averaging ON and set at max value ( 32 ) ADC_SC3_REG(adcmap) |= ADC_SC3_CAL_MASK; // Start CAL while((ADC_SC1_REG(adcmap, A) & ADC_SC1_COCO_MASK) == COCO_NOT); // Wait calibration end if((ADC_SC3_REG(adcmap) & ADC_SC3_CALF_MASK) == CALF_FAIL) { return(1); // Check for Calibration fail error and return } // Calculate plus-side calibration cal_var = 0x00; cal_var = ADC_CLP0_REG(adcmap); cal_var += ADC_CLP1_REG(adcmap); cal_var += ADC_CLP2_REG(adcmap); cal_var += ADC_CLP3_REG(adcmap); cal_var += ADC_CLP4_REG(adcmap); cal_var += ADC_CLPS_REG(adcmap); cal_var = cal_var / 2; cal_var |= 0x8000; // Set MSB ADC_PG_REG(adcmap) = ADC_PG_PG(cal_var); // Calculate minus-side calibration cal_var = 0x00; cal_var = ADC_CLM0_REG(adcmap); cal_var += ADC_CLM1_REG(adcmap); cal_var += ADC_CLM2_REG(adcmap); cal_var += ADC_CLM3_REG(adcmap); cal_var += ADC_CLM4_REG(adcmap); cal_var += ADC_CLMS_REG(adcmap); cal_var = cal_var / 2; cal_var |= 0x8000; // Set MSB ADC_MG_REG(adcmap) = ADC_MG_MG(cal_var); ADC_SC3_REG(adcmap) &= ~ADC_SC3_CAL_MASK; /* Clear CAL bit */ return(0); }
void Io_Adc_Autoscan(void) { Io_Adc_Data -> current_cnv_channel = 0; Io_Int_DisableInterrupts(); /*Read the configuration from the configuration structure of the current channel*/ ADC_CFG2_REG(ADC0) = ADC_CFG2_DEFAULT | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_config2; ADC_CFG1_REG(ADC0) = ADC_CFG1_DEFAULT | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_config1; /*If software trigger is selected, conversion begins after SC1A is written */ ADC_SC1_REG(ADC0,S1A) = IO_ADC_SC1_INTERRUPT_ENABLE_MASK | IO_ADC_SC1_SE_CONVERSION | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_ID; Io_Adc_Data->conversion_ongoing = 1; /* Re-enable interrupts */ Io_Int_EnableInterrupts(); }
void main(void) { adc_init(); dma_init(); enter_thread_mode(); sema_wait(&adc_start_sema); struct dma_ctx *ctx; ctx = dma_setup(DMAMUX_ADC0, &ADC_R_REG(ADC0, 0), dstbuf, 2, sizeof(dstbuf)/2, DMA_SRC_STICKY | DMA_DOUBLEBUF | DMA_LOOP, dma_done, NULL); adc_sample_prepare(ADC_MODE_CONTINUOUS); bf_set_reg(ADC_SC2_REG(ADC0), ADC_SC2_DMAEN, 1); ADC_SC1_REG(ADC0, 0) = ADC_SC1_ADCH(0) | ADC_SC1_DIFF_MASK; wait(main); }
void Io_Adc_Isr(void) { uint16 result; Io_Adc_Data->conversion_ongoing = 0; Io_Int_DisableInterrupts(); /* Store the value of the last conversion */ result = ADC_R_REG(ADC0,S1A); /* Conversion value is written in the specific adc_channel_value */ Io_Adc_Data->adc_ch_data[Io_Adc_Data->current_cnv_channel].adc_channel_value = result; Io_Adc_Data->adc_ch_data[Io_Adc_Data->current_cnv_channel].valid = VALID; /* Increment the channel */ Io_Adc_Data->current_cnv_channel++; /* Check if current channel is not the last one */ if (Io_Adc_Data->current_cnv_channel<Io_Adc_ConfigPtr->adc_number_of_channels) { /*Read the configuration from the configuration structure of the current channel*/ ADC_CFG2_REG(ADC0) = ADC_CFG2_DEFAULT | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_config2; ADC_CFG1_REG(ADC0) = ADC_CFG1_DEFAULT | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_config1; /* Restart the conversion for next channel */ ADC_SC1_REG(ADC0,S1A) = IO_ADC_SC1_INTERRUPT_ENABLE_MASK | IO_ADC_SC1_SE_CONVERSION | Io_Adc_ConfigPtr->adc_config_channel[Io_Adc_Data->current_cnv_channel].adc_channel_ID;; /* Conversion ongoing is set */ Io_Adc_Data->conversion_ongoing = 1; } /* Re-enable interrupts */ Io_Int_EnableInterrupts(); }
inline void adc_start() { // to start the ADC conversion ADC_SC1_REG(ADC0_BASE_PTR, A)= AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(18); }
int adc_init() { adc_pixelIndex = 0; // disable ADC irq - not ready yet disable_irq(ADC_IRQ_NUM); // turn on clock to ADC0 SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK); // to setup SW trigger on FTM2 SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(10); // to calibrate the ADC module unsigned short cal_var; cal_var = 0x0000; // add the plus-side calibration results cal_var += ADC_CLP0_REG(ADC0_BASE_PTR); cal_var += ADC_CLP1_REG(ADC0_BASE_PTR); cal_var += ADC_CLP2_REG(ADC0_BASE_PTR); cal_var += ADC_CLP3_REG(ADC0_BASE_PTR); cal_var += ADC_CLP4_REG(ADC0_BASE_PTR); cal_var += ADC_CLPS_REG(ADC0_BASE_PTR); cal_var /= 2; cal_var |= 0x8000; // store value in plus-side gain calibration register (PG) ADC_PG_REG(ADC0_BASE_PTR) = ADC_PG_PG(cal_var); cal_var = 0x0000; // add the minus-side calibration results cal_var += ADC_CLM0_REG(ADC0_BASE_PTR); cal_var += ADC_CLM1_REG(ADC0_BASE_PTR); cal_var += ADC_CLM2_REG(ADC0_BASE_PTR); cal_var += ADC_CLM3_REG(ADC0_BASE_PTR); cal_var += ADC_CLM4_REG(ADC0_BASE_PTR); cal_var += ADC_CLMS_REG(ADC0_BASE_PTR); cal_var /= 2; cal_var |= 0x8000; // store value in minus-side gain calibration register (MG) ADC_MG_REG(ADC0_BASE_PTR) = ADC_MG_MG(cal_var); ADC_SC3_REG(ADC0_BASE_PTR) &= ~ADC_SC3_CAL_MASK; // to set the configuration register 1 (CFG1) to select the mode of // operation, clock source, clock divide, and configuration for low // power or long sample time ADC_CFG1_REG(ADC0_BASE_PTR) = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_1) | ADLSMP_SHORT | ADC_CFG1_MODE(MODE_8) | ADC_CFG1_ADICLK(ADICLK_BUS); // to set the configuration register 2 (CFG2) to select the special // high-speed configuration for very high speed conversions and // select the long sample time duration during long sample mode ADC_CFG2_REG(ADC0_BASE_PTR) = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_2); // to configure the status and control register 2 (SC2) ADC_SC2_REG(ADC0_BASE_PTR) = ADTRG_SW | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_DISABLED | ADC_SC2_REFSEL(REFSEL_EXT); // to configure the status and control register 3 (SC3) // enable hw averaging, 16 samples taken ADC_SC3_REG(ADC0_BASE_PTR) = CAL_OFF | ADCO_SINGLE | AVGE_ENABLED | ADC_SC3_AVGS(AVGS_16); // to configure the status and control register 1 (SC1) // enable the interrupt, single-ended conversion, on AD18 ADC_SC1_REG(ADC0_BASE_PTR, A)= AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(18); // to configure the PGA register ADC_PGA_REG(ADC0_BASE_PTR) = PGAEN_DISABLED | PGACHP_NOCHOP | PGALP_NORMAL | ADC_PGA_PGAG(PGAG_64); // enable ADC irq enable_irq(ADC_IRQ_NUM); return ADC_RET_SUCCESS; }
//============================================================================ //函数名称:hw_ad_once //函数返回:16位无符号的AD值 //参数说明:MoudelNumber:模块号 // Channel:通道号 // accuracy:精度 //功能概要:采集一次一路模拟量的AD值 //============================================================================ uint16 hw_adc_once(int MoudelNumber,int Channel,uint8 accuracy)//采集某路模拟量的AD值 { uint16 result = 0; uint8 ADCCfg1Mode = 0; ADC_MemMapPtr ADCMoudel;//保存ADC模块地址指针 switch(accuracy) { case 8: ADCCfg1Mode = 0x00; break; case 12: ADCCfg1Mode = 0x01; break; case 10: ADCCfg1Mode = 0x02; break; case 16: ADCCfg1Mode = 0x03; break; default: ADCCfg1Mode = 0x00; } if(MoudelNumber==0)//选择ADC模块0 { ADCMoudel = ADC0_BASE_PTR; } else //选择ADC模块1 { ADCMoudel = ADC1_BASE_PTR; } //配置正常电源模式,总线时钟,总线时钟4分频,长采样时间使能,设置精度 ADC_CFG1_REG(ADCMoudel) = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_4) | ADLSMP_LONG | ADC_CFG1_MODE(ADCCfg1Mode) | ADC_CFG1_ADICLK(ADICLK_BUS); //配置禁止异步时钟使能输出,ADxxat通道选择,高速配置,长采样时间 ADC_CFG2_REG(ADCMoudel) = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_20) ; //设置通道号 ADC_SC1_REG(ADCMoudel,A) = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(Channel); //等待转换完成 while (( ADC_SC1_REG(ADCMoudel,A) & ADC_SC1_COCO_MASK ) != ADC_SC1_COCO_MASK) { } //读取转化结果 result = ADC_R_REG(ADCMoudel,A); //清ADC转换完成标志 ADC_SC1_REG(ADCMoudel,A) &= ~ADC_SC1_COCO_MASK; return result; }