#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); } } }
|