Cortex-M3学习日志(六) -- ADC实验
上一次简单的总结了一下DAC方面的知识,好吧,这次再来总结一下ADC方面的东东。ADC即Analog-to-Digital Converter的缩写,指模/数转换器或者模拟/数字转换器。现实世界是由模拟信号组成的,关于为什么要用模数转换器,这大概与现在数字存储技术有关吧,例如温度、压力、声音或者图像等只有转换成数字量才能方便的存储在硬盘、U盘等数码存储介质中,或许某天我们的技术发展了,数字存储可以用某些模拟量存储,也许我们就用不着这么麻烦的转来换去了。好了,闲话不多扯,来简单总结一下ADC的原理。模拟信号转换为数字信号,一般分为四个步骤进行,即取样、保持、量化和编码。前两个步骤在取样-保持电路中完成,后两步骤则在ADC中完成。关于它的原理,主要有以下几种模型:
1、积分型ADC(如TLC7135)
积分型ADC工作原理是将输入电压转换成时间(脉冲宽度信号)或频率(脉冲频率),然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辨率,但缺点是由于转换精度依赖于积分时间,因此转换速率极低。初期的单片AD转换器大多采用积分型,现在逐次比较型已逐步成为主流。
2、逐次比较型ADC(如TLC0831)
逐次比较型AD由一个比较器和DA转换器通过逐次比较逻辑构成,从MSB开始,顺序地对每一位将输入电压与内置DA转换器输出进行比较,经n次比较而输出数字值。其电路规模属于中等。其优点是速度较高、功耗低,在分辨率较低(<12位)时价格便宜,但高精度(>12位)时价格很高。
3、并行比较型/串并行比较型ADC(如TLC5510)
并行比较型AD采用多个比较器,仅作一次比较而实行转换,又称Flash(快速)型。由于转换速率极高,n位的转换需要2n-1个比较器,因此电路规模也极大,价格也高,只适用于视频AD转换器等速度特别高的领域。
串并行比较型AD结构上介于并行型和逐次比较型之间,最典型的是由2个n/2位的并行型AD转换器配合DA转换器组成,用两次比较实行转换,所以称为Half flash(半快速)型。还有分成三步或更多步实现AD转换的叫做分级(Multistep/Subrangling)型AD,而从转换时序角度又可称为流水线(Pipelined)型AD,现代的分级型AD中还加入了对多次转换结果作数字运算而修正特性等功能。这类AD速度比逐次比较型高,电路规模比并行型小。
4、Σ-Δ(Sigma?/FONT>delta)调制型ADC(如AD7705)
Σ-Δ型AD由积分器、比较器、1位DA转换器和数字滤波器等组成。原理上近似于积分型,将输入电压转换成时间(脉冲宽度)信号,用数字滤波器处理后得到数字值。电路的数字部分基本上容易单片化,因此容易做到高分辨率。主要用于音频和测量。
5、电容阵列逐次比较型ADC
电容阵列逐次比较型AD在内置DA转换器中采用电容矩阵方式,也可称为电荷再分配型。一般的电阻阵列DA转换器中多数电阻的值必须一致,在单芯片上生成高精度的电阻并不容易。如果用电容阵列取代电阻阵列,可以用低廉成本制成高精度单片AD转换器。最近的逐次比较型AD转换器大多为电容阵列式的。
6、压频变换型ADC(如AD650)
压频变换型(Voltage-Frequency Converter)是通过间接转换方式实现模数转换的。其原理是首先将输入的模拟信号转换成频率,然后用计数器将频率转换成数字量。从理论上讲这种AD的分辨率几乎可以无限增加,只要采样的时间能够满足输出频率分辨率要求的累积脉冲个数的宽度。其优点是分辨率高、功耗低、价格低,但是需要外部计数电路共同完成AD转换。
DAC的内部电路构成无太大差异,一般按输出是电流还是电压、能否作乘法运算等进行分类。大多数DAC由电阻阵列和多个电流开关(或电压开关)构成。按数字输入值切换开关,产生比例于输入的电流(或电压) 。此外,也有为了改善精度而把恒流源放入器件内部的。DAC分为电压型和电流型两大类,电压型DAC有权电阻网络、T型电阻网络和树形开关网络等;电流型DAC有权电流型电阻网络和倒T型电阻网络等。
1 电压输出型(如TLC5620) 。电压输出型DAC虽有直接从电阻阵列输出电压的,但一般采用内置输出放大器以低阻抗输出。直接输出电压的器件仅用于高阻抗负载,由于无输出放大器部分的延迟,故常作为高速DAC使用。
2 电流输出型(如THS5661A ) 。电流输出型DAC很少直接利用电流输出,大多外接电流- 电压转换电路得到电压输出,后者有两种方法:一是只在输出引脚上接负载电阻而进行电流- 电压转换,二是外接运算放大器。
3 乘算型(如AD7533) 。DAC中有使用恒定基准电压的,也有在基准电压输入上加交流信号的,后者由于能得到数字输入和基准电压输入相乘的结果而输出,因而称为乘算型DAC。乘算型DAC一般不仅可以进行乘法运算,而且可以作为使输入信号数字化地衰减的衰减器及对输入信号进行调制的调制器使用。
4 一位DAC。一位DAC与前述转换方式全然不同,它将数字值转换为脉冲宽度调制或频率调制的输出,然后用数字滤波器作平均化而得到一般的电压输出,用于音频等场合。
选用ADC时要注意这几个参数:取样与保持时间、量化与编码方式、分辨率、转换误差、转换时间、绝对精准度、相对精准度等。
1、取样与保持
由于取样时间极短,取样输出为一串断续的窄脉冲。要把每个取样的窄脉冲信号数字化,是需要一定的时间。因此在两次取样之间,应将取样的模拟信号暂时储存到下个取样脉冲到来,这个动作称之为保持。在模拟电路设计上,因此需要增加一个取样-保持电路。为了保证有正确转换,模拟电路要保留着还未转换的数据。一个取样-保持电路可保证模拟电路中取样时,取样时间的稳定并储存,通常使用电容组件来储存电荷。根据数字信号处理的基本原理,奈奎斯特(Nyquist)取样定理(懒猫记得这个定理应该是在《信号与线性系统》这本课上学的^_^),若要能正确且忠实地呈现所撷取的模拟信号,必须取样频率至少高于最大频率的2倍。例如,若是输入一个100Hz的正弦波的话,最小的取样频率至少要2倍,即是200Hz。虽说理论值是如此,但真正在应用时,最好是接近10倍才会有不错的还原效果(因取样点越多)。若针对多信道的A/D转换器来说,就必须乘上信道数,这样平均下去,每一个通道才不会有失真的情况产生。
2、量化与编码
量化与编码 电路是A/D转换器的核心组成的部分,一般对取样值的量化方式有下列两种:
(1)只舍去不进位
首先取一最小量化单位Δ=U/2n,U是输入模拟电压的最大值,n是输出数字数值的位数。 当输入模拟电压U在0~Δ之间,则归入0Δ,当U在Δ~2Δ之间,则归入1Δ。透过这样的量化方法产生的最大量化误差为Δ/2,而且量化误差总是为正,+1/2LSB。
(2)有舍去有进位
如果量化单位Δ=2U/(2 n+1–1),当输入电压U在0~Δ/2之间,归入0Δ,当U在Δ/2~3/2Δ之间的话,就要归入1Δ。这种量化方法产生的最大量化误差为Δ/2,而且量化误差有正,有负,为±1/2LSB。量化结果也造成了所谓的量化误差。
3、解析度
指A/D转换器所能分辨的最小模拟输入量。通常用转换成数字量的位数来表示,如8-bit,10-bit,12-bit与16-bit等。位数越高,分辨率越高。若小于最小变化量的输入模拟电压的任何变化,将不会引起输出数字值的变化。采用12-bit 的AD574,若是满刻度为10V的话,分辨率即为10V / 212 = 2.44mV。而常用的8-bit 的ADC0804,若是满刻度为5V的话,分辨率即为5V / 28 = 19.53mV。选择适用的A/D转换器是相当重要的,并不是分辨率越高越好。不需要分辨率高的场合,所撷取到的大多是噪声。分辨率太低,会有无法取样到所需的信号。
4、转换误差
通常以相对误差的形式输出,其表示A/D转换器实际输出数字值与理想输出数字值的差别,并用最低有效位LSB的倍数表示。
5、转换时间
转换时间是A/D转换完成一次所需的时间。从启动信号开始到转换结束并得到稳定的数字输出值为止的时间间隔。转换时间越短则转换速度就越快。
6、精准度
对于A/D转换器,精准度指的是在输出端产生所设定的数字数值,其实际需要的模拟输入值与理论上要求的模拟输入值之差。精确度依计算方式不同,可以区分为:绝对精确度与相对精确度。所谓的绝对精确度是指实际输出值与理论输出值的接近程度,其相关的关系是如下式子所列:

