zoukankan      html  css  js  c++  java
  • STM8S——Analog/digital converter (ADC)

    1、ADC1 and ADC2 are 10-bit successive approximation Anolog to Digital Converters.

      所谓successive approximation,是逐次逼近的意思;

      逐次逼近型ADC解释详见——博客http://blog.sina.com.cn/s/blog_a438e5290102wakc.html

    2、ADC分为ADC1和ADC2,ADC1的功能相比起ADC2更为强大,我们使用的是ADC1;

    3、ADC有多种模式:(1)Single mode(2)Continuous mode(3)Buffered continuous mode(4)Single scan mode(5)Continuous scan mode

    我们选用Continuous mode来实现,主要实现步骤:

    (1)模式选择:set CONT bit in the ADC_CR1 register (bit1),表示选择Continuous型;

           clear DBUF bit in the ADC_CR3 register (bit7),表示no-buffering型的Continuous。

    (2)转换配置:set EOCIE bit in the ADC_CSR register (bit 5),表示EOC中断使能;

        在转换完成之后,硬件会自动将EOC(End of Conversion)flag置1,表示一次转换完成,进入下一次转换时需要在代码中将其清0;

        而EOCIE位是EOC 中断的使能位,当EOCIE为1时,允许EOC中断。

    (3)开始转换:set ADON bit in the ADC_CR1 register (bit0)。

    (4)转换完后的数据存放在ADC_DR register中,只需读取寄存器中的内容即可获得答案。

    (5)停止转换:reset ADON bit,更直接的是将ADC_CR1 register赋值为0x00。

    说明:

    (*)DBUF=1(Buffered continuous mode)时,转换后的数据存放在ADC_DBxR(x=or 0...7 or 0...9)中;

      而DBUF=0时,转换后的数据存放在ADC_DR中; 

    (*)由于ADC1和ADC2都是10-bit,一个8bit的寄存器装不下,所以在数据存放寄存器ADC_DR中,分为ADC_DRH和ADC_DRL;

      我们采用右对齐的方式(ADC1_ALIGN_RIGHT)存储转换后的数据;所以10bit中的低8bit(D7...D0)存放在ADC_DRL中;剩下的2bit(D9、D8)存放在ADC_DRH的低位中,ADC_DRH的其余位全置0。同样的ADC1_ALIGN_LEFT为左对齐方式。

      说了这么多废话,其实只需要我们选择ADC1_ALIGN_RIGHT即可,其他操作都已经内部封装好了。

    4、(软件部分)根据以上步骤开始编程:

    (1)首先申请一个PIN脚给ADC,我们申请E6脚(第24脚)

      GPIO_Init(GPIOE, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);;

    (2)初始化ADC的各类寄存器,清零;

    (3)配置ADC1:

    //1.Continuous conversion mode
    //2.specifies 9 channels to convert
    //3.Prescaler selection fADC1 = fcpu/2
    //4.Conversion from Internal TIM1 TRGO event
    //5.ADC1_ExtTrigger DISABLE
    //6.Data alignment right
    //7.Schmitt trigger disable on AIN9
    //8.ADC1_SchmittTriggerState DISABLE

      ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_9, ADC1_PRESSEL_FCPU_D2,
        ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL9,
        DISABLE);

    (4)允许EOC中断,即将EOCIE置1,即ADC_CSR赋值为(uint8_t)0x20或(uint16_t)0x020;

    (5)打开通用中断:enableInterrupts();

    (6)开始转换:将ADON置1,即ADC_CR1赋值为(uint8_t)0x01;

     1 void main(void)
     2 { 
     3   /*  Init GPIO for ADC1 */
     4   GPIO_Init(GPIOE, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT); //pin E6 ,24
     5   
     6   /* De-Init ADC peripheral*/
     7   ADC1_DeInit(); //reset registers
     8 
     9   /* Init ADC1 peripheral */
    10   ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_9, ADC1_PRESSEL_FCPU_D2, 
    11             ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL9,
    12             DISABLE);
    13 
    14   /* Enable EOC interrupt */
    15   ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
    16 
    17   /* Enable general interrupts */  
    18   enableInterrupts();
    19   
    20   /*Start Conversion */
    21   ADC1_StartConversion();
    22 }
    主函数

    (7)中断处理,当EOC被硬件置1并产生中断,触发INTERRUPT_HANDLER(ADC1_IRQHandler, 22)

      中断便是传输结束,所以这时我们应该读取数据并且重置EOC准备下一次转换;

      读取数据:ADC1_GetConversionValue(void),内部函数,根据设置的左(右)对齐方式,返回一个16位的转换后的数据;

      清除EOC:将EOC重新写0;

    (8)到这里已经完成了所有的操作,由于我们选用的是Continuous mode,所以只要我们没有将ADON写回0,转换就不会停,一轮接一轮的循环下去;

      但为了便于我们观察,可以在每一轮之后将ADON写0(在中断中写),这样在主函数里设置一个断点,并查看16位的返回值就可以观察到结果。

     1 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
     2  {
     3    /* Get converted value */
     4    Conversion_Value = ADC1_GetConversionValue();
     5 
     6    /* Clear EOC */
     7    ADC1_ClearITPendingBit(ADC1_IT_EOC);
     8    
     9    /* Stop Continuous Conversion */
    10    ADC1->CR1 = 0x00;
    11  }
    中断函数

    5、硬件部分:

    (1)将STM8S105单片机的第24脚外接一个10K的电阻,再由电阻另一端接一根导线;由接地端再接出一根导线,将两条导线分别接入稳压电源器的正负极;

    (2)设置断点并运行程序,调节稳压电源器的电压(0-5V),可以发现不同的电压值会对应一个不同的16bit数;

    (3)平均每增加0.05V,示数会增加一个10。

    注意:24脚外一定要接一个电阻保护电路,否者在打开稳压电源器的瞬间,可能因为瞬间电流过大而击穿单片机。

    我是照着一个ADC2的例子修改实现本次实验的,ADC2有的函数ADC1都有,而写ADC1实现得更多,所以在将ADC2改成ADC1时,存在着很多陷阱(函数参数、中断类型等);

    但是真正弄明白我们需要拿ADC1实现什么, 又需要对ADC1做什么操作后,这些陷阱还是可以慢慢爬出来的;

    ADC1能实现的东西还有很多,比如Buffered continuous mode、analog watchd等,由于我们的实验没有用到,就先不做说明。

  • 相关阅读:
    程序员面试金典-面试题 16.15. 珠玑妙算
    程序员面试金典-面试题 16.14. 最佳直线
    程序员面试金典-面试题 16.13. 平分正方形
    程序员面试金典-面试题 16.11. 跳水板
    程序员面试金典-面试题 16.10. 生存人数
    程序员面试金典-面试题 16.08. 整数的英语表示
    程序员面试金典-面试题 16.07. 最大数值
    程序员面试金典-面试题 16.06. 最小差
    python学习笔记-47 UDP编程
    python学习笔记-46 TCP编程
  • 原文地址:https://www.cnblogs.com/Christal-R/p/7018035.html
Copyright © 2011-2022 走看看