[热门应用] KF8L22xx ADC例程

[复制链接]
 楼主| jerow 发表于 2019-8-30 16:41 | 显示全部楼层 |阅读模式
  1. /*******************************************************************************
  2.   * [url=home.php?mod=space&uid=288409]@file[/url]    KungFu8_ADC.c
  3.   * [url=home.php?mod=space&uid=187600]@author[/url]  ChipON Application Team
  4.   * [url=home.php?mod=space&uid=895143]@version[/url] V0.0.1
  5.   * @date
  6.   * @brief
  7.   * *
  8.   ******************************************************************************
  9.   */
  10. #include        "KungFu8_ADC.h"


  11. /***********************************************************************************
  12. * 函数名             :ADC_Configuration
  13. * 函数功能        :ADC模块配置
  14. * 入口参数        :无
  15. * 返回         :无
  16. * ADC模块配置
  17. **********************************************************************************/
  18. void ADC_Configuration(void)
  19. {
  20.         // 对应AD引脚的模式配置,配置为模拟  输入。 需注意:系列芯片设计IO默认为模拟输入脚功能
  21. //        ANS0= 0x02 | 0x04 | 0x01 | 0x40 ;         //  0x02 | 0x04 | 0x01 | 0x40 VS AN11 AN12 AN13 AN17 VS P01 P02 P00 P17
  22. //        TR0|=(0x02 | 0x04 | 0x01 | 0x40 );        //  0x02 | 0x04 | 0x01 | 0x40 VS AN11 AN12 AN13 AN17 VS P01 P02 P00 P17

  23.         ANS1=0x00;         // NONE
  24.         ANS2=0x00;  // NONE
  25.         ANS3=0x00;  // NONE
  26.         ANS4=0x00;  // NONE

  27.         ANS5= 0x02 | 0x04 | 0x01 ;                         //  0x02 | 0x04 | 0x01 | 0x40 VS AN8 AN18 AN19 VS P52 P50 P51
  28.         TR5|=(0x02 | 0x04 | 0x01 );                        //  0x02 | 0x04 | 0x01 | 0x40 VS AN8 AN18 AN19 VS P52 P50 P51

  29.         ANS6=0x20 ;                                                 //  0x20  VS AN9 VS P65
  30.         TR6|=(0x20);                                                //  0x20  VS AN9 VS P65

  31.         ANS7=0x00;

  32.         ADCCTL0=0x80 | 0x00 | 0x01 ;                                        //  bit7 1右对齐 0左对齐,bit6 是否T2中断触发AD采样,bit0 使能AD模块

  33.         ADCCTL1=0x80 | ADC_FAD_SCLKDIV4 | ADC_VREF_VDD ;  // bit7  是否失调校准使能

  34.         // 如果使用内部参考电压,需要配置FVR,参见FVR例程 VREFCTL的配置

  35.         ADCCTL2=AN8;   // 特别需要说明的时,选通通道后不能立即启动转换,因为需要时间采样,典型时间5us。
  36. }
  37. /***********************************************************************************
  38. * 函数名             :ADC_GetConvertData
  39. * 函数功能        :AD 结果获取
  40. * 入口参数        :无    仅用户结果的获取,建立在通道并转换完成
  41. * 返回         :
  42. * 说明          : 常规使用右对齐的12位,左对齐仅做8位应用时使用,即高位为8位的转换结果。
  43. **********************************************************************************/
  44. unsigned int ADC_GetData(void)
  45. {
  46.         s_uint16  Adbuf;
  47.         Adbuf.byte1 = ADCDATA0H;
  48.         Adbuf.byte0 =ADCDATA0L;
  49.         return Adbuf.value;
  50. }
  51. /***********************************************************************************
  52. * 函数名             :ADC_GetConvertData
  53. * 函数功能        :AD 结果获取
  54. * 入口参数        :通道 如AN8  ,滤波次数 1,16 【接近长度存贮,满量程的16倍滤波加和不溢出】
  55. * 返回         : 16bit的采样结果,如果存在满量程,滤波次数最多16,最大半量程下滤波参数可以到的32
  56. * 说明          : 滤波参数需要匹配加和结果不溢出。如果固定 4次 8次 16次 32次 可另建立函数,固定次数代码编写,效率会存在提升。
  57. *                         常规使用右对齐的12位,左对齐仅做8位应用时使用,即高位为8位的转换结果。
  58. **********************************************************************************/
  59. unsigned int ADC_GetConvertData(unsigned char chsel,unsigned char fitercount)
  60. {
  61.         s_uint16  Adbuf;
  62.         s_uint16  Adsum;
  63.         unsigned char i;
  64.         ADCCTL2=chsel;
  65.         Delay_Wait_CLK_Sample(5);                // 切换通道到启动转换需要保留采样时间

  66.         Adsum.value=0;
  67.         for(i=0;i<fitercount;i++)
  68.         {
  69.                 START=1;                                                // 启动转换
  70.                 while(START);                                        // 转换完成硬件清零,如果使用ADIF,需要做ADIF的清零
  71.         //        while(!ADIF);ADIF=0;


  72. //                Adbuf.value=ADC_GetConvertData();         // 自身的传递占用代码比直接获取效率差,这里直接获取
  73. //                Adsum.value+=Adbuf.value;                        // 值处理

  74.                 Adbuf.byte1 = ADCDATA0H;
  75.                 Adbuf.byte0 =ADCDATA0L;

  76.                 Adsum.value+=Adbuf.value;

  77.         }

  78.         return Adsum.value/fitercount;
  79. }
  80. /***********************************************************************************
  81. //
  82. ******************************************************************************
  83. */


 楼主| jerow 发表于 2019-8-30 16:41 | 显示全部楼层