相对精准度指的是满刻度值校准以后,任意数字输出所对应的实际模拟输入值(中间值)与理论值(中间值)之差。对于线性A/D转换器,相对精准度就是它的线性程度。由于电路制作上影响,会产生像是非线性误差,或是量化误差等减低相对精准度的因素。相对精确度是指实际输出值与理想理论满刻输出值之接近程度,其相关的关系是如下式子所列:

基本上,一个n-bit的转换器就有n个数字输出位。这种所产生的位数值是等效于在A/D转换器的输入端的模拟大小特性值。如果外部所要输入电压或是电流量较大的话,所转换后的的位数值也就较大。透过并列端口接口或是微处理机连接A/D转换器时,必须了解如何去控制或是驱动这颗A/D转换器的问题。因此需要了解到A/D转换器上的控制信号有哪些。
懒猫为了总结学过的东东,翻箱倒塌柜,终于找到了大学的课本,又在大学城的图书包管里面坐了几个小时,当然了懒猫不也在网上转了N久,所以呢,以上知识大部分来源网络,懒猫囫囵吞枣的咽进了肚里,但大部分也开始消化了,嘻嘻……好了,这ADC有知识先暂时总结到这,下面说一说这次实验的思路(是思路不是丝路^_^)及电路图,并简单的总结一下LPC1768内部集成的ADC。
LPC1768内部集成的是12位主次逼近式的模数转换器,具有8 个通道,它的基本时钟由APB时钟提供,它还包含一个可编程的分频器,可以将APB时钟调整为主次逼近转换所需的时钟(最大可达13MHz)。与ADC相关的引脚配置包括功能配置也即配置引脚功能选择寄存器PINSEL,一般ADC是第二功能,这次实验的电路连接的是ADC0.2通道所以要把P0.25配置成ADC功能,即PINCON->PINSEL1 |= (1<<18); /* 设置ADC有第二通道 */。还要把电源参考引脚连接上参考电源一般是接3V或与VCC电压相等。与 ADC相关的寄存器包括:
1、 外围器接口电源管理寄存器PCONP,要把这个寄存器的第12位即PCADC位置位,这一位是ADC的电源控制与时钟控制位。
2、 A/D控制寄存器ADCR,主要是控制ADC转换的一些操作如通道选择,工作模式选择等等,AD转换开始前,必须设置ADCR寄存器来选择工作模式。
3、 A/D全局数据寄存器ADGDR,它包含最近一次A/D转换的结果。
4、 A/D中断使能寄存器ADINTEN,如果使用转换完中断时,需要配置此寄存器,它包含的使能位控制每一个A/D通道的DONE标记是否用来产生中断。
5、 A/D通道n数据寄存器ADDRn,共有8个,它包含在通道n上完成的最近一次转换结果。
6、 A/D状态寄存器AD0STAT,它包含所有A/D通道的DONE标志和OVERRUN标志,以及A/D中断标志。
关于这几个寄存器的各位代表是什么意思,如何设置,这里就不总结了,芯片的数据手册上写的很清楚,如果你觉得看英文不舒服可以参考一下周公那公司翻译的中文版,应该对初学者有所帮助。下面说一下这次实验的电路图:

