1.前言
刚刚研究ADC的时候发现芯片里面还有应该mrt 16位的定时器没有搞,那回头补上吧。下午研究了一下ADC的使用,我也只是能用上,这里我只是抛砖引玉一下吧,有需要的还请各位自行深入探究,我这里讲解的是软件触发模式。
2.初始化
初始化程序如下
#define ADC_SAMPLE_CHANNEL_NUMBER 7
adc_result_info_t ADCResult;void init_adc(void)
{adc_config_t adcConfigStruct;adc_conv_seq_config_t adcConvSeqConfigStruct;/* Enables clock for IOCON.: enable */CLOCK_EnableClock(kCLOCK_Iocon);/* Enables clock for switch matrix.: enable */CLOCK_EnableClock(kCLOCK_Swm);const uint32_t IOCON_INDEX_PIO0_10_config = (/* No addition pin function */IOCON_PIO_MODE_INACT |/* Enable hysteresis */IOCON_PIO_HYS_EN |/* Input not invert */IOCON_PIO_INV_DI |/* Disables Open-drain function */IOCON_PIO_OD_DI);/* PIO0 PIN10 (coords: 11) is configured as ADC0, CH, 7. */IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_10, IOCON_INDEX_PIO0_10_config);/* ADC_CHN7 connect to P0_10 */SWM_SetFixedPinSelect(SWM0, kSWM_ADC_CHN7, true);/* Disable clock for switch matrix. */CLOCK_DisableClock(kCLOCK_Swm);/* Attach FRO clock to ADC0. */CLOCK_Select(kADC_Clk_From_Fro);CLOCK_SetClkDivider(kCLOCK_DivAdcClk, 1U);/* Power on ADC. */POWER_DisablePD(kPDRUNCFG_PD_ADC0);adcConfigStruct.clockDividerNumber = 1;adcConfigStruct.enableLowPowerMode = false;ADC_Init(ADC, &adcConfigStruct);adcConvSeqConfigStruct.channelMask =(1U << ADC_SAMPLE_CHANNEL_NUMBER); /* Includes channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER. */adcConvSeqConfigStruct.triggerMask = 0U;//选择硬件触发源adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityPositiveEdge;//上升还是下降沿触发adcConvSeqConfigStruct.enableSingleStep = false;//单次触发模式adcConvSeqConfigStruct.enableSyncBypass = true;//启用此功能允许硬件触发输入绕过同步触发器阶段,从而缩短触发输入信号和转换开始之间的时间。adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence;//设置中断模式ADC_SetConvSeqAConfig(ADC, &adcConvSeqConfigStruct);ADC_EnableConvSeqA(ADC, true); /* Enable the conversion sequence A. *//* Clear the result register. */ADC_DoSoftwareTriggerConvSeqA(ADC);while (!ADC_GetChannelConversionResult(ADC, ADC_SAMPLE_CHANNEL_NUMBER, &ADCResult)){}ADC_GetConvSeqAGlobalConversionResult(ADC, &ADCResult);
}
前面几行比较简单,先申请几个配置的结构体
然后是设置引脚,这里我们可以看到这里会多出几行,在模拟引脚我们都需要这样设置,就是配置管脚的速度,默认上下拉,保证是模拟模式,然后关联到相应通道
然后是设置时钟和分频系数,设置完毕后就开通电源
这一部分是设置ADC的分频和低功耗模式
这个结构体里,也只有这两个参数可以设置,在804这里比较鸡肋
这一块是重头戏,我来一个个介绍
第一句话是选择通道,这里我是通道7
第2~4句要连着一起用,常见的示波器都有外部触发功能,这里也可以设置,你可以让ADC的通道2作为外部触发源,你接上方波后对内部ADC进行触发,然后是设置方波极性,上升沿还是下降沿触发,最后一句是设置硬件触发模式,因为这里是软件触发不用硬件所以我直接跳过同步了。
然后是设置中断,因为是软件触发,我就跟着例程走了
配置完毕后就可以使能了,两句话要一起使用
然后是进行一次转换,官方给的说法是清除寄存器里的数据
3.软件触发
程序如下
void ReadADC(void)
{/* Get the input from terminal and trigger the converter by software. */ADC_DoSoftwareTriggerConvSeqA(ADC);/* Wait for the converter to be done. */while (!ADC_GetChannelConversionResult(ADC, ADC_SAMPLE_CHANNEL_NUMBER, &ADCResult)){}
}
这里主要介绍一下我们的通道是这个参数,如何改通道就要改这里,当然初始化部分也要改
我们的结果是放在这个结构体内
这个结构体原型如下
result就是我们的读到的数据,是最重要的。中间两是检测ADC的状态,我不怎么常用就没读了。chanelnumber是通道,比如我们这里是通道7,这个数字就是7了。overrunflag是可以检测ADC数据是否存在覆盖的情况,因为芯片内部没有DMA,所以搬运还是依靠CPU来搞,可以通过这个参数查看是否有丢失数据情况。
4.测试
我这里输入是0.8V直流信号
我在程序内部也有进行转换,上面985就是实际读取的值,下面是计算后的电压值,可以看到基本是准的。