在学习(二)中提到本次会介绍有关芯片的ADC检测及相关的运算。网上也有许多介绍ADC采样的,但不同芯片不同电路,检测运算的方式也不同。
SN8F5702芯片的ADC功能简介
获取某输入引脚的电压值是不太可能的,因为芯片内部的信号只有01。所以必须经过运算转换将大致的模拟量算出来。进而得知对应的电压值。看芯片的手册的ADC章节可以了解到,SN8F5702芯片的ADC的分辨率是12位(后面运算有用),ADC 参考高电压包括 5 种:4 种内部参考源 (Vdd、4V、3V 和 2V)和外部参考源(由 AVREFH 引脚提供)。其他的不介绍了,自己想了解的去看芯片手册。直接介绍怎么编写ADC的初始化配置。
芯片ADC的初始化配置代码,结合上述自己理解相关意思。

void ADC_Init() { ADR=0x40;//使能AIN通道,选择时钟源Fosc/16;Fosc=32MHz; VREFH=0x02;//使能ADCC內部VREFH,禁止PWM触发ADC开始,选择内部高电压4.0V P1CON=0x0f;// ADM=0x83;//使能ADC加上选择AIN3/P13通道作为ADC采样输入 }
讯享网
SN8F5702芯片的获取ADC的值
配置好检测的参考电压和ADC的采样通道后,就需要通过相关的计算得到对应的电压模拟量。运算公式在主函数中。
讯享网uint GetAdc(uint ad_channel)//获取对应通道的ADC的值0x81,0x82,0x83等,分别检测P11,P12,P13等,看自己需求 { uchar i = 0; uint temp_ad_buf = 0; uint temp_ad_data = 0; ADM = (ADM&0XF0)|ad_channel; for(i = 0; i < 8; i++) { ADM |= 0x40; //Start ADC while((ADM & 0x20) != 0x20); //EOC ADM &= 0xdf; temp_ad_buf = ADB; temp_ad_buf = (temp_ad_buf << 4) + (ADR & 0x0f); temp_ad_data += temp_ad_buf; } temp_ad_data = (temp_ad_data ) >> 3; return temp_ad_data; }
获取到的值temp_ad_data为启动芯片进行ADC采样后相关寄存器中的值。
对某电池接入引脚进行ADC电压判断
前面介绍过ADC相关的程序编写,现在就看一看整个过程。代码如下。
#include<SN8F5702.H> /* SN8F5702芯片只有P0.0-P0.7,P1.0-P1.7,P2.0-P2.1引脚 */ #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define BAT_VC 0x83 sbit LED1=P0^0; sbit LED2=P0^1; void GpioInit() { //用户在用C语言编写的时候,必须按照这个顺序编写设置系统时钟 CKCON = 0x70; CLKSEL = 0x05; CLKCMD = 0x69; CKCON = 0x00; //芯片IO口的设置,P0,P1,P2 //其中P1口有唤醒使能P1W P0=0xff;//输出高低电平控制,POM相应位使能 P0M=0xff;//定义输入0输出1。 P0UR=0x00;//内置上拉电阻控制,禁止0使能1,IO口为输出模式是建议禁止 P1=0x00; P1M=0x00; P1UR=0x00; P1W=0x00;//唤醒禁用0,使能1 P2=0x00; P2M=0x00; P2UR=0x00; } void ADC_Init() { ADR=0x40;//使能AIN通道,选择时钟源Fosc/16;Fosc=32MHz; VREFH=0x02;//使能ADCC內部VREFH,禁止PWM触发ADC开始,选择内部高电压4.0V P1CON=0x0f;// ADM=0x83;//使能ADC加上选择AIN3/P13通道作为ADC采样输入 } uint GetAdc(uint ad_channel)//获取对应通道的ADC的值 { uchar i = 0; uint temp_ad_buf = 0; uint temp_ad_data = 0; ADM = (ADM&0XF0)|ad_channel; for(i = 0; i < 8; i++) { ADM |= 0x40; //Start ADC while((ADM & 0x20) != 0x20); //EOC ADM &= 0xdf; temp_ad_buf = ADB; temp_ad_buf = (temp_ad_buf << 4) + (ADR & 0x0f); temp_ad_data += temp_ad_buf; } temp_ad_data = (temp_ad_data ) >> 3; return temp_ad_data; } uint BatAdc=0; uint BatAdcValue=0; void main() { GpioInit(); ADC_Init(); LED1=0,LED2=0; while(1) { BatAdc=GetAdc(BAT_VC); BatAdcValue=(ulong)BatAdc*4000/4096;//得到的数值位数字量,千数值 if(BatAdcValue >= 2800)// { //定2.8V LED1=1;//端口值大于2.8V LED2=0; } else { LED1=0; LED2=1;//端口值小于2.8V } } }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/13932.html