图 1-1 电位器分压电路图
实验电路很简单,就是一个电位器来分压,然后由AD转换器的通道2来采样电压,然后再把采集到的电压通过串口0 发送的到串口以便观察采样的电压值,好了,电路这块就不多费口舌了,留点笔墨说一下程序吧,下面先贴出ADC的源代码:
一、AdcFunc.c源代码(主要就是与ADC相关的一些函数)
/*********************************************************************************
文件名称:AdcFunc.c
功 能: 与ADC相关的一些函数
编译环境: MDKV4.12
时 钟: 外部12Mhz
日 期: 11/09/15
作 者: 懒猫爱飞
备 注:NULL
---------------------------------------------------------------------------------
修改内容:NULL
修改日期:XXXX年xx月xx日 xx时xx分
修改人员:xxx xxx xxx
**********************************************************************************/
#include"adc.h"
/********************************************************************************
* 函数名称 :void AdcInit(void)
* 函数功能 : ADC初始化
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :PCONP -- 外围电源控制寄存器,主要是开/关外围功能的电源,以降低功耗
* 此处主要设置该寄存器的第12位(ADC power/clock control bit)
* PINSEL1 -- 引脚功能选择寄存器,主要是配置引脚的功能的,此处主要是设置
* 该寄存器的第18:19位当这两位是10时,选择的是ADC0.2功能
* ADCR -- AD控制寄存器
* 0:7 SEL -- 选择转换通道,1 - 选择 0 - 关闭
* 8:15 CLKDIV -- 选择时钟分频
* 16 BURST -- 循环扫描
* 17:20 Reserved -- 保留位
* 21 PDN -- 转换模式选择 1 - 正常模式 0 - 掉电模式
* 22:23 Reserved -- 保留位
* 24:26 START -- 控制ADC什么时候开始转换
* 27 EDGE -- 转换启动条件 1 - 下降沿启动转换 0 - 上升沿
* 28:31 Reserved -- 保留位
*******************************************************************************/
void AdcInit(void)
{
SC->PCONP |= ( << ); /* 使能ADC控制器电源及时钟源 */
PINCON->PINSEL1 |= (<<); /* 设置ADC有第二通道 */
ADC -> ADCR |= ( << ) /* SEL=4,选择第2通道ADC0.2 */
|( ( / ADC_CLK - ) << ) /* CLKDIV = Fpclk / ADC_CLK - 1 */
|( << )
|( << ) /* PDN = 1,正常工作模式 */
|( << ) /* 设置直接启动模式 */
|( << ) ; /* 默认值 */
}
/********************************************************************************
* 函数名称 :void AdcInit(void)
* 函数功能 : ADC初始化
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :PCONP -- 外围电源控制寄存器,主要是开/关外围功能的电源,以降低功耗
* 此处主要设置该寄存器的第12位(ADC power/clock control bit)
* PINSEL1 -- 引脚功能选择寄存器,主要是配置引脚的功能的,此处主要是设置
* 该寄存器的第18:19位当这两位是10时,选择的是ADC0.2功能
* ADCR -- AD控制寄存器
* 0:7 SEL -- 选择转换通道,1 - 选择 0 - 关闭
* 8:15 CLKDIV -- 选择时钟分频
* 16 BURST -- 循环扫描
* 17:20 Reserved -- 保留位
* 21 PDN -- 转换模式选择 1 - 正常模式 0 - 掉电模式
* 22:23 Reserved -- 保留位
* 24:26 START -- 控制ADC什么时候开始转换
* 27 EDGE -- 转换启动条件 1 - 下降沿启动转换 0 - 上升沿
* 28:31 Reserved -- 保留位
*******************************************************************************/
unsigned int AdcConver(void)
{
unsigned ; /* 转换次数计数 */
unsigned ; /* 暂时存放转换结果 */
unsigned ; /* 存储转换结果 */
;i<ADC_CNT;i++)
{
ADC -> ADCR |= << ; /* 立即启动ADC转换 */
<< ))); /* 读取AD0STAT的通道2的Done */
ADC -> ADCR |= ( <<); /* 第一次转换结果丢弃 */
<< )) == ); /* 读取AD0STAT的通道2的Done */
ulADCbuf = ADC ->ADDR2; /* 只有一路,则读取全局寄存器 */
ulADCbuf = (ulADCbuf >> ) & 0xfff; /* 读取转换结果 */
ulADCData += (unsigned int)ulADCbuf; /* 转换结果累加 */
}
//ADC -> ADCR &= ~(1<<21)&(~(1<<24)); /* 停止ADC转换*/
ulADCData = (ulADCData/ADC_CNT); /* 采样ADC_CNT次进行虑波处理 */
ulADCData = (ulADCData*)/; /* 求取采样结果 */
return ulADCData; /* 返回采样结果 */
}
这个源代码,主要就是ADC初始化与ADC采样程序,程序中我已将用到的寄存器都注释了,对于初学者来说应该不是太难了,下面贴出主程序的部分代码:
二、mian.c(主要调度函数及应用函数)
/*********************************************************************************
工程名称:lesson5
功 能: 学习使用LPC1768的ADC功能
编译环境: MDKV4.12
时 钟: 外部12Mhz
日 期: 11/09/15
作 者: 懒猫爱飞
版本 号:V1R0
---------------------------------------------------------------------------------
修改内容:NULL
修改日期:
修改人员:
---------------------------------------------------------------------------------
**********************************************************************************/
/*********************************************************************************
文件名称:mian.c
功 能: 主要调度函数及应用函数
编译环境: MDKV4.12
时 钟: 外部12Mhz
日 期: 11/09/14
作 者: 懒猫爱飞
备 注:NULL
---------------------------------------------------------------------------------
修改内容:NULL
修改日期:XXXX年xx月xx日 xx时xx分
修改人员:xxx xxx xxx
**********************************************************************************/
#include"includes.h"
volatile unsigned long SysTickCnt; /* 用于系统时钟计数 */
unsigned char LedOnMeg[] = "Led 1 On!\r\n";
unsigned char LedOffMeg[] = "Led all Off!\r\n";
unsigned char KeyMeg[] = "key push down \r\n";
unsigned char DacVal[] = "the voltage is: 0.0 V \r\n";
unsigned ] = {
"**********************************************\r\n",
"**** --欢迎光临-- ****\r\n",
"**** 小野兽的小草窝^_^ ****\r\n",
"**** http://blog.ednchina.com/ytfdhb/ ****\r\n",
"**** 我是懒猫爱飞,我的口号是: ****\r\n",
"**** 每天进步一点点,开心多一点^_^ ****\r\n",
"**********************************************\r\n"
};
unsigned char AdcVal[] = "The ADC converter sampled voltage is: 0.000 V \r\n";
unsigned ; /* 按键状态 */
unsigned ; /* 按键当前状态值 */
unsigned ; /* 按键前一个状态值 */
unsigned ;
unsigned ; /* 状态计数 */
unsigned ;
/********************************************************************************
* 函数名称 :void SysTick_Handler (void)
* 函数功能 : 系统节拍定时器中断函数,每1ms计数一次
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void SysTick_Handler (void)
{
SysTickCnt++;
}
/********************************************************************************
* 函数名称 :void Delay (unsigned long tick)
* 函数功能 : 毫秒级延时函数
* 入口参数 : unsigned long tick -- 延时时长
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void DelayMs (unsigned long tick)
{
unsigned long systickcnt;
systickcnt = SysTickCnt;
while ((SysTickCnt - systickcnt) < tick);
}
/********************************************************************************
* 函数名称 :void PortInit(void)
* 函数功能 : 端口初始化
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void PortInit(void)
{
GPIO1->FIODIR = 0xB0000000; /* LEDs on PORT1 defined as Output */
GPIO2->FIODIR = 0x0000007C; /* LEDs on PORT2 defined as Output */
LedAllOff(); /* 初始化时熄灭所有的灯 */
}
/********************************************************************************
* 函数名称 :void KeyScan(void)
* 函数功能 : 按键扫描
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :现在只扫描一个按键
*******************************************************************************/
void KeyScan()
{
key_pre = KEY_EN ;
if(!KEY_EN ) /* 如果按键按下 */
{
if(key_old)
{
) /* 下降沿有效 */
{
key_sta = ; /* 记录按键状态 */
}
}
}
key_old = key_pre;
}
/********************************************************************************
* 函数名称 :void KeyHandle(void)
* 函数功能 : 按键处理函数
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void KeyHandle(void)
{
)
{
StepCnt++; /* 执行下一步*/
)
{
UART0_SendString (LedOffMeg); /* 显示LED状态信息 */
}
)
{
LedOnMeg[] = StepCnt+0x30; /* 转换成字符 */
UART0_SendString (LedOnMeg); /* 显示LED状态信息 */
}
key_sta = ; /* 按键状态清零,保证只执行一次 */
}
}
/********************************************************************************
* 函数名称 :void LedHandle()
* 函数功能 : LED灯处理函数
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void LedHandle(void)
{
switch(StepCnt)
{
:Led1On(); /* LED1 点亮*/
break;
:Led2On(); /* LED2 点亮*/
break;
:Led3On(); /* LED3 点亮*/
break;
:Led4On(); /* LED4 点亮*/
break;
:Led5On(); /* LED5 点亮*/
break;
:Led6On(); /* LED6 点亮*/
break;
:Led7On(); /* LED7 点亮*/
break;
:Led8On(); /* LED8 点亮*/
break;
:LedAllOff(); /* 熄灭所有的LED灯*/
StepCnt = ; /* 重新开始 */
break;
default:break;
}
}
/********************************************************************************
* 函数名称 :void DacConver(unsigned int val)
* 函数功能 : DAC转换函数
* 入口参数 : unsigned int val -- 要转换的电压值,单位mv
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void DacConver(unsigned int val)
{
unsigned ;
unsigned ;
hi = val/; /* 求电压的整数部分 */
low = val%/; /* 求电压的小数部分 */
DacVal[]= (unsigned char)hi + 0x30; /* 将电压值转换成字符,方便从串口发送 */
DacVal[]= (unsigned char)low + 0x30;/* 将电压值转换成字符,方便从串口发送 */
DacOut(val); /* 赋给DAC控制寄存器DACDR的值*/
UARTSend(,DacVal,); /* 发送转换信息 */
}
/********************************************************************************
* 函数名称 :void AdcDisVal(unsigned int delay)
* 函数功能 : 显示ADC转换结果
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
void AdcDisVal(void)
{
unsigned ; /* 临时存放ADC采样值 */
unsigned ; /* 存放电压整数部分 */
unsigned ; /* 存放电压小数第一位 */
unsigned ; /* 存放电压小数第二位 */
unsigned ; /* 存放电压小数第三位 */
adcval = AdcConver(); /* 获取ADC采样值 */
if(adcval != AdcValOld)
{
)!=AdcValOld)&&((adcval+)!=AdcValOld)&&((adcval+)!=AdcValOld))
{
)!=AdcValOld)&&((adcval-)!=AdcValOld)&&((adcval-)!=AdcValOld))
{
hh = adcval/; /* 求采样值整数部分 */
hi = adcval%/; /* 求采样值小数第一位 */
ll = adcval%/; /* 求采样值小数第二位 */
lo = adcval%; /* 求采样值小数第三位 */
AdcVal[] = (unsigned char)hh + 0x30; /* 将电压值转换成字符,方便从串口发送 */
AdcVal[] = (unsigned char)hi + 0x30; /* 将电压值转换成字符,方便从串口发送 */
AdcVal[] = (unsigned char)ll + 0x30; /* 将电压值转换成字符,方便从串口发送 */
AdcVal[] = (unsigned char)lo + 0x30; /* 将电压值转换成字符,方便从串口发送 */
UARTSend(,AdcVal,); /* 发送转换信息 */
AdcValOld = adcval; /* 更新采样值 */
}
}
}
}
/********************************************************************************
* 函数名称 :int main(void)
* 函数功能 : 主函数
* 入口参数 : 无
* 出口参数 : 无
* 备 注 :无
*******************************************************************************/
int main(void)
{
unsigned ;
SystemInit(); /* 系统初始化,函数在system_LPC17xx.c文件夹中定义 */
SysTick_Config(SystemFrequency/ - );/* 配置节拍定时器中断,每1ms中断一次 */
PortInit(); /* 端口初始化 */
//DACInit(); /* DAC初始化 */
AdcInit(); /* ADCC初始化 */
UARTInit(,); /* 设置串口0波特率 */
;i<;i++)
{
UARTSend(,OpenString[i],); /* 发送欢迎信息 */
}
/* 下面的函数是测试DAC的,分别输出2.0V、2.5V、3.0V与3.3V*/
//DacConver(2000); // 2.0v
//DacConver(2500); // 2.5v
// DacConver(3000); // 3.0v
//DacConver(3300); // 3.0v
//LedOnMeg[4] = 4+0x30; /* 转换成字符 */
//UART0_SendString (KeyMeg);
)
{
KeyScan(); // 按键扫描
KeyHandle(); // 按键处理
LedHandle(); // Led处理程序
AdcDisVal(); // ADC采样
}
}
下面是程序执行结果:

