打印
[STM32L1]

STM32L151C8的AD实验,线性为什么不好?

[复制链接]
1626|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ybs777|  楼主 | 2013-10-6 16:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
在ad实验时,AD在100mv内与万用表差距不大,当到600mv时,比万用表显示值大50mv左右。
  ADC->CCR|=ADC_CCR_ADCPRE_1;//这里配置ADC的HSI分频,通过swd调试看,内部并没有写成功?
void ADC_Init (void) {
  RCC->AHBENR  |= ( 1UL <<    1);         /* Enable GPIOB clock               */
  GPIOB->MODER |= ( 3UL << 2*13);         /* PB.12 is Analog mode             */

#ifndef __ADC_IRQ
  /* DMA1 Channel1 configuration ---------------------------------------------*/
  RCC->AHBENR  |= (1UL << 24);            /* enable DMA1 clock                */

  DMA1_Channel1->CMAR  = (uint32_t)&AD_last;    /* Set memory     address     */
  DMA1_Channel1->CPAR  = (uint32_t)&(ADC1->DR); /* Set peripheral address     */
  DMA1_Channel1->CNDTR = 1;               /* Transmit 1 data item             */
  DMA1_Channel1->CCR   = 0x00002522;      /* configure DMA channel            */
  NVIC_EnableIRQ(DMA1_Channel1_IRQn);     /* enable DMA1 Channel Interrupt    */
  DMA1_Channel1->CCR  |= (1UL << 0);      /* enable DMA channel 1             */
#endif

  /* Setup and initialize ADC converter                                       */
  RCC->CR      |= ( 1UL <<    0);         /* Enable Internal high-speed clock */
  RCC->APB2ENR |= ( 1UL <<  9);           /* enable periperal clock for ADC1  */
  ADC->CCR|=ADC_CCR_ADCPRE_1;//这里配置ADC的HSI分频,通过swd调试看,内部并没有写成功?
  ADC1->CR1     = ( 1UL <<  8);           /* Scan mode on, 12 Bit             */
  ADC1->CR2     =  0;

  ADC1->SQR1    =  0;                     /* Regular chn. Sequence length = 1 */
  ADC1->SQR2    =  0;                     /* Clear register                   */
  ADC1->SQR3    =  0;                     /* Clear register                   */
  ADC1->SQR4    =  0;                     /* Clear register                   */
  ADC1->SQR5    = (19UL <<  0);           /* 1. conversion = channel 18       */
  ADC1->SMPR1   =  0 ;                     /* Clear register                   */
  ADC1->SMPR2   =(7UL << 27);           /* Chn 18 sample time is 48 cyc     */

#ifndef __ADC_IRQ
  ADC1->CR2    |= ( 3UL <<  8);           /* DMA mode enable, cont. DMA req.  */
#else
  ADC1->CR1    |= ( 1UL <<  5);           /* enable for EOC Interrupt         */
  NVIC_EnableIRQ(ADC1_IRQn);              /* enable ADC Interrupt             */
#endif

  ADC1->CR2    |= ( 1UL <<  0);           /* ADC enable                       */
  }

/*----------------------------------------------------------------------------
  start AD Conversion
*----------------------------------------------------------------------------*/
void ADC_StartCnv (void) {

  if ((ADC1->SR & ((1 << 6) | (1 << 8))) == (1 << 6)) {
    ADC1->CR2|=  (1UL << 30);         /* Start A/D conversion             */
  }
}
/*----------------------------------------------------------------------------
  get converted AD value
*----------------------------------------------------------------------------*/
uint16_t ADC_GetCnv (void) {

  while (!(AD_done));                     /* Wait for Conversion end          */

        AD_done = 0;

  return(AD_last);
       

}

/*----------------------------------------------------------------------------
  A/D IRQ: Executed when A/D Conversion is done
*----------------------------------------------------------------------------*/
void ADC1_IRQHandler(void) {

  if (ADC1->SR & (1 << 1)) {              /* ADC1 EOC interrupt?              */
    AD_last = ADC1->DR;
    AD_done = 1;

    ADC1->SR &= ~(1 << 1);                /* clear EOC interrupt              */
  }

}


int main(void)
{
        u8 t;
        u16 ad_val,ad_val_;
        u16 ad_avg;
       
delay_init(24);
        delay_s(5);
uart_init(24,9600);       
       
ADC_Init();
        LED_Init();
        while(1)
        {
                delay_ms(1000);
                PAout(1)=~(PAout(1));
                for(t=0;t<16;t++)
                {
                                ADC_StartCnv();
                ad_val=ADC_GetCnv();
                                ADC_StartCnv();
                        ad_val_=ADC_GetCnv();
                if(ad_val>>8==ad_val_>>8)       
                        ad_avg+=ad_val;
                else t--;
                                delay_ms(1);
                }
                ad_avg/=16;
                printf("ADC = %04X Volt = %d mv\r\n", ad_avg, ad_avg*2948/4096);
}
}
file:///D:\My Documents\Tencent Files\18930478\Image\MT}()VLZHIOCJR7YK2_N}WQ.jpg

大虾给看看呗。呵呵
沙发
hkcj| | 2013-10-7 10:13 | 只看该作者
不是很了解   这一块不是很熟悉   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