ADS7841 driver based on MSP430

Publisher:电子思维Latest update time:2016-08-18 Source: eefocusKeywords:MSP430  ADS7841  Driver Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
My senior sister (PhD) reverse-designed the ADS7841 chip. In order to test its stability and accuracy, she helped write this driver. My senior brother originally wrote it with FPGA, but the data read out was too different, so I used a 430 microcontroller to help me make one! But the debugging of this program was not smooth, it was just painful. I didn't eat lunch and dinner yesterday! First, I encountered a broken I/O port, and the description of the reading in the DATASHEET of this chip was wrong, which was very harmful! According to the datasheet, it is necessary to wait for the busy signal to be low before starting to read. In fact, it is too late at this time and one bit will be missed. All the above problems were found out with the help of a logic analyzer. I analyzed the captured timing bit by bit and finally found the loophole of the DATASHEET in the reading. In addition, she did not mention which edge of the clock should be used to trigger writing and reading data respectively. It is really depressing~! Normally, the instruction should be written on the falling edge and the data should be read on the rising edge!
It took a day to get the result. If it weren't for the help of the logic analyzer, I guess I would not know how I died. .
Okay, the situation is explained, and the following is the code part.
*********************************************************************************
** Function prototype: unsigned int ADS7841_Read_Data(unsigned char Channel);
** Function: A/D ADS7841 driver program of SPI bus
** Input parameter: unsigned char Channel indicates the selection of reading channel
** Output parameter: unsigned int returns the 12-bit data read.
** Description: ADS7841 is a 12-bit A/D. Set it first: data bits D0---D7, where D0---D1 is
** Set the ADC power consumption mode, D2 is the analog input channel setting, H is 4 single channels, L is two
** differential inputs, D3 is mode, when mode (pin) is grounded, it is a 12-bit sampling mode, when connected to a high level
** mode is 1 when 8-bit acquisition, 0 when 12-bit acquisition, D4---D6 for input channel selection, D7 is the start bit
** Author: Thinking Fish
** Date: November 6, 2007
**-----------------------------------------------------------------------------
** Modifier:
** Date:
***************************************************************************/
#include
#define uint unsigned int
#define uchar unsigned char
#define ADS_S 0x80 //Command start bit
#define ADS_MODE 0x08 //Mode selection. MODE terminal selection directly connected to high level, this bit does not need to be set
#define ADS_S_D 0x04 //Input mode selection
#define ADS_POWER 0x00 //Whether to allow power off
#define DIR_CS P3DIR|=BIT0
#define ADS_CS_1 P3OUT|=BIT0
#define ADS_CS_0 P3OUT&=~BIT0 //Chip select
#define ADS_DIR_IN P3DIR|=BIT1 //Port output mode
#define ADS_DIN_1 P3OUT|=BIT1 //Command write AD
#define ADS_DIN_0 P3OUT&=~BIT1
#define ADS_DIR_OT P2DIR&=~BIT0 //Port is in input mode
#define ADS_CLK_DIR P4DIR|=BIT4 //Port is in output mode
#define ADS_CLK_1 P4OUT|=BIT4 //Clock is set to 1
#define ADS_CLK_0 P4OUT&=~BIT4 //Set clock to 0
#define DIR_BUSY P4DIR&=~BIT0
//#define DATA_IN ((P4IN>>2 & 0x01)
#define DATA_IN (P2IN & 0x01)
#define BUSY_IN (P4IN & 0x01) //Read input data
void Check_busy(void);
void SPI_WR(uchar DATA) ;
void Init_Port(void);
void delay(uint temp);
uint ADS7841_Read_Data(uchar Channel);
uint temp_DATA[100];
void delay(uint temp1)
{
  int i;
  for(i=temp1;i>0;i--)
  {
    ;
  }
}
uint ADS7841_Read_Data(uchar Channel) //Channel=0:CH0;1:CH1;2:CH2;3: CH3;
{
  uint ADCResult=0;
  uchar i,ADS_CHANNEL;
  uint TempBit =0;
  uchar COMMAND=0;
  switch (Channel)
  {
     case 0:ADS_CHANNEL=0x10;break; //Channel selection
     case 1:ADS_CHANNEL=0x50;break;
     case 2:ADS_CHANNEL=0x20;break;
     case 3:ADS_CHANNEL=0x60;break;
     default:ADS_CHANNEL=0x10;break;       
  }
  COMMAND=(ADS_S|ADS_CHANNEL|ADS_S_D|ADS_POWER);
  ADS_CLK_0;
  ADS_DIN_0; ///DIN is set to 0 first
  ADS_CS_0; //;Chip select signal
  //SPI_WR(COMMAND); //SPI bus write command subroutine
  //ADS_DIR_IN; //Port is defined as output mode, rising edge sends, falling edge receives
  for(i=0;i<8;i++)
  { 
     ADS_CLK_1;
     if( (COMMAND & 0x80) ==0x80)
     {
        ADS_DIN_1; //Write instruction
     }
     else
     {
        ADS_DIN_0;
     }
     COMMAND<<=1; //Left shift
     delay(5);
     ADS_CLK_0;
     delay(5); //Simulate SPI serial interface to send data                    
  }
  delay(5);
  ADS_CLK_0;
  Check_busy();
  //delay(5);
  for(i=0;i<12;i++)
  { //Rising edge read data   
     ADS_CLK_0;
     delay(4);
    if( DATA_IN==0x01 )
     {
       TempBit=1;
     }
     else
     {
       TempBit=0;
     }
    ADS_CLK_1;
    ADCResult=((ADCResult<<1)|TempBit); //Simulate SPI serial interface, receive data
    delay(5);
  }
    ADS_CLK_0;
  for(i=0;i<4;i++)
  {
     ADS_CLK_1;
     delay(5);
     ADS_CLK_0;
     delay(5);
  }
  ADS_CS_1; //Shield chip select
  return ADCResult;
}
void Check_busy(void)
{
  int temp;
  //DIR_BUSY; //Port is set to input mode
  ADS_CLK_1;
  temp=BUSY_IN;
  ADS_CLK_0;
  while( (temp&0x01)==0) //Start reading when high level is detected. . Otherwise, one bit will be lost
  {
    ADS_CLK_1; //Read port status....
    temp=BUSY_IN;
    //delay(5); //
    ADS_CLK_0;
  }
  //
 /* do
  {
      ADS_CLK_0; //Read port status....
      temp=BUSY_IN;
      delay(5); //
      ADS_CLK_1;
  }while((temp&0x01)!=0); //High bit is 1 for busy signal*/
}
 void SPI_WR(uchar DATA)
{
  uint i;
  ADS_DIR_IN; //Port is defined as output mode, rising edge sends, falling edge receives
  for(i=0;i<8;i++)
  { 
     ADS_CLK_1;
     if( (DATA & 0x80) ==0x80)
     {
        ADS_DIN_1; //write instruction
     }
     else
     {
        ADS_DIN_0;
     }
     DATA<<=1; //left shift
     ADS_CLK_0;
     delay(5); //simulate SPI serial interface to send data                    
  }
  delay(5);
  ADS_CLK_0;
}
void Init_Port(void)
{
  P3SEL=0X00;
  P4SEL=0X00;
  ADS_DIR_IN;
  ADS_DIR_OT;
  ADS_CLK_DIR;
  DIR_BUSY;
  DIR_CS;
  ADS_CLK_0;
  //delay(5);
  ADS_CS_1;
 // ADS_CLK_1; 
}
void main(void)
{
  WDTCTL = WDTPW+WDTHOLD; //turn off watchdog
  Init_Port(); //port initialization
  uint flag=0;
  uint i;
  while(1)
  {
    for(i=0;i<5;i++)
    {
      temp_DATA[i]=ADS7841_Read_Data(0);
      delay(10);
    }
    flag=1;
  }
 
}
Keywords:MSP430  ADS7841  Driver Reference address:ADS7841 driver based on MSP430

Previous article:Writing of 1S delay program in single chip microcomputer
Next article:Using msp430 and TLC5620 to implement AD_DA

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号