4.PIC16F877 ADC
1.相关寄存器及前言
PIC16F877A 有 8通道 10位模数转换器模块 8个A/D通道为AN0至AN7,通道及引脚对应如下表:
AN0 | AN1 | AN2 | AN3 | AN4 | AN5 | AN6 | AN7 |
RA0 | RA1 | RA2 | RA3 | RA4 |
RE0 |
RE1 | RE2 |
在数据手册113页有相关的寄存器(灰色为无关的,白色为相关的):
其中各部分寄存器对应功能(灰色为无关的,白色为相关的):
使用PIC16F877A的过程主要就是读写相应的寄存器
需要在初始化时(或者使用前)配置好相关寄存器功能参数,接着再读取AD转换结果计算为电压值
本教程中只讲解AD转换结果及AD配置这部分的寄存器,中断相关的之后再讲
2.各部分寄存器的详细配置
ADCON0中的ADCS1,ADCS0,和ADCON1中的ADCS2
这部分是配置转换时钟相关
数据手册131页写到
每位A/D转换时间定义为Tad,A/D转换需要每10位至少12 Tad,A/D转换时钟的来源是软件的选择。
设置不同转换时间对应的ADCS配置如下
而具体的转换时间不是随便定的,有个下限,不能低于1.6us,低于这一时间转换会不准确
ADCON1中的ADFM
ADFM是配置转换结果左右对齐的,2byte是16bit,而PIC16F877A的ADC是10位的,所以会存在左对齐还是右对齐这一问题
ADFM=1则为左对齐,ADFM=0则为右对齐,(ADRESH<<8)|ADRESL即为读取结果
ADCON0中的CHS2,CHS1,CHS0
这几位是选择ADC的通道的,单片机只要一个ADC,所以需要选择输入到ADC的通道来实现多个引脚AD转换,对应的值及通道引脚如图片所示:
ADCON0中的PCFG3,PCFG2,PCFG1,PCFG0
这个是选择引脚是数字脚还是模拟脚,还有选择参考电压源的,配置相关如下
比如想全部为数字脚且参考电压为Vdd和Vss就配置成0110或者0111
ADCON0中的GO和ADON
ADON好理解,就相当一个开关,设置为1的打开ADC,设置为0的时候关闭ADC(会省点电)
GO是开始信号,设置为1时开始转换,当转换完成后GO这一位会被硬件设置为0
ADC转换的流程如下
开始先设置GO为1,等待12个TAD,结束后GO这位被清零,
然后就能读取转换结果ADRESH和ADRESL
并根据这个公示计算
比如开始设置时设置参考电压为电源电压(5v),且用的是PIC16F877A(10位ADC),计算结果是这样
ADC转换对应参考代码
//设置部分,放在初始化的函数中 ADCON0 = 0b01010001; ADCON1 = 0b00000010; //获取电压部分 void getVoltage(){ __delay_us(50); GO = 1;//开始转换 while(GO = 1);//等待转换结束 __delay_us(20); voltage = 5*(ADRESH<<2)/1024;//voltage是一个全局变量,设置为左对齐,只取高位舍五入 }