STC15单片机自带的AD功能的使用

一、什么是ADC\DAC?

ADC: Analog-to-Digital Converter的缩写,意思是模/数转换器。实现把模拟信号转变为数字量的设备称为模—数(A/D)转换器,简称ADC。
实现把数字量转变为模拟量的设备称为数—模(D/A)转换器,DAC(Digital to Analog Convertor)简称DAC。

二、A/D转换器的结构

STC15系列的A/D转换器结构如图

STC15系列单片机的ADC是逐次比较型ADC。由多路选择器开关,比较器、逐次比较寄存器、10位DAC、转换结果寄存器(ADC_RES和ADC_RESL)以及ADC_CONTR构成。

从图中可以看到P1.0-P1.1口都可以用来进行AD转换功能,只需要在配置相关寄存器后打开对应IO口这个功能就可以了。

三、寄存器配置

为了使用AD功能需要涉及到以下寄存器。

P1模拟功能控制寄存器P1ASF

这个寄存器的功能就是打开对应的IO口,如P1ASF=0X01;就是把P1.0口的AD功能打开了。

 ADC控制寄存器ADC_CONTR

使用AD功能最重要的就是配置这个寄存器,下面将介绍每一位的功能。

ADC_POWER:电源控制位

                0:关闭电ADC电源。(注:不用AD功能关闭电源可以降低功耗)

                1:打开A/D转换器电源。初次打开需要适当的延时。

SPEED1,SPEED0:转换器速度控制位

ADC_FLAG:模数转换器结束标志位,完成后ADC_FLAG=1,要软件清零。

ADC_START:模数转换器转换启动控制位,ADC_START=1开始转换,结束                        后自动清零。

CHS2/CHS1/CHS0:模拟输入通道选择。

ADC转换结果调整寄存器——ADRJ

ADRJ:ADC转换结果调整

 0:ADC_RES[7:0]存放高8位ADC结果,ADC_RESL[1:0]存放低2位ADC结果

 1:ADC_RESL[1:0]存放高2位ADC结果,ADC_RES[7:0]存放低8位ADC结果如果需要取完整10位结果

如果只需要取8位结果

中断允许寄存器IE

EA:总中断开关位

  1:CPU接收中断

  0:COU屏蔽所有中断

EADC:A/D转换中断允许位

       1:允许A/D转换中断

       0:禁止A/D转换中断

中断优先级控制寄存器IP

PADC:A/D转换中断优先级控制位

       0:设为最低优先级

       1:设为最高优先级

举例用lcd1602显示ad采集的电压

main函数:

#include <stc15f2k60s2.h>
#include <15AD.h>
#include <lcd.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

void main()//主函数
{
	uint AD_DAT;//AD转换后缓存变量
	uchar yi,er;//缓存变量的整数部分、小数部分
	adc_init();//打开AD复用功能
	LcdInit();	//初始化lcd1602显示屏
	while(1)
	{
	  AD_DAT= get_adc();//把转换好的AD数据赋给AD_DAT
	  AD_DAT=AD_DAT*0.0475;//把AD_DAT转换为十进制数

	  yi=AD_DAT%100/10;//取AD_DAT的整数部分
	  er=AD_DAT%10;//取AD_DAT的小数部分
		LcdWriteCom(0x80); //0x80是第一行的第一个字符的地址
    LcdWriteData('0'+yi);//显示整数部分
    LcdWriteData('.');//显示 .
		LcdWriteData('0'+er);//显示小数部分
		LcdWriteData('V');//显示 V
	}
		
}

15AD.h:

#define __15AD_H

//---重定义关键词---//
#define nop _nop_()
#define ADC_POWER 0x80//开电源
#define ADC_START 0x08
#define ADC_FLAG  0x10
#define ADC_SPEEDH 0x40//转换速度为180个时钟周期
#define ADRJ 0X20  //ADRJ=1
#define AD_P1_0 0X00//P1.0为AD输出

/**********************************
函数声明
**********************************/
void	Delay10ms();//10毫秒延时
void adc_init(void);//AD功能初始化
unsigned int get_adc();//获取AD值
#endif

15AD.c:

