PIC单片机之AD转换学习记录

        首先,简单介绍一下AD原理。ADC是指将模拟信号转换成数字信号的过程。通俗理解ADC采样就是采集电路中的电压,通过数值的方式表现出来。

        以PIC16F877芯片为例,它是10位ADC,供电电压是5V,它能检测的电压也是0~5V(参考电压可以自己修改)。这就好理解了,0~5V电压对应的是0~1024数值。通俗理解为把5V分成了1024份,采集上来多少份占5V的比例。

        采集电压=(采集数值/1024)*5V

        该MCU的ADC采集精度是10位,参考电压为5V,则采集精度为5/2^10=4.8mV。

内部只有一个ADC,有八个模拟输入通道,需要软件设置选择用哪一路通道进行AD采集,方式为循环检测

一、AD转换相关寄存器介绍

1.AD控制寄存器(ADCON0:各寄存器功能如图。

ADON:AD采集的开关,写0关闭ADC,写1开启ADC。

B1没用到。

GO/DONE(B2):ADON=1时,也就是把AD打开的前提下,该位写0表示AD转换已经完成;该位写1表示AD转换还在进行。

bit3-bit5共同作用,用于选择AD采集的通道。

bit6-bit7共同作用,选择AD采集的时钟和频率,可选择内部时钟或外部时钟,一般情况都选择外部时钟。

2.ADC控制寄存器ADCON1

ADFM:用于设置AD转换结果的存放格式。

PCFG0-PCFG3:AD转换引脚功能选择位。包括AD转换结果的形成方式,RA和RE端口各引脚的初始化设置,也就是选择设置为模拟输入、参考电压输入还是通用IO口的方式。见下图。

比如:PCFG3-PCFG0设置为0000,此时将AN0-AN7都设置为模拟输入,参考电压为MCU的电源VDD和VSS,CHAN/REFS表示有八个通道,有0个可以作为参考电压。PCFG3-PCFG00001的时候,将AN4设置为正参考电压,给AN4输入一个电压值,这个电压值就是参考电压正极。

3.ADC结果寄存器高位ADRESH

4.ADC结果寄存器低位ADRESL

        用了两个8位的寄存器存放10位的转换结果,ADFM1=1时,将AD转换结果的低八位放到ADRESL里,高两位放到ADRESH里,ADRESH的其余位为0;ADFM1=0时,将AD转换结果的高八位放到ADRESH里,低两位放到ADRESH里,ADRESH的其余位为0;总结就是,如果分辨率只需要8位的话,可以直接从ADRESH里读取八位数据。

三、AD编程方法

要使用好ADC模块,要先在程序中进行初始化设置。这些设置需要包含以下内容:

1.设置ADC模块端口和数据格式

通过控制寄存器ADCON1设置引脚功能为模拟输入信道、参考电压接入方式、通用I/O引脚以及转换结果的存放格式。上面都已介绍。

2.设置ADC模块工作方式

通过控制寄存器ADCON0选中某一条模拟输入信道、设定AD转换时钟源以及开启AD转换功能。

3.如果需要中断功能,需要设置AD中断使能位

清除ADC模块中断标志位ADIF、设置ADC模块中断使能位ADIE=1、设置中断使能PEIE=1和设置全局中断使能位GIE=1.

4.等待所需要的采样时间

采样时间大约是10-20us。影响采样时间的主要因素之一是模拟信号源内阻,信号源的最大阻抗不得超过10K。

5.将控制位GO/DONE置1,开始AD转换

6.等待AD转换完成,可以通过以下两种方法来判断:

方法一:软件循环查询状态位兼控制位GO/DONE是否被硬件自动清0或中断标志位ADIF是否被硬件自动置位。

方法二:等待中断请求。在AD转换完成后,ADIF位被置位,发出中断请求。

7.读取AD转换结果寄存器对ADRESH,ADRESL

如果使用中断标志,需要都ADIF清零。

8.如果需要继续转换,根据实际要求重新从第2步或者第3步开始

在转换完成后,下一次采样开始前,需加入2Tad的等待时间,约是3.2us(Tad为AD每位转换时间)

四、示例代码

         配置ADC的AN4信道采集模拟信号,MCU为PIC16F677。

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
// 配置字
#pragma config FOSC = XT // 使用外部晶振
#pragma config WDTE = OFF // 禁用看门狗定时器
#pragma config PWRTE = ON // 启用上电复位定时器
#pragma config CP = OFF // 禁用代码保护

#define _XTAL_FREQ 32768 // 外部晶振的频率,单位Hz


void AD_Init();
unsigned int Get_AD_Value();

void main() 
{
    unsigned int ad;  
    AD_Init();
    while(1)
    {
       ad = Get_AD_Value();
    
    }
}


//AD初始化
void AD_Init()
{
    TRISC = 1; // 将C端口设置为输入
    ADCON0 = 0X91; //手册page113  RC0--AN4 数据右对齐
    ADCON1 = 0;
}

//获取AD值
unsigned int Get_AD_Value()
{
    unsigned int adval_16;  //保存数据高八位
    GO_nDONE  =  1; //开启中断
    while(GO_nDONE);//GO_bit=0,AD转换结束,跳出循环
    adval_16 = ADRESH;//高寄存器保存两位,假设是0b00000000 00000011
    adval_16 = adval_16<<8 | ADRESL;//00000011 或|就是加
    return adval_16;
}        

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值