bbgood 发表于 2006-4-26 08:10:56

用ATMEGA64 模拟SPI口接16为AD(ADS8345)

/********************************* spi.h ***********************/

//模拟SPI口

//PE4 ---- BUSY

//PB0 ---- SS

//PB1 ---- DCLK

//PB2 ---- MOSI

//PB3 ---- MISO

//

#define        set_ss()        PORTB |= 0b00000001

#define set_sck()        PORTB |= 0b00000010

#define set_mosi()        PORTB |= 0b00000100

#define set_miso()        PORTB |= 0b00001000

#define set_busy()PORTE |= 0b00010000

#define        clr_ss()        PORTB &= 0b11111110

#define clr_sck()        PORTB &= 0b11111101

#define clr_mosi()        PORTB &= 0b11111011

#define clr_miso()        PORTB &= 0b11110111

#define clr_busy()PORTE &= 0b11101111

//

void delay_us(unsigned int);

void SPI_MasterInit(void);

unsigned int SPI_Read(void);

void SPI_Write(unsigned char data);





//****************************** spi.c *******************************//



#include        "iom64v.h"

#include        "macros.h"

#include        "spi.h"

/*

void SPI_Start(void)

{

        clr_sck();

        set_ss();

        set_miso();

        set_sck();

        clr_ss();

}

*/

void SPI_MasterInit(void)

{

        unsigned char temp;

// 设置MISO(PB3)为输入,高电平;MOSI(PB2) ,SCK(PB1) 和SS(PB0)为输出,高电平

        DDRB |= 0b00000111;

        DDRB &= 0b11110111;

        PORTB |= 0b00001111;

// BUSY(PE4)为输入,高电平

        DDRE &= 0b11101111;

        PORTE |= 0b00010000;

}

//发送前:CS = 0;DCLK = 0;Din = 0;Dout = 0;

//发送后:CS = 1;DCLK = 0;Din = 0;Dout = 1;

void SPI_Write(unsigned char data)

{

        int i;

        set_ss();

        clr_ss();

        clr_sck();

        clr_mosi();

        clr_miso();

        for(i=0;i<8;i++)

        {

                if(data & 0x80)set_mosi();

                else clr_mosi();

                delay_us(1);

                clr_sck();

                NOP();NOP();NOP();NOP();

                delay_us(5);

                data <<= 1;

                set_sck();

                NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();

                NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();

        }

        delay_us(3);

        clr_sck();

        clr_mosi();

        delay_us(20);

        set_ss();

        delay_us(10);

        set_miso();

    return;

}

//发送前:CS = 0;DCLK = 0;Din = 0;Dout = 0;

//发送后:CS = 1;DCLK = 0;Din = 0;Dout = 1;

unsigned int SPI_Read()

{

        int i,recData;

        recData = 0;

        clr_ss();

        clr_sck();

        clr_mosi();

        clr_miso();

        delay_us(2);

        for(i=0;i<24;i++)

        {

                set_sck();

                NOP();NOP();NOP();NOP();NOP();

                delay_us(5);

                clr_sck();

                delay_us(4);

                if(PINB&0b00001000)recData |= 0x01;

                else recData &= 0xfffe;

                if(i<16)recData <<= 1;

        }

        delay_us(10);

        set_ss();

        return recData;

}

void delay_us(unsigned int n)

{

        unsigned int i;

        for(i=0;i<n;i++)

        {

                ;

        }

        return;

}



/*************************main.c***************************/



include        "iom64v.h"

#include        "macros.h"

#include        "main.h"

#include        "spi.h"



unsigned char        ctrlByte;

unsigned int        adData;



/****************FUNCTION*******************/

void                        delay_1ms(void);

void                        delay_ms(unsigned int);

void                        variable_init(void);

void                        USART_init(void);

unsigned char                USART_Receive(void);

void                        USART_Transmit(unsigned char data);



#pragma interrupt_handler uartrx_isr:19                //UART接收结束中断



void main(void)