#include <reg51.h>
#include <intrins.h>
#include <15AD.h>
#define nop _nop_()//延时
#define ADC_POWER 0x80//开电源
#define ADC_START 0x08//AD转换启动控制。
#define ADC_FLAG  0x10//AD转换结束标志
#define ADC_SPEEDH 0x40//转换速度为180个时钟周期
#define ADRJ 0X20  //ADRJ=1
#define AD_P1_0 0X00//P1.0为AD输出
sfr ADC_CONTR = 0Xbc;//命名ADC控制寄存器
sfr ADC_RES = 0Xbd;//命名数据高位
sfr ADC_RESL = 0Xbe;//命名数据低位
sfr P1ASF=0X9D;//命名P1口控制寄存器
sfr PCON2=0X97;//命名时钟分频寄存器
/***************AD初始化函数****************
设置P1.0口为AD输入口;
数据存放方式为高两位低八位;
开启电源;
设置转换速度;
*******************************************/
void adc_init(void)
{
  P1ASF=0X01;//P1ASF.0=1;//设置P1为模拟量输入
	PCON2=PCON2|ADRJ;//ADRJ=1
	ADC_CONTR = ADC_POWER|ADC_SPEEDH|AD_P1_0;
	//设置AD电源开启、转换速度设置、AD输入端口
	nop;nop;nop;nop;//延时4个机械周期
	
}

/***************读取AD值函数****************
开始转换AD数据;
等待转换完成;
存放数据;
清零标志位和数据位;
*******************************************/
unsigned int get_adc()//读取AD值
{
unsigned int i,j;
	ADC_CONTR=ADC_CONTR|ADC_START;//开始转换
	while((ADC_CONTR&ADC_FLAG)!=ADC_FLAG);//等待转换标志位
	i=ADC_RES;
	j=ADC_RESL;
	i=i<<8;
	i=i|j;
	ADC_CONTR=ADC_CONTR&~ADC_FLAG;//清零转换标志位
	ADC_RES=0;//数据清零
	ADC_RESL=0;//数据清零
	return(i);
}

lcd.h:

#ifndef __LCD_H_
#define __LCD_H_

/**********************************
包含头文件
**********************************/
#include <stc15.h>
#include <intrins.h>

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P4^1;
sbit LCD1602_RW=P4^2;
sbit LCD1602_RS=P4^4;

/**********************************
函数声明
**********************************/
/*在15单片机11.0592MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/	
void LcdWriteData(uchar dat)	;
/*LCD1602初始化子程序*/		
void LcdInit();						  

#endif

lcd.c:

/********************************************************
**文件名:LCD1602驱动
**日  期:2020/11/19
**描  述:
**修改记录:无
********************************************************/
#include"lcd.h"
/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能		   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在11.0592 MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
	unsigned char i, j;
	for (; c>0; c--)
	{
	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;     
	do
	{
		while (--j);
	} while (--i);
	}
}
/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能		   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;	 //使能清零
	LCD1602_RS = 0;	 //选择写入命令
	LCD1602_RW = 0;	 //选择写入

	LCD1602_DATAPINS = com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
	
	LCD1602_DATAPINS = com << 4; //发送低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能		   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/		   
void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	  //使能清零
	LCD1602_RS = 1;	  //选择写入数据
	LCD1602_RW = 0;	  //选择写入

	LCD1602_DATAPINS = dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;

	LCD1602_DATAPINS = dat << 4; //写入低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能		 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/		   
void LcdInit()						  //LCD初始化子程序
{
	LcdWriteCom(0x32);	 //将8位总线转为4位总线
	LcdWriteCom(0x28);	 //在四位线下的初始化
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}
  • 15
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STC8A单片机是一款高性能、低功耗的8位单片机,具有多种功能和特性。它的ADC(模数转换器)模块可以用于采集模拟信号,并将其转换为数字信号进行处理。 STC8A单片机ADC采集程序需要以下基本步骤: 1. 初始化ADC模块:配置ADC通道、参考电压以及采样时钟等参数。可以使用相应的寄存器设置来完成此任务。 2. 设置ADC输入通道:选择需要采集的模拟信号输入通道。单片机ADC模块可以有多个输入通道,通过设置相应的寄存器来选择通道。 3. 启用ADC模块:将ADC模块打开,使其处于工作状态。可以通过设置相应的寄存器来完成此任务。 4. 设置ADC采样时钟:根据需求设置ADC的采样时钟频率。采样时钟频率的选择要结合被采样信号的变化速度和所需精度来确定。 5. 开始采样:启动ADC模块进行模数转换,将模拟信号转换为数字信号。可以通过设置相应的寄存器来启动ADC转换过程。 6. 等待转换完成:等待ADC转换完成,可以通过查询相应的标志位或使用中断来实现。一旦转换完成,可以读取转换结果。 7. 处理转换结果:获取ADC转换的结果值,并进行相应的处理。可以将结果值用于后续的计算、显示或其他处理。 8. 关闭ADC模块:在不需要进行ADC采集时,应关闭ADC模块,以节省功耗。 以上是STC8A单片机ADC采集程序的基本步骤。通过合理的配置和操作,可以实现对模拟信号的精确采集和处理,满足各种应用需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值