📄 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 + -