分享

AVR单片机驱动高精度AD芯片ADS1256的C程序

 共同成长888 2015-06-30

#include <avr/io.h>   
#include <avr/interrupt.h>   
#include <avr/signal.h>  


/*************************************************************************************/
volatile void delay_us(unsigned char a)   //挺时1uS
{  
volatile unsigned int i=0,j=0;
for(i=0;i<a;i++)
for(j=0;j<50;j++)
;
}

/*************************************************************************************/
//ads126发送一字节的数据  
unsigned char ads_senddata(unsigned char data)  //SPI发送数据,要在外部保证SS = 0  
{
SPDR = data;                //启动数据传输  
while((SPSR & 0x80) == 0); // 等待传输结束  
data = SPDR;  
return data;  
}

/*************************************************************************************/
void ad_write(unsigned char reg,unsigned char data)//写寄存器。选择寄存器地址,写入的数据。
{               
     PORTB&=~(1<<PB1);      //SPI的CS=0使能
     while((PIND&0X8)!=0); //DRDY信号高时才能写寄存器   
     ads_senddata(0x50+reg);//选择写入寄存器      
     ads_senddata(0x00);    //写入1个寄存器      
     ads_senddata(data);    //写入数据
     PORTB|=(1<<PB1);       //SPI的CS=1,停止
     delay_us(1);          //挺时1uS     //可更改。但读数据必须在要等待最小一个采集周期(大约90ms)后。
}
/*************************************************************************************/
unsigned long int ad_read()//读A/D数据。
{     
     unsigned long int  sum=0;
     unsigned char r=0,a=0;      
     PORTB&=~(1<<PB1);        //SPI的CS=0使能
     ads_senddata(0xfc);       //SYNC   AD同步
     ads_senddata(0xff);       //WAKEUP     唤醒,并启动AD转换
     while((PIND&0X8)!=0);    //DRDY信号低时才能写寄存器   ,等待转换完毕
        {
                 delay_us(1);         //挺时1uS
         ads_senddata(0x01);  //发送读取数据命令
                 delay_us(1);         //挺时1uS
         for (r=0;r<3;r++)   //读取24位数据
            {
                   a=ads_senddata(0x00); //读取数据,先高位,后低位
                   sum|=a;
                   sum=sum<<8;
            }
                 sum=sum>>8;
                }
     PORTB|=(1<<PB1);     //SPI的CS=1,停止
         sum=0xffffff-sum;
         return  sum;
     delay_us(1);          //挺时1uS
}

/*************************************************************************************/
void  ADS1256(void)    //初始化ADS1256
{
DDRD&=~(1<<PD3);   //DRDY
PORTD|=(1<<PD3);   
DDRD|=(1<<PD4);    //START
PORTD|=(1<<PD4);   
PORTB&=~(1<<PB2);     //复位ADS1256
PORTB|=1<<PB2;
ad_write(00,0xf7);     //初始化STATUS reg  ID位为f,数据输出高位在先,自动校准开,输入缓冲关闭,DRDY高电平
ad_write(01,0x80);     //初始化MUX    reg  单端输入第0通道为选通
ad_write(02,0x00);     //初始化ADCOM  reg  时钟输出关闭,传感器检测关闭,放大倍数为1
ad_write(03,0xf0);     //初始化DRATE  reg  数据速率为30K
ad_write(04,0x0f);     //初始化DRATE  reg  定义IO为输出高电平,节能模式            
}

/*************************************************************************************/
unsigned long int ads_sum(unsigned char data)//读A/D数据。
  {   
     unsigned long int aa=0;
         if((data>=0)&&(data<=7))
        {
                ad_write(01,0x80+data);     //第几通道为选通
            ads_senddata(0xf0);         //自校准
            aa=ad_read();               //读24位A/D数据。
                }
         return aa;
  }

volatile unsigned char sum=0;    //定义全局的指令变量

//设置串口的参数
void USART_Init( unsigned int baud )
{
/* 设置波特率9600*/
UBRRH = 0;
UBRRL = 47;
/* 接收器与发送器使能*/
UCSRB = (1<<TXCIE)|(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
/* 设置帧格式: 8 个数据位, 2 个停止位*/
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit( unsigned char data )
{PORTD|=(1<<PD2);   //485输出使能
/* 等待发送缓冲器为空 */
while ( !( UCSRA & (1<<UDRE)) )
;
/* 将数据放入缓冲器,发送数据 */
UDR = data;
}

unsigned char USART_Receive( void )
{
/* 等待接收数据*/
while ( !(UCSRA & (1<<RXC)) )
;
/* 从缓冲器中获取并返回数据*/
return UDR;
}

 

SIGNAL (SIG_UART_RECV)  //接收中断
{sum=UDR;}  

SIGNAL (SIG_UART_TRANS) //发送结束中断
{PORTD&=~(1<<PD2); }    //485输入使能


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~配置SPI~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

void SPI_MasterInit(void)     //配置SPI为主机   
{   
/* 设置MOSI 和SCK 为输出,其他为输入 */   
DDRB|=(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB5);   
DDRB&=~(1<<PB4);   
PORTB|=(1<<PB1)|(1<<PB2)|(1<<PB4); //定义SS的使能端   
/* 使能SPI 主机模式,设置时钟速率为fck/16 */   
SPCR = 0x52; //7e 高位首发,SPI使能,主机模式,SCK空闲保持为低电平,数据在上升沿采样,速率为1:64(FOSC/128)   
SPSR = 0x01; //使能倍速1:32   
}  

//--------------------------------------------------------------------------------------------//  

void  port (void)   
{   
  DDRD|=(1<<PD2);    //485  cs   
  PORTD&=~(1<<PD2);     
  DDRB|=(1<<PB0);    //power 灯   
  PORTB&=~(1<<PB0);    

}  


//主函数
main(void)   
{   
  unsigned long int d=0,p[12],n=0,m=0;   
  unsigned char aa=0,a=0,b=0,c=0,i=0;   
  port();     //端口初始化   
  SPI_MasterInit();  //SPI端口初始化   
  USART_Init(1);     //串口初始化   
  ADS1256();         //初始化ADS1256   
  sei();  

  while(1)   
  {   
    aa=sum;   
    if(aa<=10)   
      {sum=15;   
       a=0;b=0;c=0;n=0x400000;m=0;   
       for (i=0;i<12;i++)   
         {   
          p[i]=ads_sum(aa);//读A/D数据。通道地址0~7  0、1、2、3、4、5、6、7   
          if(n>p[i])   
          n=p[i];   
          if (m<p[i])   
           m=p[i];   
          d=d+p[i];   
         }   
       d=(d-n-m)/10;   
       a=d%256;   
       d=d>>8;   
       b=d%256;   
       d=d>>8;   
       c=d%256;   
       USART_Transmit(c);   
       USART_Transmit(b);   
       USART_Transmit(a);  

      }   
  }     

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多