当前位置: 首页 > news >正文

江科大51单片机笔记【16】AD/DA转换(下)

写在前言


  此为博主自学江科大51单片机(B站)的笔记,方便后续重温知识

  在后面的章节中,为了防止篇幅过长和易于查找,我把一个小节分成两部分来发,上章节主要是关于本节课的硬件介绍、电路图、原理图等理论知识,主要是为下章节的代码部分打基础。

  我的单片机是24年12月在tb普中买的,型号是STC89C52,在原视频中引脚或接口不对应的我都会改正,保证在我的机子上能运行才发上来的,还有一些文字部分是我的理解,并非照搬,所以可能有理解不到位的现象。

  如有误或交流,敬请指点提问

如果上一节的运放、电路图、结构图看不懂没关系,只需要看懂下面这个时序图就可以写代码实现功能了

一、AD模数转换

先导入之前写好的Delay和LCD1602模块,然后新建XPT2046点c和点h文件

接下来就是对照这个时序把数据读出来

1.先定义引脚

#include <REGX52.H>

sbit XPT2046_CS=P3^5;
sbit XPT2046_DCLK=P3^6;
sbit XPT2046_DIN=P3^4;
sbit XPT2046_DOUT=P3^7;

 2.定义函数

给个参数(控制字),用于选择通道

并且定义一个变量ADAvalue,最后返回出来

 然后是根据上图对每个引脚先后赋值

首先把DCLK置0(初始化),CS置0,DIN赋值参数控制字的最高位
然后再给DCLK置1(上升沿),DIN就把最高位发出去,然后置0(下降沿),查看手册发现上下时间是ns级,所以不用延时

接下来就是同理依次把8个位发出去,用for循环实现

发出去之后就可以读数据了

接下来就是到图中这个位置,先给DCLK一个上升沿,一个下降沿,数据才会过来

进行一个判断,如果Dout为1,就让ADAValue把数据读出来(因为是16位所以或上0x8000)

然后对该过程循环16位,用for循环实现,因为只有12位是有数值的,后面都是零填充的,所以我们要在最后返回ADAValue的时候向右移位(如果选择8位读就移8位,12位读就移4位)

最后再把CS置高,结束这个时序,到这里就写完这个函数了

//XPT2046.c

#include <REGX52.H>

sbit XPT2046_CS=P3^5;
sbit XPT2046_DCLK=P3^6;
sbit XPT2046_DIN=P3^4;
sbit XPT2046_DOUT=P3^7;

unsigned int XPT2046_ReadAD(unsigned char Command)
{
	unsigned char i;
	unsigned int ADValue=0;
	XPT2046_DCLK=0;
	XPT2046_CS=0;
	
	for(i=0;i<8;i++)
	{
		XPT2046_DIN=Command&(0x80>>i);
		XPT2046_DCLK=1;
		XPT2046_DCLK=0;
	}
	for(i=0;i<16;i++)
	{
		XPT2046_DCLK=0;
		XPT2046_DCLK=1;
		if(XPT2046_DOUT){ADValue|=(0x8000>>i);}
	}
	XPT2046_CS=1;
	if(Command&0x08)
	{
		return ADValue>>8;
	}
	else
	{
		return ADValue>>4;
	}
}
}

这里再讲一下命令字怎么写

S就是起始位,给1;A2A1A0是地址,选择通道;MODE就是模式选择位,=0是12位模式,=1是8位模式;SER/DFR也是选择模式,=1是单端模式,=0是差分模式,我们在这用单端模式;PD0和PD1表示掉电和内部参考电压配置的关系,若为11,处于供电状态,若为00,处于低功率模式(当PD1为0时关闭内部参考电压源,为1时打开,内部参考源作用即假设原本测量值是从0-5V,接到这就是2.5-5V)

在这里我们给1 A2 A1 A0 1 1 0 0,A2A1A0的选择要看下图

下图只看前面部分,A2A1A0控制测哪的电压

为了方便写代码,我们把上面这些值给宏定义,这里要根据开发板的原理图对应上图,以及前面教的命令字写出来,因为是要外部调用,所以写在.h文件里 

 我们定义不同的命令字,一个是8位,一个是12位,方便后面选择

8位是0-255,12位是0-4096,更精细

#ifndef __XPT0246_H_
#define __XPT0246_H_

#define XPT2046_XP_8       0X9C
#define XPT2046_YP_8        0XDC
#define XPT2046_VBAT_8        0XAC
#define XPT2046_AUX_8        0XEC

#define XPT2046_XP_12       0X94
#define XPT2046_YP_12       0XD4
#define XPT2046_VBAT_12       0XA4
#define XPT2046_AUX_12       0XE4


unsigned int XPT2046_ReadAD(unsigned char Command);