{

        unsigned char i = 0;

        float f;

        SPH = 0x0f;

        SPL = 0xd0;

        CLI();

        variable_init();

        USART_init();

        SPI_MasterInit();

        SEI();

        while(1)

        {

                ctrlByte = 0b11000100;                        //ch 1,single-ended,16位分辨率,

          SPI_Write(ctrlByte);

                delay_us(20);

                adData = SPI_Read();

                i = adData&0xff;

                USART_Transmit(i);

                adData >>= 8;

                i = adData&0xff;

                USART_Transmit(i&0xff);



                delay_ms(1000);

        }

}





void delay_1ms(void)

{

        unsigned int i;               

        for(i=0;i<2286;i++)//(XTAL*143-2)

        {

                ;

        }

}



void delay_ms(unsigned int n)

{

        unsigned int i;

        for(i=0;i<n;i++)

        {

                delay_1ms();

        }

}



void USART_init(void)

{

        /* 设置波特率 */

        UBRR0L = 103;//(fosc/16/baud-1)%256;

        UBRR0H = 0;//(fosc/16/baud-1)/256;

        /* 接收器与发送器使能,允许接收 */

        UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);//

        /* 设置帧格式:偶校验,1位停止位,8位数据位 */

        UCSR0C = (1<<UPM01)|(3<<UCSZ00);

}



void uartrx_isr(void)

{

        unsigned char i;

        CLI();

        UCSR0B &= 0x7f;

        i = USART_Receive();

        SEI();

        UCSR0B |= 0x80;

}



void USART_Transmit(unsigned char data)

{

        /* wait for empty transmit buffer */

        while(!(UCSR0A & 0x20))

        {

                ;

        }

        /* put data into buffer,sends the data */       

        UDR0 = data;

}



unsigned char USART_Receive(void)

{

        /* wait for data to be received */

        while(!(UCSR0A & 0x80))

        {

                ;

        }

        /* get and return received data from buffer */

        return UDR0;

}



void variable_init()

{

        adData = 0;



}


-----此内容被bbgood于2006-04-26,08:24:14编辑过

linmch 发表于 2006-10-27 11:03:26

谢谢分享,好东西,先谢了!

hl0716 发表于 2008-3-23 14:25:57

不错,记号,这个ad怎么样啊

spy2008 发表于 2008-3-23 17:45:40

mark

ivension 发表于 2008-4-1 11:51:25

mark

hetao7241 发表于 2008-4-1 13:47:44

这个AD和AD7705相比,那个要好一些,抗共模干扰,速度?

ivension 发表于 2008-4-2 08:37:28

mark..

flashnana 发表于 2008-4-29 16:13:01

unsigned int SPI_Read()
{
      int i,recData;
      recData = 0;
      clr_ss();
      clr_sck();
      clr_mosi();
      clr_miso();
      delay_us(2);
      for(i=0;i<24;i++)
      {
                set_sck();
                NOP();NOP();NOP();NOP();NOP();
                delay_us(5);
                clr_sck();
                delay_us(4);
                if(PINB&0b00001000)recData |= 0x01;
                else recData &= 0xfffe;
                if(i<16)recData <<= 1;
      }
      delay_us(10);
      set_ss();
      return recData;
}
这个函数看不懂,为什么读是i<24个循环,而在i<16的时候对recData进行处理,其余的不处理?

gerbee 发表于 2008-4-29 18:29:28

请问这个ad价格多少?供货稳定不

yibin818 发表于 2008-4-29 18:35:10

记号

ledatou 发表于 2011-4-6 11:26:37

哇塞~这个东西好啊~mark?

wisdom9285 发表于 2011-5-21 16:59:24

谢谢分享!!!

zztbb868 发表于 2011-6-26 14:58:32

mark

fengyuehaoran 发表于 2011-8-27 09:54:04

回复【7楼】flashnana梁娅娜
-----------------------------------------------------------------------
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671607HMX8MO.jpg
(原文件名:未命名.jpg)

xingzhong 发表于 2012-2-10 15:14:05

回复【13楼】fengyuehaoran 风月浩然
-----------------------------------------------------------------------

mark

dashuai145 发表于 2013-1-22 13:51:02

借用一下
页: [1]
查看完整版本: 用ATMEGA64 模拟SPI口接16为AD(ADS8345)