松翰SN8F5702芯片的学习(三)

        在学习(二)中提到本次会介绍有关芯片的ADC检测及相关的运算。网上也有许多介绍ADC采样的,但不同芯片不同电路,检测运算的方式也不同。

SN8F5702芯片的ADC功能简介

        获取某输入引脚的电压值是不太可能的,因为芯片内部的信号只有01。所以必须经过运算转换将大致的模拟量算出来。进而得知对应的电压值。看芯片的手册的ADC章节可以了解到,SN8F5702芯片的ADC的分辨率是12位(后面运算有用),ADC 参考高电压包括 5 种:4 种内部参考源 (Vdd4V3V 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
		}
	}
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值