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

2023-11-05

一、什么是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);  //设置数据指针起点
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STC15单片机自带的AD功能的使用 的相关文章

  • Kafka压力测试(官方自带)

    1 Kafka压测 用Kafka官方自带的脚本 对Kafka进行压测 Kafka压测时 可以查看到哪个地方出现了瓶颈 CPU 内存 网络IO 一般都是网络IO达到瓶颈 kafka consumer perf test sh kafka pr
  • Django Orm 查询总结

    Django提供了一套非常方便的类似lingQ的通过对象调用的方式操作数据库表的Orm框架 关于Django Orm的操作方式做下整理 Django Orm 操作主要分为以下几类 增 向表内插入一条数据 删 删除表内数据 物理删除 改 up

随机推荐

  • [leetcode] 1675. 数组的最小偏移量

    题目链接 来源 力扣 LeetCode 链接 https leetcode cn problems minimize deviation in array 著作权归领扣网络所有 商业转载请联系官方授权 非商业转载请注明出处 示例 1 输入
  • AMR 文件解析及编解码流程

    CONTENT AMR简介 AMR 话音质量评定 AMR 文件结构解析 AMR 帧结构解析 AMR 帧读取算法 AMR 解码原理及流程 AMR 模式选择自适应机制 一 AMR 简介 基于新的网络和新的要求 无论是从节省传输频带资源 还是保持
  • Java学习之线程安全问题,关于synchronized 和 Lock 的使用

    1 Lock 解决线程安全问题的方式三 Lock锁 JDK5 0新加 synchronized 与 Lock的区别 相同点 都是解决线程的安全问题 不同点 1 Lock是显示锁 手动开启和关闭锁 synchronized是隐式锁 出了 作用
  • 智能算法系列之遗传算法

    本博客封面由ChatGPT Midjourney共同创作而成 文章目录 前言 1 算法思想 2 细节梳理 2 1 DAN编码 2 2 种群初始化及超参选择 2 3 适应度函数 2 4 选择 交叉 交配 与变异 2 5 终止条件 3 算法实现
  • MDK 出现#68-D: integer conversion resulted in a change of sign

    出现这种情况 原因如下 1 出现了无符号转换成有符号数 但是数据的最高位是符号位 可能会导致数字的值突变 2 有符号数被转换成了无符号数 经常在代码中会定义状态 错误的宏定义 出现 1等等负数 然而程序的返回值类型是 uint8 t uin
  • mfc 窗口初始化以及销毁过程

    1 模式对话框的创建过程 1 DoModal 重载函数 重载DoModal 成员函数 2 PreSubclassWindow 重载函数 允许首先子分类一个窗口 3 OnCreate 消息响应函数 响应WM CREATE消息 发送此消息以告诉
  • 机器学习实战 决策树(附数据集)

    运行环境 Anaconda Jupyter Notebook Python版本为 3 6 6 数据集 lense txt 提取码 9wsp 1 决策树 决策树也是最经常使用的数据挖掘算法 长方形代表判断模块 decision block 椭
  • 网络安全实验室4.注入关

    4 注入关 1 最简单的SQL注入 url http lab1 xseclab com sqli2 3265b4852c13383560327d1c31550b60 index php 查看源代码 登录名为admin 最简单的SQL注入 登
  • Could not autowire. No beans of 'OrderService' type found. less... (Ctrl+F1) Inspection info:Checks

    解决方法 步骤如下 把最后一个 去掉 点击ok就好了 当然还有一点就是 sevice类的前面加上 service注解
  • BRAM资源不够用?不怕!这里有FPGA BRAM省资源小秘招!

    FPGA的BRAM和LUT等资源都是有限的 在FPGA开发过程中 可能经常遇到BRAM或者LUT资源不够用的情况 一般建议BRAM和LUT资源的消耗不要超过80 当然高端一点的FPGA芯片也可以放宽到90 超过这个限制 可能就会出现时序违例
  • wifi中断攻击

    前言 wifi攻击包括wifi中断攻击 wifi密码爆破 wifi钓鱼等 本文章持续更新以上内容 先以wifi中断攻击为始 硬件为ESP8266 还买了一个无线网卡用作后续wifi密码爆破 网上某宝十几块钱就能玩 我买的是带Micro接口
  • Git的简述

    Git 文章目录 Git Git概述 版本控制工具 集中式管理控制工具 分步式管理控制工具 控制机制 Git和代码托管中心 安装Git软件 Git常用命令 Git概述 Git是一个免费的 开源的分步式版本控制系统 可以快速的处理从小型到大型
  • 输入一个url会发生什么事情?

    输入一个url会发生什么事情 1 输入解析 1 1 如果输入的是非url结构的字符串 则会使用默认浏览器的搜多引擎搜索这个字符串 1 2如果输入是url结构的字符串 url将通过进程建通信发送给网络进程 网络进程会进行DNS解析得到对应的I
  • 数据库基础 (关系数据库)

    14 34 属性 表的列 域 属性的范围 笛卡尔积 所有集合所有数X一遍 目或度 关系表属性的数量 候选码 唯一属性标识 主码 主键 外码 外键 主属性 候选码里的都叫主属性 全码 所有属性都是候选码 称为全码 关系的三种形式 基本关系 基
  • 国标GB28181视频监控平台EasyGBS视频无法播放,抓包返回ICMP是什么原因?

    国标GB28181视频平台EasyGBS是基于国标GB T28181协议的行业内安防视频流媒体能力平台 可实现的视频功能包括 实时监控直播 录像 检索与回看 语音对讲 云存储 告警 平台级联等功能 国标GB28181视频监控平台部署简单 可
  • 大数据手册(Spark)--Spark基础知识(PySpark版)

    文章目录 Spark 初始化 弹性分布式数据集 RDD DataFrame Spark安装配置 Spark基本概念 Spark基础知识 PySpark版 Spark机器学习 PySpark版 Spark流数据处理 PySpark版 Spar
  • Python-netfilterqueue(白帽)[netfilterqueue怎么安装在kali中?][iptables怎么用]

    一 环境安装 前要 使用python3 6以上版本安装netfilterqueue会出现报错无法安装 1 安装python3 6 前提 本机已有python3 9 在此前提下安装python3 6 问题 中间有什么报错无法进行 一般是小问题
  • C语言自动抓取淘宝商品详情网页数据,实现轻松高效爬虫

    你是否曾经遇到过需要大量获取网页上的数据 但手动复制粘贴又太过费时费力 那么这篇文章就是为你而写 今天我们将会详细讨论如何使用C语言实现自动抓取网页上的数据 本文将会从以下8个方面进行逐步分析讨论 1 HTTP协议的基本原理 在开始之前 我
  • Java 自动单元测试生成框架

    推广博客 Java 自动单元测试生成框架
  • STC15单片机自带的AD功能的使用

    一 什么是ADC DAC ADC Analog to Digital Converter的缩写 意思是模 数转换器 实现把模拟信号转变为数字量的设备称为模 数 A D 转换器 简称ADC 实现把数字量转变为模拟量的设备称为数 模 D A 转