https://static.assets-stash.eet-china.com/album/old-resources/2008/12/27/9b6a35b9-1337-42c5-aa91-9cdb0795f207.rarhttps://static.assets-stash.eet-china.com/album/old-resources/2008/12/27/787def9c-240a-4db3-8c63-cbfb9dbe4c4a.rar(图片请参照附件,文章中显示不了)
基于cy7c68013与cpld的ads1258 24位数据采样<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
(一)系统连接框图
由于此模块是基于cy7c68013与cpld的传感器实验平台中的一部分,刚开始布线时准备采用此单片机的IOE口来直接控制,后来发现IOE口不能进行位寻址,进行SPI模拟时较为麻烦,故现采用单片机与cpld共同控制数据采样,cpld起连接线和提供外部时钟输入的作用,系统框图如下:
(二)ads1258采样步骤
1)复位SPI总线,即将cs置高4096fclk后拉低
2)停止转换器,start=0
3)复位转换器,reset=1
4)配置寄存器,先发送配置寄存器命令后配置,先通过SPI总线发送一个写寄存器命令(70H),再逐个配置片内寄存器(设置为Auto-scan mode, Date rate =[00],GPIO[7:0]=[FFH]输出)
5)开始转换,start=1
6)读取频道信息,当DRDY=0时,发送频道信息读取命令。这里采取的是REGISTER READ MODE,故命令为00110000B,再从内部寄存器中读取频道扫描的信息
(三)SPI总线模拟
由于cy7c68013单片机没有SPI总线,故采取pd口模拟spi时序的方法来读取数据。下面是SPI读时序和SPI写时序
上面列出的是SPI总线的读和写寄存器以及发送命令的时序,在实际进行操作的时候,SPI总线是单片机在低电平的时候将数据准备好,在上升沿的时候将数据发送出去;而在读取数据的时候,往往先置低clk,再适当延时,并在上升沿后的高电平时将数据读入内部C。
在这里特别需要注意的是DATE RATE 的设定,由于是串行数据,而单片机在处理串行数据时速度上有一定的限制(特别是在模拟SPI总线时),故一般设置DATE RATE = [00],最低速。
(四)寄存器及命令的设置
下面分别对整个操作流程中需要的命令和一些寄存器设置进行一些说明:
1)配置寄存器命令,由图COMMAMD BYTE可以看出,Register Write Command命令为我们所选,还需要说明的是MUL是连续设置的意思,MUL=1代表寄存器将从后面A3~A0设置的地址开始进行配置
2)频道读取命令解析,由图command bye 可以看出,读取频道信息命令有两种,一种是Channel data read direct,这种命令可以不根据DRDY的信息,而直接看数据位中的system register中的new这位来判断数据是否更新;另一种是Channel data read from register ,这种是当drdy=0时,发送频道数据读取命令,然后存在内部的寄存器里面。在这里我们率先选取了后一种即00110000B。
3)寄存器的配置:率先采用的是Auto-Scan Mode,Date rate =[00],外部时钟输入,包含系统寄存器位。故寄存器设置从00H至09H依次为02H,00H,00H,00H,0FFH,0FFH,00H,00H,88H,8BH。
(五)参考电压的设置
根据datasheet参考电压切不可超过AVDD-AVSS,在这里选取参考电压为2.116V(根据万用表测的)。一定要设置参考电压!
(六)实例程序与注释
1)CPLD模块
CPLD模块的作用是提供一个接口与时钟
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity clock is
port(clkin :in std_logic;
drdy :in std_logic;
pd1 :in std_logic;
pd2 :in std_logic;
pd3 :in std_logic;
pd4 :in std_logic;
pd0 :out std_logic;
pwdn :out std_logic;
reset :out std_logic;
start :out std_logic;
cs :out std_logic;
clkout :out std_logic
);
end clock;
architecture behave of clock is
signal clk:std_logic;
signal clkcnt:integer range 0 to 1;
begin
comc1:process(clkin) //提供12M时钟
begin
if rising_edge(clkin) then
if(clkcnt = 1) then
clkcnt <= 0;
clk <= not clk;
else
clkcnt <= clkcnt + 1;
end if;
end if;
end process comc1;
clkout <= clk;
cs<=pd4; //以下为接口配置
start<=pd3;
reset<=pd2;
pwdn<=pd1;
pd0<=drdy;
end behave;
2)CY7C68013模块
sbit spiclk = IOD^5;
sbit spidout = IOD^6;
sbit spidin = IOD^7;
sbit cs = IOD^4;
sbit start = IOD^3;
sbit reset = IOD^2;
sbit pwdn = IOD^1;
sbit drdy = IOD^0;
void ads1258(void)
{
pwdn="1";
OED="0xBE"; //设置pd6和pd0(即spiout和drdy)为输入,其余pd口均为输出
cs=1; //拉高cs
#pragma asm
MOV R1,#15
TSR1:MOV R0,#90 //延时4096/12~~341us
DJNZ R0,$
DJNZ R1,TSR1
#pragma endasm
cs="0"; //拉低
start="0"; //停止转换器
reset = 0;
SYNCDELAY;
reset = 1; }
void spisend(void)//配置寄存器工作状态
{
#pragma asm
SPISTART:MOV R2,#00H
SPIWRITE:MOV DPTR,#SPICOMMAND
MOV A,R2
MOVC A,@A+DPTR
MOV R0,A
MOV R1,#8
CLR C
MOV A,R0
SPI:CLR IOD^5
RLC A
JC FUZHI
CLR IOD^7
SJMP NEXT
FUZHI:SETB IOD^7
NEXT:SETB IOD^5
DJNZ R1,SPI
INC R2
CJNE R2,#11,SPIWRITE
SPICOMMAND: DB 70H,02H,00H,00H,00H,0FFH,0FFH,00H,00H,88H,8BH //AUTO-SCAN MODE
//DRATE[1:0] = 10
#pragma endasm
}
void readchanelcom(void)//开始转换
{ start=1;}
void tmrdata(void)
{
#pragma asm
SPIREAD:MOV R0,#30H
SPIIN: MOV R2,#8
SPIBIT: CLR SPICLK
NOP
SETB SPICLK
NOP
NOP
MOV C,SPIDOUT
MOV A,@R0
RLC A
MOV @R0,A
DJNZ R2,SPIBIT
INC R0
CJNE R0,#38h,SPIIN
MOV R0,#00H
RET
#pragma endasm
}
void tmrtemp(void)
{
ads1258();
spisend();
readchanelcom();
}
void TD_Init( void )
{ // Called once at startup
CPUCS = 0x10; // CLKSPD[1:0]=10, for 48MHz operation
IFCONFIG = 0xE0; // set peripheral interface to ports mode
SYNCDELAY; // see TRM section 15.14
EP1OUTCFG = 0xA0; // ep1out is valid BULK OUT 64
SYNCDELAY; // see TRM section 15.14
EP8CFG = 0xE0;
SYNCDELAY;
PORTACFG = 0x00; // PORTA as i/o pins...
OED = 0xFF; // and as outputs...
PORTCCFG = 0x00; // PORTC as i/o pins...
Rwuen = TRUE; // Enable remote-wakeup
tmrtemp();
// turn debug LED[3:0] off...
}
void TD_Poll( void ) //发送频道读取命令与读取数据送入EP8FIFOBUF
{ // Called repeatedly while the device is idle
if(drdy==0)
{
#pragma asm //发送频道读取命令 CHANNEL DATA READ (register format)
COMMANDREAD:MOV R2,#00H
RECOMWRITE:MOV R0,#00110000B
MOV R1,#8
CLR C
MOV A,R0
SPILOWEDGE:CLR IOD^5
RLC A
JC IOD71
CLR IOD^7
SJMP SPIRISINGEDGE
IOD71:SETB IOD^7
SPIRISINGEDGE:SETB IOD^5
DJNZ R1,SPILOWEDGE
#pragma endasm
tmrdata();
if(!(EP2468STAT & bmEP8FULL))
{
#pragma asm
MOV DPTR,#0xFC00
MOV A,30H
MOVX @DPTR,A
MOV DPTR,#0xFC01
MOV A,31H
MOVX @DPTR,A
MOV DPTR,#0xFC02
MOV A,32H
MOVX @DPTR,A
MOV DPTR,#0xFC03
MOV A,33H
MOVX @DPTR,A
MOV DPTR,#0xFC04
MOV A,34H
MOVX @DPTR,A
MOV DPTR,#0xFC05
MOV A,35H
MOVX @DPTR,A
MOV DPTR,#0xFC06
MOV A,36H
MOVX @DPTR,A
MOV DPTR,#0xFC07
MOV A,37H
MOVX @DPTR,A
#pragma endasm
SYNCDELAY;
EP8BCH = 0x00;
SYNCDELAY;
EP8BCL = 0x08;
}
}
}
(七)实验数据的读取
在EZ-USB Control Pannel里面我们可以看到不同通道对应的数据,把Ain0接外部模拟信号输入,由于板子上面刚开始的输入是悬空的,所以未接模拟信号的15个外部通道均有一定的悬空电压。
通过下图可以看出,第一个字节对应是频道信息,第二三四均为数据采样信息,我们还是看看AIN0的信号电压是多少V吧
找到第一个字节对应有08的单元(即88H 前面三位为100,new=1)。
88 12 88 54:12 88 54是我们采得的数据,即Data
1LSB = VREF/780000H=2.69063313802083e-7
Ain0=Data*1LSB=0.32679030965169270833333333V
这与我们用万用表测的0.326V一致,且其精度要远远好于万用表
用户1742203 2014-4-23 13:56
用户1262263 2011-3-30 10:22
用户152019 2010-12-7 20:53
用户194501 2009-9-28 14:56
用户226067 2009-8-24 14:01
用户178741 2009-6-14 20:31
用户411554 2009-6-3 15:30
tengjingshu_112148725 2009-4-8 20:31
用户179261 2009-1-8 17:17
用户178741 2009-1-8 15:33