主函数的配置
  1. /****************************************************************************************
  2. *
  3. * 文件名: main.c
  4. * 项目名:
  5. * 版 本: v1.0
  6. * 日 期:
  7. * 作 者:
  8. *
  9. ****************************************************************************************/
  10. #include "includes.h"

  11. s_uint16  AdVaule;
  12. s_uint16  AdResult;
  13. /***********************************************************************************
  14. * 函数名             :
  15. * 函数功能        :有限周期数的延迟
  16. * 入口参数        :1~255的有效范围
  17. * 返回         :无
  18. ***********************************************************************************
  19. */
  20. void Delay_Wait_CLK_Sample(unsigned char x)
  21. {
  22. #pragma save
  23. #pragma disable_warning 59
  24. #pragma disable_warning 85   // 59 85 屏蔽参数未使用警告,函数未返回警告,作用于嵌汇编函数功能实现

  25.         __asm
  26.          ;// 参数使用R0传递
  27.          ;//MOV R0,#0x05 固定样例
  28.          DECJZ R0
  29.          JMP $-1
  30.         __endasm;

  31. #pragma restore
  32. }
  33. //***********************************************************************************
  34. //主函数
  35. //***********************************************************************************
  36. void main()
  37. {
  38.         OSCCTL=0x70; // 系统时钟

  39.         // FVR 配置  ,使样例可切换到内部电压为参考源,具体查看FVR例程
  40.         VREFCTL= 0x80  | 0x30 ;        // 电压选择 2/3/4V  0x40 0x80 0xC0 | 校准使能  与校准时钟  0x30 0x00
  41.         VREFEN=1;                                // 使能

  42.         ADC_Configuration();
  43.         while(1)
  44.         {// 注:调试时第二次循环指向上一行代码,此为正常现象,是因为嵌汇编的XX指令在KF工具中没有行号,被属于需上一行代码的尾指令。
  45.                 _CWDT_();  // 周期性清理,如果代码执行时间超过看门狗的周期,应该在代码中插入清狗指令。

  46.                 START=1;                                                // 启动转换
  47.                 while(START);                                        // 转换完成硬件清零,如果使用ADIF,需要做ADIF的清零
  48.                 AdVaule.value=ADC_GetData();

  49.                 AdResult.value=ADC_GetConvertData(AN8,8);

  50.                 Delay_Wait_CLK_Sample(200);
  51.         }
  52. }
  53. //中断函数0:0X04入口地址
  54. void int_fun0() __interrupt (0)
  55. {

  56. }


  57. //中断函数1:0x14入口地址
  58. void int_fun1() __interrupt (1)
  59. {

  60. }
 楼主| jerow 发表于 2019-8-30 16:55 | 显示全部楼层
KF8L22xx  ADC模数转换模块介绍
ADC12 模数转换模块可将模拟输入信号转换为 12 位二进制值。KF8L22Z20XX 拥有 9 路 IO 模拟输入通道和 4 路内部通道。转换器通过逐次逼近法将模拟输入信号转换为二进制值,并将转换结果存放到 12 位寄存器中。可通过软件方式选择内部参考电压 VREFOUT、VDD 或施加在 VREFIN 引脚上的电压作为转换使用的参考电压。
869485d68e497ecf4b.png
 楼主| jerow 发表于 2019-8-30 17:15 | 显示全部楼层
KF8L22xx  ADC模数转换模块有关的寄存器
894775d68e914ce433.png
 楼主| jerow 发表于 2019-8-30 17:16 | 显示全部楼层
KF8L22xx  ADC模数转换模块通道的选择
KF8L22Z20XX 中的 ADC12 转换模块的输入可以选择 9 路来自外部的模拟信号和 4 路内部通道。通过寄存器 ADCCTL2(如寄存器 7.3 所示)进行通道的选择。当选择外部的模拟信号作为 ADC12 转换的输入时,需要将对应的引脚配置为模拟输入口;当选择内部信号作为 ADC12 转换的输出时,无需占用任何 I/O 引脚;ADC12 可选的内部信号输入及配置方式如下(用户如需使用温度传感器,通过 TEMPSNR 寄存器的 TSEN 位置 1来使能该功能):
 通道 14=OPOUT,运算放大器的输出
 通道 15=TSOUT,温度传感器的输出
 通道 16=VREFOUT,内部参考电压
 通道 24=CTOUT,电容触摸(H 模式)的输出
 楼主| jerow 发表于 2019-8-30 17:18 | 显示全部楼层
