freedomhit

ADIS16355的通讯程序(补充)

0
阅读(3185)

	#include<ADuC7026.h> 
#include "ADIS16355_IO.h"
#define SET_CS()  GP4DAT = (GP4DAT | 0x00080000) //P4.3->/CS
#define CLR_CS()  GP4DAT = (GP4DAT & 0xFFF7FFFF)
#define SET_SCL()  GP4DAT = (GP4DAT | 0x00100000) //P4.4->SCLK
#define CLR_SCL()  GP4DAT = (GP4DAT & 0xffefffff)
#define SET_SDO()  GP4DAT = (GP4DAT | 0x00200000) //P4.5->DIN
#define CLR_SDO()  GP4DAT = (GP4DAT & 0xffdfffff)
void delay (signed int length)
{
 while (length >0)
     length--;
}
//---------------------------------
//WriteToADIS16355ViaSpi();
//---------------------------------
//Function that writes to the ADIS16355 via the SPI port. It sends first the control
//word that includes the start address and then the data to write.
//When writing registers which take up multi-bytes, ADIS16355 must be written one byte by one byte.
//CS must be pulled high and then pulled low before writing the next byte
//--------------------------------------------------------------------------------
void WriteToADIS16355ViaSpi(unsigned char RegisterAddress, unsigned char NumberofRegisters, unsigned char *RegisterData)
{
 unsigned char ControlValue = 0;
 unsigned int  ValueToWrite = 0;
 unsigned char RegisterIndex = 0;
 unsigned char i = 0;
 
 for(RegisterIndex=0; RegisterIndex<NumberofRegisters*2;
RegisterIndex++)//every register of ADIS16355 takes up two bytes
 {
  //Create the 8-bit header
  ControlValue = (RegisterAddress + RegisterIndex) | 0x80;
  SET_SCL();
  delay(1);
  SET_CS();
  delay(1);
  CLR_CS();
  delay(1);
  //Write out the control word
  for(i=0; i<8; i++)
  {  
   CLR_SCL();
   if(0x80 == (ControlValue & 0x80))
   {
    SET_SDO();  //Send one to DIN pin of ADIS16355
   }
   else
   {
    CLR_SDO();  //Send zero to DIN pin of ADIS16355 
   }
   delay(1);
   SET_SCL();
   delay(1);
   ControlValue <<= 1; //Rotate data 
  }
  //And then the data
  ValueToWrite = *(RegisterData + RegisterIndex);
  for (i=0; i<8; i++)
  {
   CLR_SCL();
   if(0x80 == (ValueToWrite & 0x80))
   {
    SET_SDO();   //Send one to DIN pin of ADIS16355
   }
   else
   {
    CLR_SDO();   //Send zero to DIN pin of ADIS16355
   }
   delay(1);
   SET_SCL();
   delay(1);
   ValueToWrite <<= 1; //Rotate data
  }
     SET_CS();    //bring CS high again
     delay(2);
 }
}
//---------------------------------
//ReadFromADIS16355ViaSpi();
//---------------------------------
//Function that reads from the ADIS16355 via the SPI port. ADIS16355 supports full duplex mode operation.
//It first send the control word that includes the start address which you are going to access and then 8 clcoks
//Now,the data on DOUT pin of ADIS16355 is the register which you accessed just before this operation
//Then repeat sending control word and clock, read data at the same time and now
//the data on DOUT pin of ADIS16355 is the register which you are going to read
//CS must be pulled high and then pulled low before reading the next register
//--------------------------------------------------------------------------------
void ReadFromADIS16355ViaSpi(unsigned char RegisterAddress, unsigned char NumberofRegisters, unsigned char *RegisterData)
{
 unsigned char ControlValue = 0;
 unsigned char RegisterIndex = 0;
 unsigned char ReceiveData = 0;
 unsigned char i = 0, j = 0;
 unsigned int  iTemp = 0;
 for(RegisterIndex=0; RegisterIndex<NumberofRegisters; RegisterIndex++)
 {
  for(j=0;j<2;j++) //Repeat reading to make sure the data on DOUT is just the register which you are going to read
  {
   //Create the 8-bit header
   ControlValue = RegisterAddress + RegisterIndex*2;//every register of ADIS16355 takes up two bytes
   SET_SCL();
   delay(1); 
   SET_CS();
   delay(1);
   CLR_CS();  //bring CS low
   delay(1);
 
   //Write out the control word
   for(i=0; i<8; i++)
   {
    CLR_SCL();
    if(0x80 == (ControlValue & 0x80))
    {
     SET_SDO();   //Send one to DIN pin of ADIS16355
    }
    else
    {
     CLR_SDO();   //Send zero to DIN pin of ADIS16355
    }
    delay(1);
    SET_SCL();
    ReceiveData <<= 1;  //Rotate data
    iTemp = GP0DAT;   //Read DOUT of ADIS16355
    if(0x00000020 == (iTemp & 0x00000020))
    {
     ReceiveData |= 1; 
    }
    delay(1);
    ControlValue <<= 1; //Rotate data
   }
   *(RegisterData + RegisterIndex*2 + 1) = ReceiveData;
   //Read data in
   for(i=0; i<8; i++)
   {
    CLR_SCL();
    delay(1);
    SET_SCL();
    ReceiveData <<= 1;  //Rotate data
    iTemp = GP0DAT;   //Read DOUT of ADIS16355
    if(0x00000020 == (iTemp & 0x00000020))
    {
     ReceiveData |= 1; 
    }
    delay(1);
   }
   *(RegisterData + RegisterIndex*2) = ReceiveData;
   SET_CS(); //bring CS high again
   delay(2); 
  }
 }
}
 ADIS作为从机,7026作为主机,之前已经发过ADIS16355的数据手册了,在数据额手册里
有对应的时钟、信号通道,在7026中我已经标出了所对应的通道,大家按着这个管脚相连,
就可以完成通讯了。但是由于水平有限,我还没有对温度等漂移进行补偿,大家如果谁设计
好了电路什么的解决这个问题,分享一下,小弟感觉不尽(这是改过的程序,并不是所有都
是原创的)