1、单片机:STC89C52
2、AD/DA介绍
(1)AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可操作的数字信号
(2)DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号
(3)AD/DA转换打开了计算机与模拟信号的大门,极大的提高了计算机系统的应用范围,也为模拟信号数字化处理提供了可能
3、硬件电路模型

(1)AD转换通常有多个输入通道,用多路选择开关连接至AD转换器,以实现AD多路复用的目的,提高硬件利用率
(2)AD/DA与单片机数据传送可使用并口(速度快、原理简单),也可使用串口(接线少、使用方便)
(3)可将AD/DA模块直接集成在单片机内,这样直接写入/读出寄存器就可进行AD/DA转换,单片机的IO口可直接复用为AD/DA的通道
4、硬件电路



5、运算放大器
(1)运算放大器(简称“运放”)是具有很高放大倍数的放大电路单元。内部集成了差分放大器、电压放大器、功率放大器三级放大电路,是一个性能完备、功能强大的通用放大电路单元,由于其应用十分广泛,现已作为基本的电路元件出现在电路图中
(2)运算放大器可构成的电路有:电压比较器、反相放大器、同相放大器、电压跟随器、加法器、积分器、微分器等
(3)运算放大器电路的分析方法:虚短、虚断(负反馈条件下)

6、运放电路


7、DA原理


8、AD原理

9、AD/DA性能指标
(1)分辨率:指AD/DA数字量的精细程度,通常用位数表示。例如,对于5V电源系统来说,8位的AD可将5V等分为256份,即数字量变化最小一个单位时,模拟量变化5V/256=0.01953125V,所以,8位AD的电压分辨率为0.01953125V,AD/DA的位数越高,分辨率就越高
(2)转换速度:表示AD/DA的最大采样/建立频率,通常用转换频率或者转换时间来表示,对于采样/输出高速信号,应注意AD/DA的转换速度
10、XPT2046

11、XPT2046时序

12、AD模数转换
(1)main.c
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.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);
Delay(10);
ADValue=XPT2046_ReadAD(XPT2046_YP_8);
LCD_ShowNum(2,5,ADValue,3);
Delay(10);
ADValue=XPT2046_ReadAD(XPT2046_VBAT_8);
LCD_ShowNum(2,9,ADValue,3);
Delay(10);
}
}
(2)XPT2046.c
/*头文件*/
#ifndef __XPT2046_H__
#define __XPT2046_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
/*源文件*/
#include <REGX52.H>
#include "Delay.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 int ADValue=0;
unsigned char i;
XPT2046_CS=0;
XPT2046_DCLK=0;
for(i=0;i<8;i++)
{
XPT2046_DIN=Command&(0x80>>i);
XPT2046_DCLK=1;
Delay(1);
XPT2046_DCLK=0;
}
for(i=0;i<16;i++)
{
XPT2046_DCLK=1;
Delay(1);
XPT2046_DCLK=0;
if(XPT2046_DOUT){ADValue|=(0x8000>>i);}
}
XPT2046_CS=1;
if(Command&0x08)
{
return ADValue>>8;
}
else
{
return ADValue>>4;
}
}
(3)Delay.c
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
(4)LCD1602.c
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
13、DA数模转换
(1)main.c
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
sbit DA=P2^1;
unsigned char Counter,Compare;
unsigned char i;
void main()
{
Timer0_Init();
Compare=0;
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
{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100;
if(Counter<Compare)
{
DA=1;
}
else
{
DA=0;
}
}
(2)Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,100微秒@11.0592MHz
* @param 无
* @retval 无
*/
void Timer0_Init(void) //100微秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
T0Count++;
if(T0Count==1000)
{
T0Count=0;
}
}
*/
(3)Delay.c
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}

2513

被折叠的 条评论
为什么被折叠?