KF8L22xx  ADC模数转换模块参考电压的选择
KF8L22Z20XX 中 ADC12 模块的参考电压可以选择 3 种分别为: 电源电压(VDD)、外部参考电压(VREFIN)和内部参考电压 VREFOUT。通过寄存器 ADCCTL1(如寄存器 7.2 所示) 的 VCFG<1:0>设置参考电压。
616935d68e9c76eabf.png
 楼主| jerow 发表于 2019-8-30 17:19 | 显示全部楼层
KF8L22xx  ADC模数转换模块转换时钟的选择
完成一次 ADC12 转换所需要的时间为 13Tad。如寄存器 7.2 所示,可通过软件方式设置 ADCS位(ADCCTL1<6:4>)选择转换时钟源,共有 7种时钟选项。Tad和Fad分别为 ADC12转换时钟周期和频率。
70525d68ea02b2694.png
 楼主| jerow 发表于 2019-8-30 17:19 | 显示全部楼层
KF8L22xx  ADC模数转换模块的输出格式
KF8L22Z20XX 中 ADC12 转换的结果为 12 位二进制数,ADC12 转换结果寄存器为两个 8 位的寄存器。用户可以通过 ADLR(ADCCTL0.7)设置转换结果输出格式,ADLR 置 1 输出为右对齐,ADLR 清 0 输出为左对齐。如图 7.2 所示。
804335d68ea3dc9717.png
 楼主| jerow 发表于 2019-8-30 17:21 | 显示全部楼层
KF8L22xx  ADC模数转换模块AD转换的启动和完成
先将 ADEN 位置 1,然后将 START 位(ADCCR0.1)置 1 即可启动 AD 转换。当转换结束时,ADC12 模块将:
1.将 START 位清 0
2.将 ADIF 位置 1
3.如果使能 AD 转换中断,则响应中断
可以采取在程序中将 START 位清 0 的方法中止当前的转换操作。在 AD 转换采样全部结束之前,ADCDATA0H:ADCDATA0L 寄存器中的内容将不会被更新,而是仍旧保留前一次的转换结果。AD 转换被中止后,需至少等待 2Tad 的延时时间后才能开始下一次数据采集。
 楼主| jerow 发表于 2019-8-30 17:22 | 显示全部楼层
KF8L22xx  ADC模数转换模块 工作在休眠模式
ADC12 转换器模块可以在休眠模式下工作。这需要把 ADC12 的时钟源设定为 ADC12专用的内部振荡器。当选择了专用内部时钟源后,ADC12 需等待一个指令周期后才能启动转换操作,转换结束后,START 位将被清 0,且转换结果将被载入 ADCDATA0H: ADCDATA0L 寄存器。如果 ADC12 中断被使能,器件将从休眠状态唤醒。如果 ADC12 中断被禁止,ADC12 模块在转换完成后被关闭。
如果 ADC12 时钟源不是 ADC12 专用的内部振荡器,执行 IDLE 指令将导致当前转换操作中止,并使 ADC12 模块关闭。
 楼主| jerow 发表于 2019-8-30 17:22 | 显示全部楼层
KF8L22xx  ADC模数转换模块使用转换器的设置
启动 ADC12 转换器时的设置: 1. 选择 ADC12 采样输入通道,设置 AD 转换结果对齐方式;
2. 将对应的 ADC12 采样输入通道设置为模拟输入模式;
3. 如果需要使能 ADC12 的失调校准,将 ADCCTL1 寄存器的 ADCALEN 位置 1; 4. 选择参考电压和 ADC12 采样时钟频率,打开 AD 转换;
5. 如果采用中断方式,使能 ADC12 转换中断;
6. 等待 ADC12 所需的采集时间;
7. 启动 AD 转换;
8. 查询 ADC12 是否转换完成(START=0)或进入 AD 中断;
9. 读取 AD 转换结果。
 楼主| jerow 发表于 2019-8-30 17:23 | 显示全部楼层
复位对KF8L22xx  ADC模数转换模块的影响
器件复位将强制所有寄存器进入复位状态。因此,ADC12 模块将被关闭,任何进行中的转换操作被中止。ADCDATA0H:ADCDATA0L 寄存器中的值不变。
merry_zsp 发表于 2019-8-31 12:03 | 显示全部楼层
支持下,谢谢分享!
zlmin 发表于 2019-10-3 09:06 来自手机 | 显示全部楼层
谢谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

520

帖子

3

粉丝
快速回复 返回顶部 返回列表