文章
博客 网店

 STM8L ADC转换示例程序


STM8L051 ADC模式
1.单次转换模式
此模式下只能转换单个通道,如果选择了多个通道那最高序号通道被转换,
此模式下DMAOFF位需要设置(关闭),转换完成后产生中断,转换结果可从ADC_DR寄存器读取。
2.单次转换扫描模式
此模式指单次转换模式的基础上选择DMAOFF位设置0(即dma打开),此模式下一次触发转换操作将逐次被转换选取的所有通道一遍后转换停止。
转换结果存储在dma指定的RAM区域。
3.连续转换模式
此模式下必须使用dma使转换结果存储到DMA指定RAM缓冲区,当所有被选取的通道转换一次后产生一次中断,并不需要重新触发转换自动指行下一轮的转换操作。

注:DMA转换结果存储顺序为选取的通道号从小到大的顺序

以下为单次转换扫描模式示例:

#define DMA_BUF_SIZE 6  //单次转换通道个数
uint16_t g_ArrayValue[DMA_BUF_SIZE];
uint32_t g_ArraySum[DMA_BUF_SIZE];
#define ONCE_CONV_TIME 8
uint8_t g_ConvTime=0;

//adc设置
void drv_adc_config(void)
{
  uint16_t addr;
  
  CLK->PCKENR2 |= CLK_PCKENR2_ADC1;//ADC1时钟允许
  
  ADC1->CR1=0; //12位,单次转换模式
  ADC1->CR2=(1<<7)|(0X03);//adc时钟分频2  低速通道采样周期24
  ADC1->CR3=(3<<5);//高速通道采样周期为24
  
  ADC1->CR1 |= ADC_CR1_ADON;//打开adc
  ADC1->TRIGR[0] |= (uint8_t)(ADC_TRIGR1_VREFINTON);//使能内部参考电压
  
  //通道选择
  ADC1->SQR[0]=(1<<4);//内部参考电压
  ADC1->SQR[1]=(1<<0)|(1<<1);//CH16,CH17
  ADC1->SQR[2]=(1<<7)|(1<<6)|(1<<5);//CH15,CH14,CH13
  ADC1->SQR[3]=0;
  
  //DMA设置
  CLK->PCKENR2 |= CLK_PCKENR2_DMA1;//DMA1时钟允许
  SYSCFG->RMPCR1&=~(0X03);//ADC1选dma通道0(默认)
  
  //连续工作,MEM INC MODE
  DMA1_Channel0->CCR=DMA_CCR_ARM|DMA_CCR_IDM;

  DMA1_Channel0->CSPR =DMA_CSPR_16BM;//向mem传送16数据

  //dma缓冲区大小
  DMA1_Channel0->CNBTR = DMA_BUF_SIZE;

  //设置读取地址
  addr=(uint16_t)&(ADC1->DRH);
  DMA1_Channel0->CPARH = (uint8_t)(addr>> 8);
  DMA1_Channel0->CPARL = (uint8_t)addr;

  //设置写入地?
  addr=(uint16_t)&(g_ArrayValue[0]);
  DMA1_Channel0->CM0ARH = (uint8_t)(addr >>8);
  DMA1_Channel0->CM0ARL = (uint8_t)addr;
  
  DMA1_Channel0->CCR|=DMA_CCR_CE;//DMA使能
  DMA1_Channel0->CCR |=DMA_CCR_TCIE;//中断使能
  DMA1->GCSR |= DMA_GCSR_GE;//DMA1使能
  ADC1->SQR[0] &= ~ADC_SQR1_DMAOFF;
}

INTERRUPT void DMA1_CHANNEL0_1_IRQHandler(void)
{
  uint8_t i;
  
  for(i=0;i<DMA_BUF_SIZE;i++)
    g_ArraySum[i]+=g_ArrayValue[i];
  g_ConvTime++;
  
  DMA1_Channel0->CSPR &= ~ DMA_CSPR_TCIF;
  
  if(g_ConvTime<ONCE_CONV_TIME)
    ADC1->CR1 |= ADC_CR1_START;
  else
    frm_set_event(EVENT_ADC_ID);//转换完成
}

void drv_adc_start(void)
{
  uint8_t i;
  
  g_ConvTime=0;
  for(i=0;i<DMA_BUF_SIZE;i++)
    g_ArraySum[i]=0;
    
  ADC1->CR1 |= ADC_CR1_START;
}

uint16_t drv_adc_read(uint8_t ch)
{
  if(ch >= DMA_BUF_SIZE)
    return 0;
  
  return (uint16_t)(g_ArraySum[ch]/ONCE_CONV_TIME);
}

芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved