⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ads1218.c

📁 8通道24位AD转换器ADS1218操作函数
💻 C
字号:
/************************************************************************************/
/* ads1218-采样程序								    */
/* MCU 型号: upsd32xx								    */
/* MCU时钟频率: 2.4576 MHz							    */
/* ADS1218时钟频率: 2.4576 MHz							    */
/* 接口方式: SPI								    */
/* 开发环境: Keil C51 V7.09							    */
/* 开发日期: 2004.03.9-								    */
/* 程序编写: jl_mx								    */

/* the delay time of the flash write command   performed completely requires great than 60ms */


/************************************************************************************/


#include <absacc.h>
#include <uPSD3200.H>
#include <intrins.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtx51.h>                    /* RTX-51 functions & defines         */

#include "common.h"
#include <menu.h>
#include <ads1218.h>

void delay(unsigned int val);



//定义ads1218命令
#define		RDATA	0x01				//读最新ad转换数据
#define		RDATAC	0x03				//连续读取转换后的数据
#define		STOPC	0x0F				//停止连续读模式
#define		RREG	0x10				//两字节命令,读取寄存器内容第一字节: bit3-bit0 =0-16  ;
#define		RRAM	0x20				//两字节命令,读取ram中内容第一字节: bit3-bit0 =0-16  ;
#define		CREG	0x40				//拷贝寄存器内容到指定的ram bank中,低三位指定ram的页地址
#define		CREGA	0x48				//拷贝寄存器内容到所有的ram bank中。
#define		WREG	0x50				//2字节命令,写数据到寄存器0-15
#define		WRAM	0x60				//2字节指令,写数据到128字节的ram中
#define		RF2R	0x80				//读指定FLASH页的数据到128字节的RAM中
#define		WR2F	0xA0				//将ram中的数据写入到指定的FLASH页中
#define		CRAM	0xC0				//复制选择的ram数据到配置寄存器中,将覆盖当前的工作寄存器内容
#define		CSRAMX	0xD0				//计算指定页ram中的校验和,不包含ID,DRDY DIO
#define		CSARAMX	0xD8				//计算所有ram中的校验和,不包含ID,DRDY DIO
#define		CSREG	0xDF				//计算配置寄存器的校验和
#define		CSRAM	0xE0				//计算指定页ram中的校验和,包含所有位
#define		CSARAM	0xE8				//计算所有ram中的校验和,包含所有位
#define		CSFL	0xEC				//计算所有FLASH中的校验和,包含所有位
#define		SELFCAL	0xF0				//偏移量和增益自校准
#define		SELFOCAL	0xF1			//偏移量自校准
#define		SELFGCAL	0xF2			//增益自校准
#define		SYSOCAL		0xF3			//系统偏移量校准
#define		SYSGCAL		0xF4			//系统增益校准
#define		DSYNC		0xFC			//同步DRDY
#define		SLEEP		0xFD			//休眠模式
#define		RESET		0xFE			//复位寄存器到上电时的数据,停止连续读模式,不影响ram中的数据

typedef struct{
	uchar	adresfg;
	uchar	adresh;
	uchar	adresm;
	uchar	adresl;
}ad_reg;

typedef union	{
	long	adreslong;
	ad_reg	ADRST;
}char2long;

/*****************ads1218 配置寄存器结构*******************/
typedef	struct	adstruct{
	uchar	SETUP;
	uchar	MUX;
	uchar 	ACR;
	uchar	IDAC1;
	uchar	IDAC2;
	uchar	ODAC;
	uchar	DIO;
	uchar	DIR;
	uchar	DEC0;
	uchar	MDEC1;
	uchar	OCR0;
	uchar	OCR1;
	uchar	OCR2;
	uchar	FSR0;
	uchar	FSR1;
	uchar	FSR2;
}ADREG;


uchar	code AinConfig[]={
0x08,			//AIN0-AINCOM	
0x18,			//AIN1-AINCOM
0x28,			//AIN2-AINCOM
0x38,			//AIN3-AINCOM
0x48,			//AIN4-AINCOM
0x58,			//AIN5-AINCOM
0x68,			//AIN6-AINCOM
0x78,			//AIN7-AINCOM
0x88			//TEMPERATURE SENSOR
};

char2long	idata adresconv;
ADREG	xdata ADCONREG;
ADREG	xdata	adreg8[8];		//该参数将被写入ADS1218的RAM中
HdP		xdata  HdParam[8];		//硬件整定参数
/*
HdParam[0]:ch0 mA
HdParam[1]:ch1 mA
HdParam[2]:ch0 v
HdParam[3]:ch1 v
HdParam[4]:ch2 Rt
HdParam[5]:ch3 Rt
HdParam[6]:ch2 Th
HdParam[7]:ch3 Th

*/
Run_HdP	xdata	RunHdParam[4];	//运行参数,由整定参数得来并由逻辑通道参数得到工程量计算系数


#if(1)
	sbit	CS		=P3^5;
	sbit	CLK		=P1^1;
	sbit	DIN		=P1^0;
	sbit	DOUT	=P1^7;
	sbit	DRDY	=P3^3;
	//sbit	WREN	=PD^1;
	//sbit	BUFEN	=PD^2;
	//sbit	RST		=PC^7;

#else
	sbit	MEM_CS0 =P1^0;
	sbit	CLK		=P1^1;
	sbit	DOUT	=P1^2;
	sbit	DIN		=P1^3;
	sbit	CS		=P1^4;
	sbit	DRDY	=P3^3;
	sbit	BUFEN	=P1^6;
	sbit	WREN	=P1^7;
	//sbit	RST		=PC^7;
#endif

#define ENWREN	PSD8xx_reg.DATAOUT_D |= 0x02
#define DISWREN	PSD8xx_reg.DATAOUT_D &= 0xFD
#define START CS=0;
#define STOP  CS=1;


/************BYTE OUT**************/
void	send_byte(uchar var)
{uchar  idata i;
	for(i=0;i<8;i++){
		CLK=0;
		DIN=(var<<i)&0x80;
		CLK=1;
	}
}
/**************读取一个字节*******************/
uchar	read_byte(void)
{uchar idata i,j;
	j=0;
	for(i=0;i<8;i++){
		CLK=0;
		j=_crol_(j,1);
		j|=(uchar)DOUT;
		CLK=1;
	}
	return j;
}

/****************发送1字节命令,无数据输入,无数据返回****************/
void	send_comm1(uchar comm)
{
	START
	send_byte(comm);
	STOP
}

/****************发送1字节命令,无数据输入,无数据返回****************/
/* 适用命令
#define		STOPC	0X0F				//停止连续读模式
#define		CREG	0X40				//拷贝寄存器内容到指定的ram bank中,低三位指定ram的页地址
#define		CREGA	0X48				//拷贝寄存器内容到所有的ram bank中。
#define		RF2R	0X80				//读指定FLASH页的数据到128字节的RAM中
#define		WR2F	0XA0				//将ram中的数据写入到指定的FLASH页中
#define		CRAM	0XC0				//复制选择的ram数据到配置寄存器中,将覆盖当前的工作寄存器内容
#define		CSRAMX	0XD0				//计算指定页ram中的校验和,不包含ID,DRDY DIO
#define		CSARAMX	0XD8				//计算所有ram中的校验和,不包含ID,DRDY DIO
#define		CSREG	0XDF				//计算配置寄存器的校验和
#define		CSRAM	0XE0				//计算指定页ram中的校验和,包含所有位
#define		CSARAM	0XE8				//计算所有ram中的校验和,包含所有位
#define		CSFL	0XEC				//计算所有FLASH中的校验和,包含所有位
#define		SELFCAL	0XF0				//偏移量和增益自校准
#define		SELFOCAL	0XF1			//偏移量自校准
#define		SELFGCAL	0XF2			//增益自校准
#define		SYSOCAL		0XF3			//系统偏移量校准
#define		SYSGCAL		0XF4			//系统增益校准
#define		DSYNC		0XFC			//同步DRDY
#define		SLEEP		0XFD			//休眠模式
#define		RESET		0XFE			//复位寄存器到上电时的数据,停止连续读模式,不影响ram中的数据

*/

/************************读取ad转换后的数据*****************************/
//fg 0:有极性 1: 无极性
long	read_ad_data(uchar fg)
{
	START
	send_byte(RDATA);
	delay(0);
	adresconv.ADRST.adresh=read_byte();
	adresconv.ADRST.adresm=read_byte();
	adresconv.ADRST.adresl=read_byte();
	STOP
	adresconv.ADRST.adresfg=0;
	if(adresconv.ADRST.adresh&0x80 && fg==0)//long
		adresconv.ADRST.adresfg=0xff;
	return	adresconv.adreslong;
}

/***********************2字节命令*******************************/
// 连续读取、写入 配置寄存器reg0-15,或RAM中的数据,
//读取reg时,如超出范围将回绕;读取Ram时,将以BANK为起点,0-127字节长度
//写入REG时
//buff: 	读或写时存放数据的缓冲区地址
//comm_page:命令前缀和读取或写入reg、RAM的开始地址
//length:	要写入或读取的字节长度;该值为实际字节长度-1
//return	返回实际写入的字节长度

uchar 	wr_rd_data_sequ(uchar * buff,uchar comm_page,uchar length)
{	uchar  i;
	bit	fg;
	if((comm_page&0xf0)==RREG || (comm_page&0xf0)==RRAM){	//是读命令
		fg=1;
	}
	else{
		if((comm_page&0xf0)==WREG || (comm_page&0xf0)==WRAM)//是写命令
			fg=0;
		else
			return 0;		//非法命令返回数据长度0
	}
	START
	send_byte(comm_page);		//发送读或写命令和开始地址,reg:0-15,ram:0-7
	delay(0);
	send_byte(length);			//要读、写的字节长度。
	delay(0);
	if(fg){
		for(i=0;i<length+1;i++){
			*(buff+i)=read_byte();		//读取数据
		}
	}
	else{
		for(i=0;i<length+1;i++){
			send_byte(*(buff+i));		//写入数据
		}
	}
	STOP
	return i;
}

/******************设定AD数据输出速率******************/
//val 转换速率 xxHz/s
//10-950Hz
void	ad_rate_set(uint val)
{
	uint	 decratio;
	wr_rd_data_sequ((uchar *)&ADCONREG.DEC0,RREG|(&ADCONREG.DEC0-&ADCONREG.SETUP),1);		//读取原值
	decratio=FOSC*1000/((((ADCONREG.SETUP>>4)&0x01)+1) *128)/val;	//求得DEC
	if(decratio>2047)decratio=2047;
	if(decratio<20)decratio=20;
	ADCONREG.DEC0=decratio&0x00ff;						//DEC0
	ADCONREG.MDEC1&=0xf8;
	ADCONREG.MDEC1|=(decratio>>8)&0x07;			//DEC1
	wr_rd_data_sequ((uchar *)&ADCONREG.DEC0,WREG|(&ADCONREG.DEC0-&ADCONREG.SETUP),1);		//设定
}

/******************读取单个寄存器********************/
//uchar *reg:ADCONREG结构中的元素,由此计算出写入的开始地址
//同时修改和返回读取的值
uchar	read_reg(uchar	*reg)
{	uchar reg_addr;
	reg_addr=reg-&ADCONREG.SETUP;
	wr_rd_data_sequ(reg,RREG|reg_addr,0);
	return *reg;
}

/******************写入单个寄存器********************/
//uchar *reg:ADCONREG结构中的元素,由此计算出写入的开始地址
//
uchar	write_reg(uchar	*reg)
{	uchar reg_addr;
//	uchar * startptr=&ADCONREG;
	reg_addr=reg-&ADCONREG;
	wr_rd_data_sequ(reg,WREG|reg_addr,0);
	return *reg;
}

/******************flash 读写使能位 处理***************/
//fg 0:disable 1:enable

uchar  flash_write_ctrl(uchar fg)
{uchar  datatemp;
	datatemp=read_reg(&ADCONREG.MDEC1);		//读取当前wren 
	if(fg){
		datatemp|=0x08;						//enable
		ENWREN;								//flash enable pin =1
	}
	else{
		datatemp&=0xf7;						//disable
		DISWREN;							//flash enable pin =0
	}
	ADCONREG.MDEC1=datatemp;
	write_reg(&ADCONREG.MDEC1);				//write flash write enable bit
	return datatemp;
}

/*******************设定AD转换通道********************/
//chnum:将要使用的通道,0-8
void	set_channel(uchar chnum)
{
	ADCONREG.MUX=AinConfig[chnum];		//提取输入端口配置
	write_reg(&ADCONREG.MUX);			//单字节写入
}
/*******************读取DI输入引脚状态****************/
//return DIO 当前状态
uchar	read_di(void)
{
	read_reg(&ADCONREG.DIO);			//单字节写入
	return ADCONREG.DIO;
}

/*******************设定DO输出引脚状态****************/
//return DIO 当前状态
uchar	write_do(uchar val)
{	ADCONREG.DIO=val;
	write_reg(&ADCONREG.DIO);			//单字节写入
	return 0;
}

/*******************配置数字引脚为输入或输出****************/
//return DIR 当前状态
uchar	write_dir(uchar val)
{	ADCONREG.DIR=val;
	write_reg(&ADCONREG.DIR);			//单字节写入
	return 0;
}

/*******************设定AD为双极性、单极性****************/
//
void	set_data_fmt(uchar val)
{	SFR_Reg	temp;
	temp.bytes=read_reg(&ADCONREG.MDEC1);
	if(val)
		temp.bits.bit6=1;
	else
		temp.bits.bit6=0;
	ADCONREG.MDEC1=temp.bytes;
	write_reg(&ADCONREG.MDEC1);			//单字节写入
}

void init_ads1218(void)
{
PSD8xx_reg.DIRECTION_C|=0x80;	//set PC7as a output mode .1.2.3.4.5.6 input mode bit7 as output
PSD8xx_reg.DATAOUT_C|=0x80;		//set PC7=0

PSD8xx_reg.DIRECTION_D|=0x06;	//set PC7 as a output mode .1.2.3.4.5.6 input mode bit7 as output
PSD8xx_reg.DATAOUT_D|=0x06;		//set PD1 PD2=1


write_dir(0x0f);	//配置数字IO为bit3-0 为输入引脚;bit7-4为输出引脚
write_do(0x00);		//输出0000 74hc04的输出为1111
write_do(0xff);		//输出1111 74hc04的输出为0000
set_data_fmt(0);	//AD双极性输出
ad_rate_set(80);	//120Hz输出速率

}

void delay(unsigned int val)
{
	while(val)val--;
}

//*******************************************************************/
#if(0)
void main(void)
{	float  adres;
	uint i=1;
	uchar j,k=0;
	float	 adarry[8];
	float Ti;

init_int1();
init_time1();
LCMInit();
cls();
write_dir(0x0f);	//配置数字IO为bit3-0 为输入引脚;bit7-4为输出引脚
write_do(0x00);		//输出0000 74hc04的输出为1111
write_do(0xff);		//输出1111 74hc04的输出为0000
set_data_fmt(0);	//AD双极性输出
i=119;
ad_rate_set(i+1);

	while(1){	 
		
//		send_comm1(RESET);
		while(!DRDY);
		while(DRDY);
		cursor(k,0);
//		adres=read_ad_data(0);
//		adarry[k]=(adarry[k]*100+adres)/101;
		aprintf("AD%bu=%.3f mV %u",k,ad_res[k]*ADMSB,i+1);
/*		read_di();
		cursor(2,0);
		aprintf("DIR= 7 6 5 4 3 2 1 0");
		cursor(3,0);
		aprintf("     ");
		for(j=0;j<8;j++){
			if((ADCONREG.DIR<<j)&0x80)
				aprintf("1 ");
			else
				aprintf("0 ");
		}

		cursor(4,0);
		aprintf("DIO= 7 6 5 4 3 2 1 0");
		cursor(5,0);
		aprintf("     ");
		for(j=0;j<8;j++){
			if((ADCONREG.DIO<<j)&0x80)
				aprintf("1 ");
			else
				aprintf("0 ");
		}
		write_do(i<<4);		//输出
*/
		Ti=Read_Temperature();
		cursor(7,0);
		aprintf("T=%.2f",Ti);
		++k;
		if(k>7)k=0;
		set_channel(k);		//0 通道 
		wr_rd_data_sequ((uchar *)&ADCONREG,RREG|0x00,15);


/**************测试5×8字库*********************/
//		for(j=0x20;j<0x80;j++)
//			aprintf("!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]");
//			aprintf("abcdefghijklmnopqrstuvwxyz{|}~");
//		wr_rd_data_sequ((uchar *)&ADCONREG,(RREG|0x00),15);
//		ad_rate_set(20);

	}



}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -