用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编辑过 谢谢分享,好东西,先谢了! 不错,记号,这个ad怎么样啊 mark mark 这个AD和AD7705相比,那个要好一些,抗共模干扰,速度? mark.. 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进行处理,其余的不处理? 请问这个ad价格多少?供货稳定不 记号 哇塞~这个东西好啊~mark? 谢谢分享!!! mark 回复【7楼】flashnana梁娅娜
-----------------------------------------------------------------------
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671607HMX8MO.jpg
(原文件名:未命名.jpg) 回复【13楼】fengyuehaoran 风月浩然
-----------------------------------------------------------------------
mark 借用一下
页:
[1]