do利用STC89C58内部E2PROM 存储N组电压 12Bit DA 16bit AD模块tl
#include //""表示引用自保存目录; #include #include "16bit diyabiao 4_1.h"
#define uchar unsigned char
#define uint unsigned int uint tem1,result ;//送显示电压临时数据; uchar num1,KEY; //定时器1时基,返回健值; uchar KEY_read();
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit led=P1^4;//运行指示;
sbit k5=P1^5;
sbit k6=P1^6;
sbit k7=P1^7;
sbit P20 = P2 ^ 4; sbit P21 = P2 ^ 5; sbit P22 = P2 ^ 6; sbit P23 = P2 ^ 7; sbit CS =P2^0; //输出DAC片选信号 sbit CLK=P2^3; //输出DAC时钟
sbit SDI=P2^2; //输出DAC数据
sbit LD=P2^1; //输出数/模转换过程启动信号 unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x27,0x7f,0x6f}; //共阴数码驱动
void delay1(uchar z) //1ms 延时处理 {
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--); }
void display(uint k) //数码管显示函数;依次分离各值; {
P0 = 0xff;
P0 = dispcode[k % 10]; //个位
P23 = 0;
delay1(1);
P23 = 1;
P0 = 0xFF;
P0 = dispcode[k / 10 % 10]; //十位
P22 = 0;
delay1(1);
P22 = 1;
P0 = 0xFF;
P0 = dispcode[k / 100 % 10]; //百位
P21 = 0;
delay1(1);
P21 = 1;
P0 = 0xFF;
P0 =( dispcode[k/ 1000 % 10])|0x80; //千位 ,固定显示一个小数点;
P20 = 0;
delay1(1);
P20 = 1;
}
/******初始化
DAC7611***********///////////////***********************************/
void init_da(void) {
LD=0; // 装载引脚置低 ;
CS=1; //片选置高 ;
CLK=1; //时钟置高 ;
SDI=0;
}
/*****时钟脉冲函数***********/ void clock(void)
{
CLK=0;
_nop_(); _nop_();
CLK=1; //一个时钟脉冲
_nop_(); _nop_(); }
/******DAC7611转换***************/
void DAC_7611(uint vol) {
uint i,j;
vol<<=4;
LD=1; //装载置高
_nop_();
CS=0; //片选拉低,准备转换
for(i=0;i<12;i++)
{
j=vol;
SDI=j&0x8000;
clock();
vol<<=1;
}
CLK=1; // 输出时钟置高
_nop_();
CS=1; //片选引脚CS置高
_nop_();
LD=0; //装载引脚LD置低启动数模转换
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
//延时使输出模拟电压达到稳定
LD=1; //LD置高
}
//----------------ADS1110地址、配置字-----------------// #define ADS1110_WR_ADDRESS 0x90 //1001 000 0 写
#define ADS1110_RD_ADDRESS 0x91 //1001 000 1 读
#define ADS1110_CONFIG_REG 0x8C //连续转换模式,16bit精度,PGA=1
#define uchar unsigned char
#define uint unsigned int
sbit ADS1110_SDA = P3^4; //模拟I2C数据传输位
sbit ADS1110_CLK = P3^5; //模拟I2C时钟控制位
/*******************************************************************************
*******************
名称: ads1110Start(void)
功能: ADS1110 I2C Start
********************************************************************************
******************/
void ads1110Start(void)
{
ADS1110_SDA=1;
_nop_(); _nop_(); _nop_();_nop_(); _nop_();
ADS1110_CLK=1;
_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
ADS1110_SDA=0;
_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); }
/*******************************************************************************
*******************
名称: ads1110Stop(void)
功能: ADS1110 I2C Stop
********************************************************************************
******************/
void ads1110Stop(void)
{
ADS1110_SDA=0;
_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();
ADS1110_CLK=1; // -----------结束I2C总线.
_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
ADS1110_SDA=1;
_nop_(); _nop_(); _nop_();
}
/*******************************************************************************
*******************
名称: waitAck(void)
功能: ADS1110 I2C 等待ack
********************************************************************************
******************/
uchar waitAck(void)
{
uint i=0;
ADS1110_CLK=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
while((ADS1110_SDA==1)&(i<500))
i++;
ADS1110_CLK=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
return 0x00;
}
/*******************************************************************************
*******************
名称: void sendAck(void)
功能: 向ADS1110 I2C 发送 ack
********************************************************************************
******************/
void sendAck(void)
{
ADS1110_SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
ADS1110_CLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
ADS1110_CLK=0;
}
/*******************************************************************************
*******************
名称: void sendNotAck(void)
功能: 向ADS1110 I2C 不发送 ack
********************************************************************************
******************/
void sendNotAck(void)
{
ADS1110_SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
ADS1110_CLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
ADS1110_CLK=0;
}
/*******************************************************************************
*******************
名称: void ads1110SendByte(BYTE sendData) 功能: 向ADS1110 I2C 发送1个字节
********************************************************************************
******************/
void ads1110SendByte(uchar sendData) {
uchar i,temp;
temp=sendData;
for(i=0;i<8;i++)
{
temp=temp<<1;
ADS1110_CLK=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
ADS1110_SDA=CY;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
ADS1110_CLK=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
ADS1110_CLK=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
ADS1110_SDA=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
/******************************************************************************* *******************
名称: uchar ads1110ReceiveByte(void)
功能: ADS1110 I2C 接收1个字节
******************************************************************************** ******************/
uchar ads1110ReceiveByte(void)
{
uchar i,k;
ADS1110_CLK=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
ADS1110_SDA=1;
_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();
for(i=0;i<8;i++)
{
ADS1110_CLK=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
k=(k<<1)|ADS1110_SDA;
ADS1110_CLK=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_();
return k;
}
/*******************************************************************************
*******************
名称: void ads1110Config(void)
功能: 对ADS1110进行配置
********************************************************************************
******************/
void ads1110Config(void)
{
ads1110Start();
ads1110SendByte(ADS1110_WR_ADDRESS);
waitAck();
ads1110SendByte(ADS1110_CONFIG_REG);
waitAck();
ads1110Stop();
}
/*******************************************************************************
*******************
名称: 读取ADS1100数据子程序
功能:
********************************************************************************
******************/
uint RD_ADS()
{
uchar data temp00;
uint W_B1byte_low,W_B1byte_high,W_B1_word;
ads1110Start();
ads1110SendByte(ADS1110_RD_ADDRESS);
temp00=waitAck();
if(temp00)
{
W_B1byte_high=ads1110ReceiveByte();
sendAck();
W_B1byte_low=ads1110ReceiveByte();
sendAck();
temp00=ads1110ReceiveByte();
ads1110Stop();
W_B1_word= (W_B1byte_high<<8)+ W_B1byte_low;
if(W_B1_word>0x7fff)
W_B1_word=0;
return W_B1_word;
}
else return 0x0000; }
/*******************************************************************************
/*******************************************************************************
*******************
名称: 定时器0 LED显示程序
功能:
********************************************************************************
******************/
void T0_init(void)
{
TMOD=0x11;//设置T0,T1为16位 计数模式;
TH0=(65536-9216)/256;
TL0=(65536-9216)%256;
TH1=(65536-45872)/256; //50ms
TL1=(65536-45872)%256;
EA=1;//开中断
ET0=1;//允许定时器中断
TR0=1;//启动定时器/计数器0
ET1=1;
TR1=1;
}
//************定时器T0中断程序****************** void clock_T0() interrupt 1
{
TH0=(65536-4500)/256; //9216
TL0=(65536-4500)%256;
DAC_7611(tem1);
result=(RD_ADS()/16+0x04)*4;
display(result-4); //仅做显示 ; //ADC输入端实际电压值换算; }
//************定时器T1中断程序**//返回各健值;**************** void clock_T1() interrupt 3
{
TH1=(65536-45872)/256; //50ms初值;
TL1=(65536-45872)%256;
num1++;
if(num1%20==0)
{
led=~led;
}
if(k1==0) //k1
{
delay1(3);
if (k1==0)
{ KEY=1;
}
}
if(k2==0) //k2
{
delay1(3);
if (k2==0)
{ KEY=2;
}
}
if(k3==0) //k3
{
delay1(3);
if (k3==0)
{ KEY=3;
}
}
if(k4==0) //k4
{
delay1(3);
if (k4==0)
{ KEY=4;
}
}
if(k5==0) //k5
{
delay1(3);
if (k5==0)
{ KEY=5;
}
}
if(k6==0) //k6
{
delay1(3);
if (k6==0)
{ KEY=6;
}
}
if(k7==0) //k7
{
delay1(3);
if (k7==0)
{ KEY=7;
}
}
}
void delay(void)
{
unsigned char m,n;
for(m=5000;m>0;m--)
for(n=1000;n>0;n--);
}
void main()
{
ads1110Config();
init_da();
T0_init();
/*sector_erase(0x8000); //清第1扇区;
sector_erase(0x8200); //清第2扇区;
sector_erase(0x8400); //...
sector_erase(0x8600);
eeprom_write_int(0x8000,125); //固定位置写入初始数据... eeprom_write_int(0x8200,1250); eeprom_write_int(0x8400,250); eeprom_write_int(0x8600,2250); */
while(1)
{
uchar count;
switch(KEY)
{
case 1: tem1=eeprom_read_int(0x8000);//DAC_7611(tem1) ;
count=1;
break;
case 2: tem1=eeprom_read_int(0x8200);//DAC_7611(tem1);
count=2;
break;
case 3: tem1=eeprom_read_int(0x8400);//DAC_7611(tem1);
count=3;
break;
case 4: tem1=eeprom_read_int(0x8600);//DAC_7611(tem1);
count=4;
break;
// default://DAC_7611(tem1)DAC_7611(tem1);
}
if(count==1) ////////////////////////////记录count次数,判断写入的位置;
{
if(k6==0)
{ delay1(5);
if(k6==0)
{
do{ tem1=tem1+1;delay1(500);
if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k7==0)
{ delay1(5);
if(k7==0)
{
do{ tem1=tem1-1;delay1(500);if(tem1>4095)tem1=4095;
} while(k6==0);
}
}
if(k5==0)
{ delay1(5);
if(k5==0)
{ while(k5==0)
{sector_erase(0x8000);delay1(3);
eeprom_write_int(0x8000,tem1);}
}
}
} //////////////////////////////////记录count次数,判断写入的
位置1;
if(count==2) /////////////////////记录count次数,判
断写入的位置2;
{
if(k6==0)
{ delay1(5);
if(k6==0)
{
do{ tem1=tem1+1;delay1(500);if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k7==0)
{ delay1(5);
if(k7==0)
{
do{ tem1=tem1-1;delay1(500);if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k5==0)
{ delay1(5);
if(k5==0)
{ while(k5==0)
{sector_erase(0x8200);delay1(3);
eeprom_write_int(0x8200,tem1);}
}
}
} //////////////////////////////////记录count次数,判断写入的
位置2;
if(count==3) ///////////////////记录count次数,判断
写入的位置3;
{
if(k6==0)
{ delay1(5);
if(k6==0)
{
do{ tem1=tem1+1;delay1(500);if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k7==0)
{ delay1(5);
if(k7==0)
{
do{ tem1=tem1-1;delay1(500);if(tem1>4095)tem1=4095;
} while(k6==0);
}
}
if(k5==0)
{ delay1(5);
if(k5==0)
{ while(k5==0)
{sector_erase(0x8400);delay1(3);
eeprom_write_int(0x8400,tem1);}
}
}
} ////////////////////////////////////记录count次数,判断写入
的位置3;
if(count==4) //////////////////////记录count次数,
判断写入的位置4;
{
if(k6==0)
{ delay1(5);
if(k6==0)
{
do{ tem1=tem1+1;delay1(500);if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k7==0)
{ delay1(5);
if(k7==0)
{
do{ tem1=tem1-1;delay1(500);if(tem1>4095)tem1=0;
} while(k6==0);
}
}
if(k5==0)
{ delay1(5);
if(k5==0)
{ while(k5==0)
{sector_erase(0x8600);delay1(3);
eeprom_write_int(0x8600,tem1);}
}
}
} ////////////////////////////////////记录count次数,判断写入
的位置;
}
}