富士通微控制器 ( 上海 ) 有限公司应用笔记 MCU-AN-500005-Z-11 F²MC-8FX 家族 8 位微控制器 MB95200H/210H 系列 A/D 转换器 应用笔记
变更履历 变更履历 日期作者修改记录 2008-03-20 Benjamin Yang V1.0, 第 1 版 2008-07-15 Benjamin Yang V1.1, 修订版 本文档由 30 页构成 1. 本文档记载的产品信息及规格说明如有变动, 恕不预先通知 如需最新产品信息和 / 或规格说明, 联系富士通销售代表或富士通授权经销商 2. 基于本文档记载信息或示意图的使用引起的对著作权 工业产权或第三方的其他权利的侵害, 富士通不承担任何责任 3. 未经富士通明文批准, 不得对本文档的记载内容进行转让 拷贝 4. 本文档所介绍的产品并不旨在以下用途 : 需要极高可靠性的设备, 诸如航空航天装置 海底中继器 核控制系统或维系生命的医用设施 5. 本文档介绍的部分产品可能是 外汇及外贸管理法 规定的战略物资 ( 或专门技术 ), 出口该产品或其中部分元件前, 应根据该法获得正式批准 2008 富士通微电子 ( 上海 ) 有限公司版权所有 MCU-AN-500005-Z-11 Page 2
目录 目录 变更履历目录 1 概要 2 功能 变更履历... 2 目录... 3 概要... 5 功能... 6 2.1 主要功能... 6 2.2 框图... 7 2.3 寄存器... 8 2.3.1 8/10 位 A/D 转换器控制寄存器 1 (ADC1)... 8 2.3.2 8/10 位 A/D 转换器控制寄存器 2 (ADC2)... 9 2.3.3 8/10 位 A/D 转换器数据寄存器高位 / 低位 (ADDH ADDL)... 10 2.4 8/10 位 A/D 转换器的中断... 11 2.4.1 8/10 位 A/D 转换器的中断... 11 2.4.2 8/10 位 A/D 转换器中断的关联寄存器和向量表... 11 模拟输入和相关外部电路... 12 3 模拟输入和相关外部电路 3.1 电气规范... 12 3.2 模拟输入的外部电路... 13 采样时间的注意事项... 15 示例... 16 4 采样时间的注意事项 5 ADC 示例 5.1 A/D 转换器设定步骤... 16 5.1.1 初始化... 16 5.1.2 中断处理... 16 5.2 A/D 转换器的启动方法... 17 5.2.1 通过设定启动位启动 A/D 转换器... 17 5.2.2 通过 8/16 位多功能定时器 (TO00) 输出... 18 5.3 A/D 转换状态的判定方法... 19 5.3.1 通过转换标志位判定... 19 5.3.2 通过中断请求标志位判定... 20 6 使用 8/16 位 A/D 转换器时的注意事项 转换器时的注意事项... 22 6.1 编程设置的注意事项... 22 6.2 中断请求的注意事项... 22 AN-MCU-500005-Z-11 Page 3
目录 6.3 误差... 22 6.4 8/10 位 A/D 转换器模拟输入时序... 22 附加信息... 23 附录... 24 7 附加信息 8 附录 8.1 框图一览... 24 8.2 表格一览... 24 8.3 示例代码... 25 8.3.1 Project1... 25 8.3.2 Project2... 27 8.3.3 Project3... 29 MCU-AN-500005-Z-11 Page 4
1 概要 1 概要 本应用笔记介绍各个模式下如何使用 8/10 位 A/D 转换器以及模拟 / 数字转换器 (ADC) 的功能并举例说明 AN-MCU-500005-Z-11 Page 5
2 功能 2 功能 本章介绍 8/10 位 A/D 转换器的基本功能 2.1 主要功能 A/D 转换器将模拟输入引脚的模拟电压 ( 输入电压 ) 转换为 10 位数字值 可从多种模拟输入引脚中选择一种 可设定转换速度 ( 根据工作电压和频率进行选择 ) A/D 转换完成时, 发生中断 通过 ADC1 寄存器的 ADI 位检查转换状态 以下两种方法可激活 A/D 转换功能 a. 使用 ADC1 寄存器的 A/D 位激活 b. 使用 8/16 位多功能定时器输出 TO00 连续激活 MCU-AN-500005-Z-11 Page 6
2 功能 2.2 框图 图 2-1 是 ADC 的内部框图 图 2-1:ADC 的内部内部框图 通过模拟通道选择器将模拟输入信号 (AN00 ~ AN05) 传送到采样保持电路并最后传输到控制电路 模拟 数字的转换结果保存到 A/D 转换器数据寄存器 (ADDH ADDL) 一旦转换开始或触发, 则控制电路将先采样所选输入通道并保持采样保持电路中的电压电平稳定 AN-MCU-500005-Z-11 Page 7
2.3 寄存器 AD 转换器 V1.1 2 功能 关于寄存器的详细信息, 参考 MB95200H/210H 系列硬件手册的 第 17 章 2.3.1 8/10 位 A/D 转换器控制寄存器 1 (ADC1) 该寄存器用于使能 / 禁止 8/16 位 A/D 转换器功能, 选择模拟输入引脚, 检查 A/D 转换状态 图 2-2:8/10 位 A/D 转换器控制寄存器 1(ADC1) 注意模拟输入引脚号因产品系列而异 MB95200H 系列有模拟输入引脚 (AN00 ~ AN05) 的 6 路通道 但 MB95210H 系列仅有模拟输入引脚 (AN05 ~ AN04) 的 2 路通道 模拟输入引脚也可用作通用 I/O 口 MCU-AN-500005-Z-11 Page 8
2 功能 2.3.2 8/10 位 A/D 转换器控制寄存器 2 (ADC2) 该寄存器用于选择 8/10 位 A/D 转换器功能, 选择输入时钟, 处理中断, 检查 A/D 转换状态 图 2-3: 8/10 位 A/D 转换器控制寄存器 2 (ADC2) AN-MCU-500005-Z-11 Page 9
2 功能 2.3.3 8/10 位 A/D 转换器数据寄存器高位 / 低位 (ADDH ADDL) 8/16 位 A/D 转换器数据寄存器高位 / 低位 (ADDH ADDL) 指示 10 位 A/D 转换结果 10 位数据的高 2 位指示 ADDH 寄存器 ; 低 2 位指示 ADDL 寄存器 设定 ADC2:AD8=1 时, 可从 ADDL 寄存器中读取数据的高 8 位, 设定 ADC2:AD8=0 时, 该位选择 10 位精度 图 2-4: 8/10 位 A/D 转换器数据寄存器高位 / 低位 (ADDH ADDL) MCU-AN-500005-Z-11 Page 10
2 功能 2.4 8/10 位 A/D 转换器的中断 2.4.1 8/10 位 A/D 转换器的中断 A/D 转换完成后, 中断请求标志位 (ADC1:ADI) 置 1 若使能中断请求使能位 (ADC2:ADIE=1), 则中断请求发成并传送到中断控制器 通过中断服务程序清零 ADI 位以清除中断请求 无论 ADIE 位的值如何, 当 A/D 转换完成时,ADI 位置位 使能中断请求 (ADC2:ADIE= ) 状态下, 若中断请求标志位 (ADC1:ADI) 置 1, 则 CPU 无法从中断处理中返回 务必在中断服务程序内清零 ADI 位 2.4.2 8/10 位 A/D 转换器中断的关联寄存器和向量表 表 2-1:8/10 位 A/D 转换器中断的关联寄存器和向量表 关于所有外设资源的中断请求号和向量表, 详见 MB95200H/210H 系列硬件手册 " 附录 B 中断源一览表 " AN-MCU-500005-Z-11 Page 11
3 模拟输入和相关外部电路 3 模拟输入和相关外部电路 本章介绍电气规范和基本外部电路 3.1 电气规范 下表是 8FX 家族的主要电气规范 表 3-1: 电气规范和相关 A/D 转换器 MCU-AN-500005-Z-11 Page 12
3 模拟输入和相关外部电路 3.2 模拟输入的外部电路 信号 图 3-1:A/D 转换的推荐连接 为保护过电压的模拟引脚, 通常向输入引脚引接一个 钳位电阻器 电阻器的最小值可通过以下算出 : Rclamp = Uovervoltage / Iclamp 以上公式中,Iclamp 指 数据手册 中规定的最大钳位电流 很多应用中不使用较大的钳位电阻器 所以, 在输入引脚和 AVCC 引脚间, 连接带低漏电流功能的外部钳位二极管 某些情况下, 由于输入电压高于微控制器规定的最大额定电压, 因此传感器可能产生偏差 例如, 汽车电子应用中, 车载传感器直接使用车用电池 ( 电压是 12V/24V) 时可能产生偏差 电阻分压器 ( 包含 R1/R2) 通常用于跟踪传感器引脚的电压信号 ( 保证引脚值等于或小于 VCC)( 详见图 3-1) R1 和 R2 的比率应满足以下公式 : 影响 R1 R2 和 R clamp 值的其他因素有相应的功耗预算和输入信号噪声控制, 后者将会详细讨论 传感器的信号也可能成为噪声, 该噪声 ( 有一个小于采样时间 Tsampling 的时间常量 ) 通过 ADC 传送到 MCU, 以致引起错误输出 这种情况下, 添加专用旁通电容器或钳位电阻器或电阻分压器, 使其用作低通滤波器 大的电容器将降低 AC 阻抗并更有效的阻断噪声信号 通常而言, 低通滤波器的时间常量 (Rclamp + R1 R2) x Cnoise 应大于采样时间 ( 大于潜规则的 5 ~ 10 倍 ) AN-MCU-500005-Z-11 Page 13
3 模拟输入和相关外部电路 然而, 根据应用程序不同, 时间常量应小于传感器信号中一个 这种情况下, 模拟引脚应跟踪 ADC 的动态变化 选择电容器时, 应考虑 R1/R2 或 Rclamp 的尺寸以避免滤掉重要的高频信号 MCU-AN-500005-Z-11 Page 14
4 采样时间的注意事项 4 采样时间的注意事项 本章介绍变量间的关系 本章介绍 MCU(MB95200H/201H 系列 ) 中的采样时间 首先, 我们介绍变量间的关系 1 MCLK= 1/ PLL clock A/D 转换速度受时钟模式 主时钟振荡频率和主时钟速度切换 ( 换档功能 ) 的影响 例 : 采样时间 =CKIN (ADC:TIM1/TIM0 设置 ) 比较时间 =CKIN 10 ( 固值 ) + MCLK 转换时间 =A/D 启动处理时间 + 采样时间 + 比较时间 根据 A/D 转换器的启动时序, 可能发生最大 1CKIN-1MCLK 的误差 A/D 转换器中进行软件编程时, 需满足 采样时间 和 比较时间 详见 F 2 MC-8FX MB95200H/210H 系列数据手册 的 电气规范 部分 AN-MCU-500005-Z-11 Page 15
5 ADC 示例 5 ADC 示例 本章举例说明 8/10 位 A/D 转换器 通常而言, 有两种方法可用来启动 8/10 位 A/D 转换 一是通过 8/16 位多功能定时器 (TO00) 输出启动, 另一种是设定 A/D 转换启动位 (ADC1:AD=1) 另外, 也有两种方法用来判定 A/D 转换是否完成 5.1 A/D 转换器设定步骤 以下步骤用于设定 8/10 位 A/D 转换器 5.1.1 初始化 设定输入口 (DDR1) 设定中断级 (ILR4) 使能 A/D 输入 (ADC1:ANS0 ~ ANS3) 设定采样时间 (ADC2:TIM1, TIM0) 选择时钟 (ADC2:CKDIV1, CKDIV0) 设定 A/D 转换精度 (ADC2:AD8) 选择操作模式 (ADC2:EXT) 选择启动触发 (ADC2:ADCK) 使能中断 (ADC2:ADIE=1) 激活 A/D 转换器 (ADC1:AD=1) 5.1.2 中断处理 清零中断请求标志 (ADC1:ADI=0) 读取转换值 (ADDH, ADDL) 激活 A/D 转换器 (ADC1:AD=1) MCU-AN-500005-Z-11 Page 16
5.2 A/D 转换器的启动方法 AD 转换器 V1.1 5 ADC 示例 有两种方法用来启动 A/D 转换器 一是设定启动位以产生软件触发 另一种是通过 8/16 位多功能定时器 (TO00) 输出启动 A/D 转换器 以下是上述方法的示例 5.2.1 通过设定启动位启动 A/D 转换器使用 A/D 转换启动位 (ADC1:AD=1) 产生软件触发 ADC2 = 0x81; ADC1 = 0x00; ADC1_AD = 1; //8-bit resolution,2 MCLK //AN00 as input //start AD converter 关于示例代码 project 1 AD_BASIC, 详见附录 AN-MCU-500005-Z-11 Page 17
5 ADC 示例 5.2.2 通过 8/16 位多功能定时器 (TO00) 输出这种情况下, 使用定时器 0 关于定时器 0 操作的详细信息, 详见 F²MC-8FX 硬件手册的第 14 章 以下是 8/16 位多功能定时器 0 的设定示例 /********************************************************** Name: Function: InitCompTimer TO00 control AD converter **********************************************************/ void InitCompTimer(void) T00DR = 0xE0; TMCR0 = 0x40; T00CR0 = 0x01; T00CR1 = 0x81; // set count value (low 8 bit) // 8-bit, no filtering // interval timer with continuous mode // enable output, start timer 以下是 A/D 转换示例 /**************************************************** Name: MCU_Initialization Function: Initialization MCU *****************************************************/ void MCU_initialization() //... ADC1=0x00; //AN00 as input ADC2=0x81; //8-bit resolution, 2 MCLK ADC1_AD = 0; //Don t to start AD conversion. ADC2_ADCK =1; //Start via 8/16-bit composite timer (TO00) output ADC2_EXT =1; //Continuous activation with the clock selected by the ADCK bit in the ADC2 register //... 关于示例代码 project 2 AD-TIMER, 详见附录 MCU-AN-500005-Z-11 Page 18
5 ADC 示例 5.3 A/D 转换状态的判定方法 5.3.1 通过转换标志位判定这种情况下, 应使用转换标志位 (ADC1:ADMV) 若读值是 1, 则 A/D 转换正在进行 /************************************************* Name: Function: AD_Sample Use AN00 as the sample voltage channel **************************************************/ void AD_Sample(void) Distem = ADDL/50; //Read AD Sample Value ADC1_AD=1; //Start AD again /*********************************************************************** Name: Function: syinit Initial AD ***********************************************************************/ void syinit(void) ADC1 = 0x01; ADC2 = 0x82; // start AD converter //8-bit precision, 4 MCLK /******************************************************************** Name: Function: main Main Routine ***********************************************************************/ void main(void) syinit(); while (1) while(adc1_admv); AD_Sample(); //Check converter finish flag, //ADC1_ADMV = 0 means AD Sample finished 关于示例代码 project 1 AD_BASIC, 详见附录 AN-MCU-500005-Z-11 Page 19
5 ADC 示例 5.3.2 通过中断请求标志位判定这种情况下, 应使用中断请求标志位判定 若中断请求标志 (ADC1:ADI=1) 置位, 则中断请求产生的状态下,A/D 转换完成 /********************************************************************* Name: Function: InitADC initialize AD **********************************************************************/ void InitADC(void) ADC2 = 0x89; ADC1 = 0x01; // 8-bit resolution, enable interrupts // AN0 pin as input /******************************************************************** Name: Function: main Main Routine ***********************************************************************/ void main(void) while(1) // waiting for interrupt ( no operation ) asm("nop"); /******************************************************************** AD Interrupt process ***********************************************************************/ interrupt void ISR_ADC (void) Temp=ADDL; ADC1 = 0x00; // read the AD sample value // clear interrupt flag MCU-AN-500005-Z-11 Page 20
5 ADC 示例 注意在标准临时工程的 Vectors.c 模块中, 定义相应的中断向量和中断级 void InitIrqLevels(void) ILR4 = 0xDF; // IRQ16: 16-bit reload timer ch1 I 2 C ch0 // IRQ17: 16-bit PPG ch1 // IRQ18: 10-bit AD-converter // IRQ19: Timebase timer... interrupt void ISR_ADC (void);... #pragma intvect ISR_ADC 18 // IRQ18: 10-bit AD-converter 关于示例代码 project 3 AD_INT, 详见附录 AN-MCU-500005-Z-11 Page 21
6 使用 8/16 位 A/D 转换器时的注意事项 6 使用 8/16 位 A/D 转换器时的注意事项 本章介绍使用 8/10 位 A/D 转换器时的注意事项 6.1 编程设置的注意事项 使用 A/D 转换功能时,A/D 转换完成后, 保持 ADDH 和 ADDL 寄存器的内容 A/D 转换期间, 保持上次转换的值 A/D 转换功能运行时, 特别是连续激活时, 切勿重选模拟输入引脚 (ADC1:ANS3 ~ ANS0) 重选模拟输入通道前, 禁止连续激活 (ADC2:EXT=0) 启动复位模式 停止模式或计时模式以停止 8/10 位 A/D 转换器并初始化各个寄存器 使能中断请求 (ADC2:ADIE=1) 后, 若中断请求标志位 (ADC1:ADI) 置 1, 则 CPU 无法从中断处理程序中返回 务必在中断服务程序中清零 ADI 位 6.2 中断请求的注意事项 若 A/D 转换恢复运行 (ADC1:AD=1) 且同时终止, 则中断请求标志位 (ADC1:ADI) 置位 6.3 误差 Vcc Vss 变小时, 误差相对增大 6.4 8/10 位 A/D 转换器模拟输入时序 数字电源 (VCC) 打开后或打开的同时, 打开模拟输入 (AN00 ~ AN07) 另外, 关闭模拟输入 (AN00 ~ AN07) 的同时或关闭后, 关闭数字电源 (VCC) 打开 / 关闭 8/10 位 A/D 转换器时, 注意不要让模拟输入电压超过数字电源电压 MCU-AN-500005-Z-11 Page 22
7 附加信息 7 附加信息 关于富士通微电子产品的更多信息, 访问以下网页 简体中文版本 : http://www.fujitsu.com/cn/fmc/services/mcu/mb95200/ 中文版本 : http://www.fujitsu.com/cn/fmc/en/services/mcu/mb95200/ AN-MCU-500005-Z-11 Page 23
8 附录 8 附录 8.1 框图一览 图 2-1:ADC 的内部框图... 7 图 2-2:8/10 位 A/D 转换器控制寄存器 1(ADC1)... 8 图 2-3:8/10 位 A/D 转换器控制寄存器 2(ADC2)... 9 图 2-4:8/10 位 A/D 转换器数据寄存器高位 / 低位 (ADDH ADDL)... 10 图 3-1:A/D 转换器的推荐链接 13 8.2 表格一览表 2-1:8/10 位 A/D 转换器中断的关联寄存器和向量表... 11 表 3-1:A/D 转换器相关的电气规范... 12 MCU-AN-500005-Z-11 Page 24
8 附录 8.3 示例代码 8.3.1 Project1 Name: AD_BASIC Function: By setting start-bit and Check with the conversion flag bit /****************************************************************************** Name: MAIN.C ******************************************************************************/ #include mb95200.h unsigned char Distem; /****************************************************************************** Name: AD_Sample Function: Use AN00 as the sample voltage channel ******************************************************************************/ void AD_Sample(void) Distem = ADDL; // Read AD Sample value ADC1_AD=1; // Start AD again /****************************************************************************** Name: syinit Function: Initial AD, IO-PORT ******************************************************************************/ void syinit(void) ADC1=00; //AN00 as input ADC2 = 0x81; //8-bit resolution 2 ÁMCLK ADC1_AD = 1; //start A/D converter DDR0 = 0x00; //use P00-P05 input PDR0 = 0x00; /****************************************************************************** Name: main Function: Main Routine ******************************************************************************/ void main(void) AN-MCU-500005-Z-11 Page 25
syinit(); InitIrqLevels(); EI(); set_il(3); while(1) while(adc1_admv); AD_Sample(); AD 转换器 V1.1 8 附录 // initialize Interrupt level register and IRQ vector table // global interrupt enable // set global interrupt mask to allow all IRQ levels //Check converter finish flag MCU-AN-500005-Z-11 Page 26
8 附录 8.3.2 Project2 Name: AD-TIMER Function: Start A/D by 8/16 bit compound timer and checking with the conversion flag bit /****************************************************************************** Name: MAIN.C Function: Start AD By 8/16-bit composite timer (TO00) output ******************************************************************************/ #include mb95200.h unsigned char ad_data; /****************************************************************************** Name: MCU_Initialization Function: 初始化 MCU ******************************************************************************/ void MCU_initialization() DI(); SYCC=0x00; //MCLK = source clock = 4Mhz (Main CR) DDR0_P05 = 1; AIDRL=0xfc; //IO port WDTC=0x35; //Clear watch dog timer ADC1=0x00 ; //AN00 as input ADC2=0x81; //8-bit precision,disable interrupt, 2 ÁMCLK ADC1_AD = 0; //No start A/D conversion. ADC2_ADCK =1; //Start AD by 8/16-bit composite timer (TO00) output // Continuous activation with the clock selected by the ADCK bit in the ADC2 register ADC2_EXT =1; /****************************************************************************** Name: InitCompTimer Function: TO00 control AD converter ******************************************************************************/ void InitCompTimer(void) T00DR = 0xE0; // set count value (low 8 bit) TMCR0 = 0x40; // 8-bit, no filtering T00CR0 = 0x01; // interval timer with continuous mode AN-MCU-500005-Z-11 Page 27
T00CR1 = 0x81; AD 转换器 V1.1 8 附录 // enable output, start timer /****************************************************************************** Name: ad_sample Function: AD sample code ******************************************************************************/ void ad_sample() while (ADC1_ADMV); Ad_data=ADDL; // If AD Complete? //Read AD Sample value /****************************************************************************** Name: main Function: Main Loop ******************************************************************************/ void main() MCU_initialization(); InitCompTimer(); while(1) ad_sample(); WDTC=0x35; //Clear watch dog timer MCU-AN-500005-Z-11 Page 28
8 附录 8.3.3 Project3 Name: AD_INT Function: Start A/D by setting start-bit and checking with interrupt request flag bit /****************************************************************************** Name: MAIN.C Function: Checking with interrupt request flag bit ******************************************************************************/ #include "mb95200.h" /****************************************************************************** Name: InitADC Function: initialize AD ******************************************************************************/ int tmp; void InitADC(void) ADC2 = 0x89; // 8-bit resolution, enable interrupts ADC1 = 0x01; // AN0 pin as input, start AD /****************************************************************************** Name: main Function: Main Routine ******************************************************************************/ void main(void) PDR0 = 0x00; // Port 0: AIDRL = 0xfe; // used as I/O-port (no analog inputs), P00 as AN-input DDR0 = 0x00; // Set to input InitIrqLevels(); // initialise Interrupt level register and IRQ vector table EI(); // global interrupt enable set_il(3); // set global interrupt mask to allow all IRQ levels InitADC(); // init AD - converter while(1) // waiting for interrupt ( no operation ) asm("nop"); AN-MCU-500005-Z-11 Page 29
8 附录 /***************************************************************************** Interrupt process ******************************************************************************/ #include mb95200.h interrupt void ISR_ADC (void) tmp = ADDL; ADC1 = 0x01; // voltage calculating // clear interrupt flag, start A/D again /***************************************************************************** VECTORS.C ******************************************************************************/ void InitIrqLevels(void) ILR4 = 0xDF; // IRQ16: 16-bit reload timer ch1 I2C ch0 // IRQ17: 16-bit PPG ch1 // IRQ18: 10-bit AD-converter // IRQ19: Timebase timer interrupt void DefaultIRQHandler (void); interrupt void ISR_ADC (void); #pragma intvect ISR_ADC 18 interrupt void DefaultIRQHandler (void) DI(); while(1) wait_nop(); // IRQ18: 10-bit AD-converter // disable interrupts // halt system MCU-AN-500005-Z-11 Page 30