#endif

因为AUX接到了一个接口上,所以这里我们不读,只读其他三个

//main.c

#include <REGX52.H>
#include " Delay.h"
#include " LCD1602.h"
#include " XPT2046.h"

unsigned int ADValue;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADJ NTC RG");
	while(1)
	{
 		ADValue=XPT2046_ReadAD(XPT2046_XP_8);
		LCD_ShowNum(2,1,ADValue,3);
 		ADValue=XPT2046_ReadAD(XPT2046_YP_8);
		LCD_ShowNum(2,5,ADValue,3);
 		ADValue=XPT2046_ReadAD(XPT2046_VBAT_8);
		LCD_ShowNum(2,9,ADValue,3);
		Delay(10);
	}
}

这里我需要把DS18B20拔掉才能显示正常,暂时还未找到原因 

#include <REGX52.H>
#include " Delay.h"
#include " LCD1602.h"
#include " XPT2046.h"

unsigned int ADValue;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADJ  NTC  RG");
	while(1)
	{
 		ADValue=XPT2046_ReadAD(XPT2046_XP_8);
		LCD_ShowNum(2,1,ADValue,3);
 		ADValue=XPT2046_ReadAD(XPT2046_YP_8);
		LCD_ShowNum(2,6,ADValue,3);
 		ADValue=XPT2046_ReadAD(XPT2046_VBAT_8);
		LCD_ShowNum(2,11,ADValue,3);
		Delay(10);
	}
}

 这样就可以调节我们电路板上的电阻,然后会把阻值通过AD转换后输出在LCD上

GR是光敏电阻,NTC是热敏电阻,AD1(ADJ)是可调电阻

二、 DA数模转换

接下是PWM,因为跟之前写过的直流电机调速原理是一样的,所以我们复制过来创建一个新的工程

首先是更改接口

sbit DA=P2^1;

然后是更改命名,可以点这里一键替代

然后把关于按键的部分删掉,在主函数里实现一个呼吸灯的效果

#include <REGX52.H>
#include " Delay.h"
#include " Key.h"
#include " Nixie.h"
#include " Timer0.h"

sbit DA=P2^1;

unsigned char Counter,Compare;
unsigned char i;

void main()
{

	Timer0_Init();
	while(1)
	{
		for(i=0;i<100;i++)
		{
			Compare=i;
			Delay(10);
		}
		for(i=100;i>0;i--)
		{
			Compare=i;
			Delay(10);
		}
  }
}
void Timer0_Routine() interrupt 1
{
	Key_Loop();
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter%=100;
	if(Counter<Compare)
	{
		DA=1;
	}
	else
	{
		DA=0;
	}
}

其他部分都不需要改,这样就实现了呼吸灯的效果。

相关文章:

  • 完美解决ElementUI中树形结构table勾选问题
  • k8s环境部署
  • 算法每日一练 (10)
  • ai智能语音机器人对我们生活有什么影响
  • OpenAI智能体初探:使用 OpenAI Responses API 在 PDF 中实现检索增强生成(RAG)
  • 自然语言处理:文本聚类
  • 202250311-WINDOWS本地4G显存Docker运行vLLM
  • 垂起固定翼+多旋翼+自组网:无人机中低空一体化组网技术详解
  • 平时作业
  • 头歌java课程实验(Java面向对象 - 封装、继承和多态的综合练习)
  • C/C++都有哪些开源的Web框架?
  • 【软件】免费的PDF全文翻译软件,能保留公式图表的样式
  • 鲸鱼算法WOA对风电场风电机组一次二次调频参数进行全局最优辨识,二次调频参数辩识matlab/simulink,也可进一步修改成一次调频参数辩识
  • Nginx 限流功能:原理、配置与应用
  • talib编译whl文件通不过问题
  • i18n的替换处理
  • 【从零开始学习计算机科学】数据库系统(十一)云数据库、NoSQL 与 NewSQL
  • 智能化水利监管:无人机视频在违章行为识别中的应用
  • 基于java(springboot+mybatis)汽车信息管理系统设计和实现以及文档
  • 5秒学会excel中序号列自动增加,不是拖动,图解加说明,解决序号自增多了手拖太累
  • 假冒政府机构账号卖假货?“假官号”为何屡禁不绝?媒体调查
  • 浙江理工大学传播系原系主任刘曦逝世,年仅44岁
  • 中国驻美大使:远离故土的子弹库帛书正随民族复兴踏上归途
  • 梅花奖在上海|湘剧《夫人如见》竞梅,长沙文旅来沪推广
  • 在本轮印巴冲突的舆论场上也胜印度一筹,巴基斯坦靠什么?
  • 日本一季度实际GDP环比下降0.2%