本帖最后由 guizhong282 于 2014-3-10 23:16 编辑
/*------------------------------------------------------------------------------------------------------------------------------------------*/ /*--*************************功能: 【ADS1115单端输入检测电压】********************--*/
/*--*************************CPU: 【STC12C5A60S2】*******************************--*/
/*--*************************ADC芯片:【ADS1115(2差分输入或4单端输入)】***********--*/
/*--*************************液晶: 【LCD1602】************************************--*/
/*--*************************ADC与单片机连接:【SCL:P1.0 , SDA:P1.1】*******************--*/
/*--*************************检测范围:【0.00~4.99V】*********************************--*/
/*----------------------------------------------------------------------------------------------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define _Nop() _nop_()
/*------------------------以下为LCD1602显示模块端口定义及函数声明-----------------------*/
sbit lcd_rs_port = P2^5; /*定义LCD控制端口*/
sbit lcd_rw_port = P2^6;
sbit lcd_en_port = P2^7;
#define lcd_data_port P0
unsigned char num_char_table[] = {"0123456789ABCDEF -"};
unsigned char Lcd_Dis1_table[] = {"Volt: V "}; //电压显示框架
unsigned char pos_char_table[] = {" . V "}; //电压显示位置
void lcd_delay(uchar ms); //LCD1602 延时
void lcd_busy_wait(); //LCD1602 忙等待
void lcd_command_write(uchar command); //LCD1602 命令字写入
void lcd_system_reset(); //LCD1602 初始化
void lcd_char_write(uchar x_pos,y_pos,lcd_dat); //LCD1602 字符写入
void lcd_bad_check(); //LCD1602 坏点检查
void Num_to_Disp(uint Num); //LCD1602 数据处理
void LcdDisp(uint num); //LCD1602 数据显示
void delay_1ms(uchar x); //LCD1602 延时1ms
/*------------------------以下为ADS1115模块端口定义及函数声明--------------------------*/
sbit SCL = P3^1;
sbit SDA = P3^0;
#define TRUE 1
#define FALSE 0
unsigned int Config;
unsigned char Writebuff[4],Readbuff[3];
unsigned int Result[2];
int D_ADS; //转换的数字量
#define Accuracy 32768 //定义ADC精度,ADS1115单端输入时15位
float VCC = 4.096; //VCC,电压参考值
#define ADDRESS_0 0x90 //ADDR PIN ->GND
#define ADDRESS_1 0x92 //ADDR PIN ->VDD
#define ADDRESS_2 0x94 //ADDR PIN ->SDA
#define ADDRESS_3 0x96 //ADDR PIN ->SCL
/************POINTER REGISTER*****************/
#define Pointer_0 0x00 //Convertion register
#define Pointer_1 0x01 //Config register
#define Pointer_2 0x02 //Lo_thresh register
#define Pointer_3 0x03 //Hi_thresh register
/************CONFIG REGISTER*****************/
#define OS_0 0x0000
#define OS_1 0x8000
#define MUX_0 0x0000 //AINp=AIN0, AINn=AIN1
#define MUX_1 0x1000 //AINp=AIN0, AINn=AIN3
#define MUX_2 0x2000 //AINp=AIN1, AINn=AIN3
#define MUX_3 0x3000 //AINp=AIN2, AINn=AIN3
#define MUX_4 0x4000 //AINp=AIN0, AINn=GND
#define MUX_5 0x5000 //AINp=AIN1, AINn=GND
#define MUX_6 0x6000 //AINp=AIN2, AINn=GND
#define MUX_7 0x7000 //AINp=AIN3, AINn=GND
#define PGA_0 0x0000 //FS=6.144V
#define PGA_1 0x0200 //FS=4.096V
#define PGA_2 0x0400 //FS=2.048V
#define PGA_3 0x0600 //FS=1.024V
#define PGA_4 0x0800 //FS=0.512V
#define PGA_5 0x0A00 //FS=0.256V
#define PGA_6 0x0C00 //FS=0.256V
#define PGA_7 0x0E00 //FS=0.256V
#define MODE_0 0x0000
#define MODE_1 0x0100
#define DR_0 0x0000 //Data Rate = 8
#define DR_1 0x0020 //Data Rate = 16
#define DR_2 0x0040 //Data Rate = 32
#define DR_3 0x0060 //Data Rate = 64
#define DR_4 0x0080 //Data Rate = 128
#define DR_5 0x00A0 //Data Rate = 250
#define DR_6 0x00C0 //Data Rate = 475
#define DR_7 0x00E0 //Data Rate = 860
#define COMP_MODE_0 0x0000
#define COMP_MODE_1 0x0010
#define COMP_POL_0 0x0000
#define COMP_POL_1 0x0008
#define COMP_LAT_0 0x0000
#define COMP_LAT_1 0x0040
#define COMP_QUE_0 0x0000
#define COMP_QUE_1 0x0001
#define COMP_QUE_2 0x0002
#define COMP_QUE_3 0x0003
//*************ADDR Initial********************/
#define ADDRESS ADDRESS_0 //ADDR PIN ->GND
#define ADDRESS_W ADDRESS|0x00 //写地址
#define ADDRESS_R ADDRESS|0x01 //读地址
/*************Config Initial*********************/
#define OS OS_1
#define MUX_A0 MUX_4 //AINp=AIN0, AINn=GND
#define MUX_A1 MUX_5 //AINp=AIN1, AINn=GND
#define MUX_A2 MUX_6 //AINp=AIN2, AINn=GND
#define MUX_A3 MUX_7 //AINp=AIN3, AINn=GND
#define MUX_D0 MUX_0 //AINp=AIN0, AINn=AIN1
#define MUX_D1 MUX_1 //AINp=AIN0, AINn=AIN3
#define MUX_D2 MUX_2 //AINp=AIN1, AINn=AIN3
#define MUX_D3 MUX_3 //AINp=AIN2, AINn=AIN3
#define PGA PGA_1 //FS=4.096V
#define MODE MODE_1 //Continuous conversion mode
#define DR DR_7 //Data Rate = 860
#define COMP_QUE COMP_QUE_3
void Delay_us_15 (void);
void Delay_ms_1 (void); //功 能:延时
void Start(void); //功 能:完成IIC的起始条件操作
void Stop(void); //功 能:完成IIC的终止条件操作
void ACK(void); //功 能:完成IIC的主机应答操作
void NACK(void); //功 能:完成IIC的主机无应答操作
unsigned char Check(void);//功 能:检查从机的应答操作
void Write_1_Byte(unsigned char DataByte); //写 1个字节
unsigned char Write_N_Byte(unsigned char *writebuffer,unsigned char n); //写 N个字节
unsigned char Read_1_Byte(void); //读 1个字节
void Read_N_Byte(unsigned int *readbuff,unsigned char n); //读 N个字节
void InitADS1115(bit S_MUX_0, bit S_MUX_1); //ADS1115初始化
void WriteWord(void); //写
void ReadWord(void); //读
unsigned int ADS1115(bit S_MUX_0, bit S_MUX_1); //ADS1115取值
/*--------------------------------------------------------------------------------------------------------------------------------*/
/*--*********************************【 主函数 】*******************************--*/
/*-------------------------------------------------------------------------------------------------------------------------------*/
void main()
{
unsigned int result;
lcd_system_reset(); //LCD1602 初始化
//lcd_bad_check(); //LCD1602 坏点检查
while(1)
{
result = ADS1115(0,0); //ADS1115取值_AIN0
//result = ADS1115(0,1); //ADS1115取值_AIN1
//result = ADS1115(1,0); //ADS1115取值_AIN2
//result = ADS1115(1,1); //ADS1115取值_AIN3
LcdDisp(result); //LCD1602显示电压值
}
}
/*--------------------------------------------------------------------------------------------------------------------------------*/
/*--****************************************************************************--*/
/*-------------------------------------------------------------------------------------------------------------------------------*/
void LcdDisp(uint num) /************LCD显示*************/
{
uint i=0;
for (i=0;i<16;i++)
{
lcd_char_write(i,0,Lcd_Dis1_table); //显示框架
}
Num_to_Disp(num);
for(i = 6; i < 13; i++)
{
lcd_char_write(i,0,pos_char_table); //显示电压
}
delay_1ms(100);
}
void Num_to_Disp(uint Num) /******LCD显示数据处理*****/ //Start_1-Over_1:显示电压值,Start_2-Over_2:显示ADS1115输出数值
{
float NUM; //Start_1
int xx, yy, zz, zzz,zzzz;
if(Num>0x7fff) //单通道显示负数
{
Num = ~Num + 1;
pos_char_table[6] = num_char_table[17]; //显示负号
}
else
{
pos_char_table[6] = num_char_table[16];
}
;
NUM = (Num / (float)Accuracy) * VCC; //ADS1115取值 = Accuracy × (Vin / VCC)
xx = (int)NUM;
yy = (int)((NUM - (float)(xx)) * 10);
zz = (int)((NUM - (float)(xx)) * 100)%10;
zzz = (int)((NUM - (float)(xx)) * 1000)%10;
zzzz = (int)((NUM - (float)(xx)) * 10000)%10;
//pos_char_table[6] = num_char_table[xx / 10]; //电压值十位
pos_char_table[7]= num_char_table[xx % 10]; //电压值个位
pos_char_table[9]= num_char_table[yy]; //电压值小数点后一位
pos_char_table[10]= num_char_table[zz]; //电压值小数点后两位
pos_char_table[11]= num_char_table[zzz]; //电压值小数点后三位
pos_char_table[12]= num_char_table[zzzz]; //电压值小数点后四位 //Over_1
/* pos_char_table[6] = num_char_table[Num / 10000]; //Start_2
pos_char_table[7] = num_char_table[(Num % 10000) / 1000];
pos_char_table[8]= num_char_table[((Num % 10) % 1000) / 100];
pos_char_table[9]= num_char_table[(Num / 10) % 10];
pos_char_table[10]= num_char_table[Num % 10]; //Over_2 */
}
void delay_1ms(uchar x) /*******1MS为单位的延时程序******/
{
uchar j;
while(x--){
for(j=0;j<125;j++)
{;}
}
}
/*------------------------以下为ADS1115模块端口函数定义--------------------------*/
void Delay_us_15 (void) /*延时程序*/
{
unsigned char i;
for(i = 0;i < 10;i++)
_nop_();
}
void Delay_ms_1 (void)
{
unsigned char i;
for(i = 100;i > 0;i--) _nop_();
}
///*******************************************
//函数名称:Start
//功 能:完成IIC的起始条件操作
//参 数:无
//返回值 :无
//********************************************/
void Start(void)
{
SCL=1;
SDA=1;
Delay_us_15 ();
SDA=0;
Delay_us_15 ();
SCL=0;
Delay_us_15 ();
}
//
///*******************************************
//函数名称:Stop
//功 能:完成IIC的终止条件操作
//参 数:无
//返回值 :无
//********************************************/
void Stop(void)
{
SDA=0;
Delay_us_15 ();
SCL=1;
Delay_us_15 ();
SDA=1;
Delay_us_15 ();
}
///*******************************************
//函数名称:ACK
//功 能:完成IIC的主机应答操作
//参 数:无
//返回值 :无
//********************************************/
void ACK(void)
{ // uchar i=0;
SDA=0;
_nop_(); _nop_();
SCL=1;
// for(i=0;i<100;i++)
Delay_us_15 ();
SCL=0;
_nop_(); _nop_();
_nop_(); _nop_();
SDA=1;
Delay_us_15 ();
}
//*******************************************
//函数名称:NACK
//功 能:完成IIC的主机无应答操作
//参 数:无
//返回值 :无
//********************************************/
void NACK(void)
{
SDA=1;
_nop_(); _nop_();
SCL=1;
Delay_us_15 ();
SCL=0;
_nop_(); _nop_();
SDA=0;
Delay_us_15 ();
}
//**********检查应答信号函数******************/
///*如果返回值为1则证明有应答信号,反之没有*/
///*******************************************
//函数名称:Check
//功 能:检查从机的应答操作
//参 数:无
//返回值 :从机是否有应答:1--有,0--无
//********************************************/
unsigned char Check(void)
{
unsigned char slaveack;
SDA=1;
_nop_(); _nop_();
SCL=1;
_nop_(); _nop_();
_nop_(); _nop_();
slaveack = SDA; //读入SDA数值
SCL=0;
Delay_us_15 ();
if(slaveack) return FALSE;
else return TRUE;
}
/***************Write a Byte****************/
void Write_1_Byte(unsigned char DataByte)
{
int i;
for(i=0;i<8;i++)
{
if(DataByte&0x80) //if((DataByte<<i)&0x80)
SDA=1;
else
SDA=0;
Delay_us_15 ();
SCL=1;
Delay_us_15 ();
SCL=0;
Delay_us_15 ();
DataByte <<= 1;
}
SDA=1;
_nop_();
}
/***************Write N Byte****************/
unsigned char Write_N_Byte(unsigned char *writebuffer,unsigned char n)
{
int i;
for(i=0;i<n;i++)
{
Write_1_Byte(*writebuffer);
if(Check()) //检查从机是否应答
{
writebuffer ++;
}
else
{
Stop(); //未应答则结束发送
return FALSE;
}
}
Stop();
return TRUE;
}
//***************Read a Byte****************/
unsigned char Read_1_Byte(void)
{
unsigned char data_Value = 0, FLAG, i;
for(i=0;i<8;i++)
{
// SDA=1;
// Delay_us_15 ();
SCL=1;
Delay_us_15 ();
FLAG=SDA;
data_Value <<= 1;
if( FLAG)
data_Value |= 0x01;
SCL=0;
Delay_us_15 ();
}
return data_Value;
}
//***************Read N Byte****************/
void Read_N_Byte(unsigned int*readbuff, unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
readbuff=Read_1_Byte();
if(i==n-1)
NACK(); //不连续读字节
else
ACK(); //连续读字节
}
Stop();
}
//*****************初始化******************/
void InitADS1115(bit S_MUX_0, bit S_MUX_1)
{
if (S_MUX_0 == 0 && S_MUX_1 == 0) //AIN0 2014年3月8日21:41:50修改MUX_A0 成差分A0A1输入
Config = OS+MUX_D0+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 0 && S_MUX_1 == 1) //AIN1
Config = OS+MUX_A1+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 1 && S_MUX_1 == 0) //AIN2
Config = OS+MUX_A2+PGA+DR+COMP_QUE+MODE;
if (S_MUX_0 == 1 && S_MUX_1 == 1) //AIN3
Config = OS+MUX_A3+PGA+DR+COMP_QUE+MODE;
Writebuff[0]=ADDRESS_W;
Writebuff[1]=Pointer_1;
Writebuff[2]=Config/256;
Writebuff[3]=Config%256;
Readbuff[0]=ADDRESS_W;
Readbuff[1]=Pointer_0;
Readbuff[2]=ADDRESS_R;
}
//***************Write a Word***********************/
void WriteWord(void)
{
int t;
Start(); //写入4个字节
do
{
t=Write_N_Byte(Writebuff,4);
}while(t==0);
}
//***************Read Word***********************/
void ReadWord(void)
{
int t;
Start(); //写入2个字节
do
{
t=Write_N_Byte(Readbuff,2);
}while(t==0);
Start(); //写入2个字节
do
{
t=Write_N_Byte(&Readbuff[2],1);
}while(t==0);
Read_N_Byte(Result,2); //读出2个字节
}
//***************ADS1115********************/
unsigned int ADS1115(bit S_MUX_0, bit S_MUX_1)
{
InitADS1115(S_MUX_0, S_MUX_1);
WriteWord();
Delay_ms_1();
ReadWord();
D_ADS=Result[0]*256+Result[1]; //转换的数字量
return D_ADS;
}
|