FM33LC046N评测+ADC采集报警
原帖地址:http://bbs.eeworld.com.cn/thread-1159028-1-1.html
一、ADC概述 FM33LC0XX 带有 1Msps 12bit SAR-ADC,可实现温度、电池电压或其他直流信号的测量功能。 主要特点为: 1、工作电压 1.8~5.5V
2、输入信号幅度 0~VDDA
3、最高采样率 1Msps(FADC=16Mhz)
4、16 个单端输入通道,包含温度传感器、内部基准电压、运放输出 x2、 12 个外部通道
5、8 个外部快速通道, 8 个低速通道
6、可配置的采样保持时间
7、支持单次转换和连续转换
8、支持 DMA
9、支持过采样硬件平均,最高 16bit 输出(256 次平均) 二、结构框图
三、输入通道
四、功能描述之采样值与实际电压的转换
ADC一般使用电源电压作为基准电压,在电源电压发生变化时,特定输入信号电平对应的转换值也会发送变化,为了能够得到准确的绝对电压,文档中接收的解决方案如下: 芯片出厂时在Vdd=3V的情况下,测量VREFINT的电压并保存在Flash中 1、以上条件下,使用ADC转换VREFINT输出,得到转换值VREFINT_CAL并保存在芯片中; 2、芯片实际应用中,由于不知道当前VDDA电压,ADC先测量VREFINT得到转换值VREFINT_DATA;通过以下公式可以得到当前实际的VDDA;
假设ADC对某个输入通道的采样值为ADC_DATA,通过以下公式可以得到当前某个输入通道的实际电压(12bit 输出)
采用这个方式,不需要知道每颗芯片VREFINT的实际电压值,仅需计算当前VREFINT采样值和出厂测试值的比例;
VREF1p2 采样的软件配置方法 1、软件使用 ADC 采样 VREF1p2 时,需要按照以下步骤:
2、置位 VREF_EN 寄存器,使能 VREF1p2 模块
3、置位 BUFFERCTRL.VREFBUFFER_EN,使能 VREF 输出 BUFFER
4、等待 VREF 建立,通过查询 VREF_RDY 寄存器,或通过 VREF_IF 中断
5、使能 ADC 的 REFCH 通道
6、使能 ADC 开始转换 五、软件实现步骤 1、ADC初始化 - void MF_ADC_Init(void)
- {
- FL_GPIO_InitTypeDef GPIO_InitStruct;
- FL_ADC_InitTypeDef defaultInitStruct;
- GPIO_InitStruct.pin = FL_GPIO_PIN_9; //PC9 ADC_IN0
- GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG;
- GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.pull = DISABLE;
- GPIO_InitStruct.remapPin = DISABLE;
- FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
- defaultInitStruct.conversionMode = FL_ADC_CONV_MODE_SINGLE;//联系转换模式 ,单次转换
- defaultInitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO;//单次转换半自动模式, 自动模式
- defaultInitStruct.waitMode = ENABLE; //等待模式控制, 等待模式
- defaultInitStruct.overrunMode = ENABLE; //覆盖上次数据
- defaultInitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_BACKWARD;//反向扫描ADC_IN11-->ADC_IN0
- defaultInitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_NONE;//禁止触发信号使能和极性选择
- defaultInitStruct.triggerSource = FL_ADC_TRGI_PA8; //硬件触发源 pA8
- defaultInitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_4_ADCCLK; //快速通道采样时间控制 4
- defaultInitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_192_ADCCLK;//慢速通道采样时间控制192
- defaultInitStruct.oversamplingMode = ENABLE;//过采样使能
- defaultInitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_16X;//过采样率控制 16x
- defaultInitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_4B;//过采样移位配置
- FL_ADC_Init(ADC,&defaultInitStruct );
- }
- void MF_ADC_Common_Init(void)
- {
- /*IO CONFIG*/
- FL_ADC_CommonInitTypeDef CommonInitStruct;
- CommonInitStruct.clockSource = FL_RCC_ADC_CLK_SOURCE_RCHF;
- CommonInitStruct.clockPrescaler = FL_RCC_ADC_PSC_DIV8;
- FL_ADC_CommonInit(&CommonInitStruct );
- FL_ADC_EnableIT_EndOfConversion(ADC );
- }
- void MF_NVIC_Init(void)
- {
- InterruptConfigStruct.preemptPriority = 1; //ADC中断优先级
- NVIC_Init(&InterruptConfigStruct,ADC_IRQn );
- }
复制代码2、ADC转换函数 - #define ADC_VREF (*((uint16_t *)(0x1FFFFB08))) // 30℃ vref1.22采样值
- static uint32_t GetVREF1P2Sample_IT(void)
- {
- uint16_t ADCRdresult;
- uint8_t i=0;
- FL_RCC_SetADCPrescaler(FL_RCC_ADC_PSC_DIV8);
- FL_VREF_EnableVREFBuffer(VREF);//使能VREF BUFFER
- FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);//通道选择VREF
-
- FL_ADC_ClearFlag_EndOfConversion(ADC);//清标志
- FL_ADC_Enable(ADC); // 启动ADC
- FL_ADC_EnableSWConversion(ADC); // 开始转换
- // 等待转换完成
- while (ADCComplete == 0)
- {
- if(i>=5)
- {
- break;
- }
- i++;
- DelayMs(1);
- }
- ADCComplete = 0;
- FL_ADC_ClearFlag_EndOfConversion(ADC);//清标志
- ADCRdresult =FL_ADC_ReadConversionData(ADC);//获取采样值
- FL_ADC_Disable(ADC); // 关闭ADC
- FL_ADC_DisableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);//通道关闭VREF
- FL_VREF_DisableVREFBuffer(VREF);//关闭VREF BUFFER
- // 转换结果
- return ADCRdresult;
- }
- static uint32_t GetSingleChannelSample_IT(uint32_t channel)
- {
- uint16_t ADCRdresult;
- uint8_t i=0;
- FL_RCC_SetADCPrescaler(FL_RCC_ADC_PSC_DIV1);
- FL_ADC_EnableSequencerChannel(ADC, channel);//通道选择
- FL_ADC_ClearFlag_EndOfConversion(ADC);//清标志
- FL_ADC_Enable(ADC); // 启动ADC
- FL_ADC_EnableSWConversion(ADC); // 开始转换
- // 等待转换完成
- while (ADCComplete == 0)
- {
- if(i>=5)
- {
- break;
- }
- i++;
- DelayMs(1);
- }
- ADCComplete = 0;
- FL_ADC_ClearFlag_EndOfConversion(ADC);//清标志
- ADCRdresult =FL_ADC_ReadConversionData(ADC);//获取采样值
- FL_ADC_Disable(ADC); // 关闭ADC
- FL_ADC_DisableSequencerChannel(ADC, channel);//通道
- // 转换结果
- return ADCRdresult;
- }
- uint32_t GetSingleChannelVoltage_IT(uint32_t channel)
- {
- uint32_t Get122VSample,GetChannelVoltage;
- uint64_t GetVSample;
-
- Get122VSample = GetVREF1P2Sample_IT();
- GetVSample =GetSingleChannelSample_IT(channel);
- GetChannelVoltage = (GetVSample *3000*(ADC_VREF))/(Get122VSample*4095);
- // 转换结果
- return GetChannelVoltage;
- }
复制代码3、数据采集报警处理 - GetVoltage = GetSingleChannelVoltage_IT(FL_ADC_EXTERNAL_CH0 );//获取AD值转换结果
- //事件处理
- if(uc_secondflag==1)//定时器1s中断
- {
- uc_secondflag=0;
- if(GetVoltage>0xA00)
- {
- printf("警告:AD值大于0xA00=2560 当前AD值 = %x\n",GetVoltage);
- FL_GPIO_ResetOutputPin(GPIOC,FL_GPIO_PIN_0);//点亮 LED0
- }
- else
- {
- printf("PC9 ADC =%x\n",GetVoltage);
- FL_GPIO_SetOutputPin(GPIOC,FL_GPIO_PIN_0);//熄灭 LED0
- }
- }
复制代码
|