图 1-2 程序执行结果
这只是部分代码,详细的源代码请参考附件。这段代码是将采集到的数据转换成字符发送到串口显示,里面没有什么复杂的计算,都是烂大街的程序,因为懒猫也不是什么高手,也说不出什么高深的理论,只能总结点简单的东西,希望这些简单的实验能起到抛砖引玉的作用,让初学者尽快能迈入单片机这扇门,万事开头难,徘徊在门口的感觉最不好爱,懒猫也曾彷徨过,也曾无奈过,也曾痛苦过,也曾抱怨过,但道路虽然崎岖,只要你坚持就能爬到山顶。懒猫深知很多人面对电子有着莫大的兴趣,但却无从下手,没有高手指导,没有教材参考,这种感觉实在不好爱,所以懒猫有空便会写下自己的学习日志,尽量简单,尽量详细,俗话说师傅引进门,修行靠个人,当你熬过阵痛,跨进电子这扇门之后,剩下的事就是发挥你的聪明才智,努力的创造奇妙的未来!还是那句老话,学无难易,贵在坚持!
Cortex-M3学习日志(六) -- ADC实验的更多相关文章
- stm32和cortex M3学习内核简单总结
1.stm32综述 2.寄存器组 3.操作模式和特权级别 4.存储器映射 5.中断和异常 6.其他 Stm32综述 这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来 ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- Cortex-M3学习日志(五) -- DAC实验
终于逮了个忙里偷闲的机会,就再学一下LPC1768的外围功能吧,循序渐进是学习的基本规则,也许LPC1768的DAC与8位单片机16位单片机里面集成的DAC操作类似,但是既然这是懒猫的学习日志,就顺便 ...
- Redis学习笔记六:持久化实验(AOF,RDB)
作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...
- ARM Cortex M3系列GPIO口介绍(工作方式探讨)
一.Cortex M3的GPIO口特性 在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图 从图中可以看出 ...
- ARM Cortex M3(V7-M架构)硬件启动程序 一
Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- 201521123122 《java程序设计》 第六周实验总结
201521123122 <java程序设计>第六周实验总结 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想 ...
- ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)
ARM架构: 由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7: 一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...
随机推荐
- JQuery给元素绑定click事件多次执行的解决方法
原绑定方法: $(".subNavdiv").click(function () { ###### }); 这种方法只会在原click方法中继续添加新方法: 解决办法更改绑定方法为 ...
- Android 测试工具集02
User scenario testing for Android(功能性测试框架) Robotium is an Android test automation framework that has ...
- AutoItLibrary库入门
一.AutoItLibrary入门 1. 为什么要使用AutoItLibrary Selenium2library在我们实际测试web页面的时候基本上已经够用了,不过还是会有部分情况下会脱离Selen ...
- jQuery学习-事件之绑定事件(五)
大家应该还记得dispatch方法中有这么一段代码: event = jQuery.event.fix( event ); event的修复是在fix这个方法中的,而在fix中是通过 new jQue ...
- JS中如何使用Cookie
1.关于JS设置Cookie的说明 在Javascript脚本里,一个cookie 实际就是一个字符串属性.当你读取cookie的值时,就得到一个字符串,里面当前WEB页使用的所有cookies的名称 ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- 第一个使用Writer写的博客
今天开通的博客园的博客账户,先来尝试一下用哪种方式最适合写博. 目前用Live Writer. 以后计划在这里分享数据技术的技术体会和学习心得,尤其是大数据和数据仓库相关的知识.Hello my bl ...
- aix vg lv pv
lsvg lsvg -o lsvg rootvg 查看rootvg的信息 lsvg -p rootvg 查看rootvg卷里的物理硬盘以及分布信息 lsvg -l rootvg 查看rootvg卷下的 ...
- 成都UBER优步司机第六组奖励政策
保底时段详解 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs. ...
- wx.ToolBar
wx.ToolBar A toolbar is a bar of buttons and/or other controls usually placed below the menu bar in ...