STC51 单片机实例之 38 用 PCF8591T 实现 DA 功能(正弦波)
1#
[您是本帖第 812 位阅读者]
/********************************************************************
* 文件名 : PCF8591T 做 DA 实验.c
* 描述
: 我们单片机去控制 PCF8591T 去实现 DA 功能。
这个代码也要在示波器上才能观测到,DA 输出一个正弦波。
* 可以用示波器测到正弦波
***********************************************************************/
#include
#include
#define PCF8591 0x90
//PCF8591 地址
c
d
E
-
// 此表为 LED 的字模
A
b
unsigned
=
{ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x88,0x83,0xC6,0xA1,0x86,0xbf,0xc7,0x8c,0
xc1, 0xff, 0xf7 };
2
Hidden _ (20)
Disp_Tab[]
L
char
// 0
P
6
7
1
U
8
9
3
4
5
LedOut[8];
idata D[32];
unsigned char AD_CHANNEL;
unsigned long xdata
unsigned int
// 128 点正弦波样本表
unsigned char code auc_SinParam[128] = {
64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,109,111,113,115,117,118,120,121,
123,124,125,126,126,127,127,127,127,127,127,127,126,126,125,124,123,121,120,118,
117,115,113,111,109,106,104,102,99,96,94,91,88,85,82,79,76,73,70,67,64,60,57,54,51,48,
45,42,39,36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,1,0,0,0,0,0,0,0,1,1,2,3,4,6,
7,9,10,12,14,16,18,21,23,25,28,31,33,36,39,42,45,48,51,54,57,60};
/*******************************************************************
DAC 变换, 转化函数
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
{
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(c);
if(ack==0)return(0);
SendByte(Val);
if(ack==0)return(0);
//启动总线
//发送器件地址
//发送控制字节
//发送 DAC 的数值
Stop_I2c();
return(1);
}
//结束总线
/*******************************************************************
ADC 发送字节[命令]数据函数
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
{
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(c);
if(ack==0)return(0);
Stop_I2c();
return(1);
}
//启动总线
//发送器件地址
//发送数据
//结束总线
/*******************************************************************
ADC 读字节数据函数
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
{ unsigned char c;
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
c=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(c);
//启动总线
//发送器件地址
//读取数据 0
//发送非就答位
//结束总线
}
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(unsigned char i)//1ms 延时
{
unsigned char x,j;
for(j=0;j
}
//******************************************************************/
main()
{
unsigned char i=0;
while(1)
{/********以下 AD-DA 处理*************/
switch(AD_CHANNEL)
{
case 0: ISendByte(PCF8591,0x41);
D[0]=IRcvByte(PCF8591)*2;
break;
//ADC0 模数转换 1
case 1: ISendByte(PCF8591,0x42);
D[1]=IRcvByte(PCF8591)*2;
break;
case 2: ISendByte(PCF8591,0x43);
//ADC1 模数转换 2
D[2]=IRcvByte(PCF8591)*2;
break;
//ADC2 模数转换 3
case 3: ISendByte(PCF8591,0x40);
D[3]=IRcvByte(PCF8591)*2;
break;
//ADC3 模数转换 4
case 4: DACconversion(PCF8591,0x40, D[4]/4); //DAC
数模转换
break;
}
if(++AD_CHANNEL>4) AD_CHANNEL=0;
/********以下将 AD 的值送到 LED 数码管显示*************/
D[4] = auc_SinParam[i++]*2;
Delay_1ms(5);
if(i==128) i=0;
}
}
/************************* 此 部 分 为 I2C 总 线 的 驱 动 程 序
*************************************/
#include
#include
#include
#define NOP()
_Nop()
#define
_nop_()
_nop_()
/* 定义空指令 */
/*定义空指令*/
SCL=P1^5;
//I2C 时钟
sbit
sb