学习KEA之ADC之四:FIFO

作者:曾Jerry 或 大橙员, 250359225@qq.com

学习KEA之ADC之一:基本介绍
学习KEA之ADC之二:查询方式
学习KEA之ADC之三:中断方式
学习KEA之ADC之四:FIFO
学习KEA之ADC之五:自动比较功能

FIFO的意义

要是不使用FIFO功能的话,在多路采集时,ADC会频繁进入中断,这样对MCU来说是个负担,所以需要开启FIFO功能,这样在所有通道采集完后才进入一次中断,提高了效率。

FIFO有关寄存器

当ADC_SC4[AFDEP]不为0时,便使能了FIFO。 ADC_SC4[AFDEP]也决定了FIFO的深度,其中这个深度最大是8。
在这里插入图片描述

FIFO的模拟输入通道 和 结果通道 是由ADC_SC1[ADCH] 决定的:
在这里插入图片描述
假如FIFO的深度为3,在初始化ADC_SC1[ADCH]时,依次设置了AD7、AD12和AD14,则最终FIFO转换的结果也是对应了AD7、AD12和AD14。有个要注意的是:若ADC_SC4[ASCANE]=1,则开启了扫描方式,只对第一次设置的通道AD7采样,也就是最终的FIFO转换的3个结果都是AD7的。

当FIFO所有通道转换完成的时候,相应的结果将会存取在FIFO的结果通道,不过最终还是通过ADC_R寄存器来获得。同时,ADC_SC1[COCO]还会置1;如果开启了中断(ADC_SC1[AIEN]=1),还会发生ADC中断。

笔者在调试时,发现寄存器设置的顺序会有影响,建议的顺序如下:

  1. SIM_SCGC:使能ADC模块
  2. ADC_APCTL1:把GPIO设置AD管脚
  3. ADC_SC4:设置FIFO扫描方式、FIFO深度
  4. ADC_SC3:设置ADC时钟和转换位数
  5. ADC_SC2:设置软件或硬件启动、参考源
  6. ADC_SC1:设置单次或连续采样、中断,最后才设置ADC_SC1_ADCH

FIFO的转换时序

FIFO可以由软件或硬件触发,这个由ADC_SC2[ADTRG]决定。

FIFO还有单次采样(Single) 和 连续(Continuous)采样模式,这个由ADC_SC2[ADCO]决定:

  • Single: ADC启动后,采样一次就结束了
  • Continuous: ADC启动后,会一直地采样
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

FIFO中断例程

/**
 *  FIFO, Continuous, AD7, AD12, AD14, interrupt
 *
 * */
void ADC_Init(void)
{
	SIM_SCGC |= SIM_SCGC_ADC_MASK;   /* Enable bus clock in ADC*/

	ADC_APCTL1 |= ADC_APCTL1_ADPC(1<<7 | 1<<12 | 1<<14); /* Channel selection */

	ADC_SC4 |= ADC_SC4_AFDEP(0b010); /* 3-level FIFO is enabled */

	ADC_SC3 |= ADC_SC3_ADICLK(0b00); /* Bus clock selected, 20 MHz */
	ADC_SC3 |= ADC_SC3_MODE(0b10);   /* 12-bit mode operation */

	ADC_SC2 |= 0x00;                 /* Software Conversion trigger, disable compare function*/
	ADC_SC2 |= ADC_SC2_REFSEL(0b01); /* Select VDD and VSS as voltage reference source*/

	ADC_SC1 |= ADC_SC1_ADCO_MASK;    /* Continuous mode operation */
	ADC_SC1 |= ADC_SC1_AIEN_MASK;    /* ADC Interrupt Enabled */


	ADC_SetChannel(7);  /* Enable ADC by setting ADCH bits as low*/
	ADC_SetChannel(12);
	ADC_SetChannel(14);
}


/*****************************************************************************//*!
   *
   * @brief set ADC channel.
   *
   * @param[in]  u8Channel adc channel to conversion.
   *
   * @return none
   *
   * @ Pass/ Fail criteria: none
   *****************************************************************************/
void ADC_SetChannel(uint8_t u8Channel)
{
    uint32_t u32temp;

    u32temp = ADC_SC1;
    u32temp &= ~ADC_SC1_ADCH_MASK;

    ADC_SC1 = u32temp | ADC_SC1_ADCH(u8Channel);
}

/***********************************************************************************************
*
* @brief    ADC0_IRQHandler - Interrupt for ADC channels, Calls user function.
* @param    none
* @return   none
* @note     在中断中,不需要查询ADC_SC2_FEMPTY_MASK的
************************************************************************************************/
void ADC0_IRQHandler(void)
{
	u16ADC_ConversionBuff[0] = ADC_R;
	u16ADC_ConversionBuff[1] = ADC_R;
	u16ADC_ConversionBuff[2] = ADC_R;

	u8ADC_ConversionFlag = 1;
}

FIFO查询例程

/**
 *  FIFO, Continuous, AD7, AD12, AD14, no interrupt
 *
 * */
void ADC_Init(void)
{
	SIM_SCGC |= SIM_SCGC_ADC_MASK;   /* Enable bus clock in ADC */

	ADC_APCTL1 |= ADC_APCTL1_ADPC(1<<7 | 1<<12 | 1<<14); /* Channel selection */

	ADC_SC4 &= ~ADC_SC4_ASCANE_MASK; /* FIFO scan mode disabled */
	ADC_SC4 |= ADC_SC4_AFDEP(0b010); /* 3-level FIFO is enabled */

	ADC_SC3 |= ADC_SC3_ADICLK(0b00); /* Bus clock selected, 20 MHz */
	ADC_SC3 |= ADC_SC3_MODE(0b10);   /* 12-bit mode operation */

	ADC_SC2 |= 0x00;                 /* Software Conversion trigger, disable compare function*/
	ADC_SC2 |= ADC_SC2_REFSEL(0b01); /* Select VDD and VSS as voltage reference source*/

	ADC_SC1 |= ADC_SC1_ADCO_MASK;    /* Continuous mode operation */
	ADC_SC1 &= ~ADC_SC1_AIEN_MASK;    /* Disable ADC Interrupt */

	ADC_SetChannel(7);  /* Enable ADC by setting ADCH bits as low*/
	ADC_SetChannel(12);
	ADC_SetChannel(14);
}

void ADC_SetChannel(uint8_t u8Channel)
{
    uint32_t u32temp;

    u32temp = ADC_SC1;
    u32temp &= ~ADC_SC1_ADCH_MASK;

    ADC_SC1 = u32temp | ADC_SC1_ADCH(u8Channel);
}

/***********************************************************************************************
*
* @brief    ADC_FIFO_Poll
* @param    none
* @return   none
* @note     The ADC_SC1[COCO] bit will be set only when all conversions indicated by the analog input channel FIFO complete
*           whatever software or hardware trigger is set
************************************************************************************************/
void ADC_FIFO_Poll(uint16_t *buff)
{
	while(!(ADC_SC1 & ADC_SC1_COCO_MASK));

	buff[0] = ADC_R;
	buff[1] = ADC_R;
	buff[2] = ADC_R;
}

小结

如果采样次数很多,要求速度比较快的,尽量选择FIFO。

附录

完整代码:
KEAZN64_ADC5_FIFO_POLL.zip
KEAZN64_ADC5_FIFO_Interrupt.zip

OVER~~

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值