|
发表于 2008-5-7 13:43:02
|
显示全部楼层
我以前写的一个 SPI<--->UART 转换的程序:
中断发送
/**********************************************************************/
/* These are system macros and defines */
/**********************************************************************/
#define HIBYT(x) (x)/256
#define LOBYT(x) (x)%256
#define F_CPU 7372800 //oscillator frequency
#define BAUD 115200
#define BAUDRATE F_CPU/16/BAUD-1 //baudrate=fosc/16/rate-1
#include <avr/io.h>
#include <avr/interrupt.h>
/**********************************************************************/
/* UART Buffer Defines */
/**********************************************************************/
#define UART_RX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#define UART_TX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error UART RX buffer size is not a power of 2
#endif
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error UART TX buffer size is not a power of 2
#endif
/**********************************************************************/
/* SPI Buffer Defines */
/**********************************************************************/
#define SPI_RX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define SPI_RX_BUFFER_MASK ( SPI_RX_BUFFER_SIZE - 1 )
#define SPI_TX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define SPI_TX_BUFFER_MASK ( SPI_TX_BUFFER_SIZE - 1 )
#if ( SPI_RX_BUFFER_SIZE & SPI_RX_BUFFER_MASK )
#error SPI RX buffer size is not a power of 2
#endif
#if ( SPI_TX_BUFFER_SIZE & SPI_TX_BUFFER_MASK )
#error SPI TX buffer size is not a power of 2
#endif
/**********************************************************************/
/* These are microcontroller port and pin assgin */
/**********************************************************************/
//portb define
#define SS PB2 //spi ss input
#define MOSI PB3 //spi mosi input
#define MISO PB4 //spi miso output
#define SCK PB5 //spi sck input
/**********************************************************************/
/* These are the global variables */
/**********************************************************************/
//UART related buffers and variables
unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
volatile unsigned char UART_RxHead;
volatile unsigned char UART_RxTail;
unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
volatile unsigned char UART_TxHead;
volatile unsigned char UART_TxTail;
//SPI related buffers and variables
unsigned char SPI_RxBuf[SPI_RX_BUFFER_SIZE];
volatile unsigned char SPI_RxHead;
volatile unsigned char SPI_RxTail;
unsigned char SPI_TxBuf[SPI_TX_BUFFER_SIZE];
volatile unsigned char SPI_TxHead;
volatile unsigned char SPI_TxTail;
//SPI TX and RX flag
volatile unsigned char SPI_SendFlag = 0;
/*******************************
MCU initialize
*******************************/
void init_system(void)
{
DDRB = 0x00; //PORTB in,
PORTB = 0xFF; //enable pullup
DDRC = 0x00; //PORTC in,not used
PORTC = 0xFF; //enable pullup
DDRD = 0x00; //PORTD in,not used
PORTD = 0xFF; //enable pullup
ACSR |= (1<<ACD); //close Analog Comparator
}
/**********************************************************************/
/* initialize SPI */
/**********************************************************************/
/* initialize spi */
void init_SPI( void )
{
//set MISO as output
DDRB |= (1<<MISO);
//set MISO output low
PORTB &= ~(1<<MISO);
//set SS as input
DDRB &= ~(1<<SS);
//set SS pull high
PORTB |= (1<<SS);
//SPI interrupt and SPI enable;
//Slave SPI,MSB send first,fall edge
SPCR = (1<<SPIE) | (1<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (1<<CPHA);
SPDR = 0; //clear SPDR data
/* flush buffer */
SPI_RxTail = 0;
SPI_RxHead = 0;
SPI_TxTail = 0;
SPI_TxHead = 0;}
void SPI_DATA(unsigned char dat)
{
SPDR = dat;
}
/**********************************************************************/
/* interrupt of SPI send complele */
/**********************************************************************/
SIGNAL(SIG_SPI)
{
unsigned char data;
unsigned char tmphead,tmptail;
//received SPI data,if no data then received 0
data = SPDR; /* read the received data */
/* calculate buffer index */
tmphead = ( SPI_RxHead + 1 ) & SPI_RX_BUFFER_MASK;
SPI_RxHead = tmphead; /* store new index */
if ( tmphead == SPI_RxTail )
{
/* ERROR! Receive buffer overflow */
}
SPI_RxBuf[tmphead] = data; /* store received data in buffer */
//send SPI data,if no data then send 0
/* check if all data is transmitted */
if ( SPI_TxHead != SPI_TxTail )
{
/* calculate buffer index */
tmptail = ( SPI_TxTail + 1 ) & SPI_TX_BUFFER_MASK;
SPI_TxTail = tmptail; /* store new index */
data = SPI_TxBuf[tmptail]; /* get data */
}
else
{
data = 0;
SPI_SendFlag = 0; //clear send flag
}
SPDR = data; //send spi data
}
/**********************************************************************/
/* SPI Buffer Read and write and Buffer check functions */
/**********************************************************************/
unsigned char SPIReceiveByte( void )
{
unsigned char tmptail;
while ( SPI_RxHead == SPI_RxTail ) /* wait for incomming data */
;
tmptail = ( SPI_RxTail + 1 ) & SPI_RX_BUFFER_MASK;/* calculate buffer index */
SPI_RxTail = tmptail; /* store new index */
return SPI_RxBuf[tmptail]; /* return data */
}
void SPITransmitByte( unsigned char data )
{
unsigned char tmphead;
tmphead = ( SPI_TxHead + 1 ) & SPI_TX_BUFFER_MASK; /* calculate buffer index */
while ( tmphead == SPI_TxTail )/* wait for free space in buffer */
;
SPI_TxBuf[tmphead] = data; /* store data in buffer */
SPI_TxHead = tmphead; /* store new index */
}
unsigned char SPIDataInReceiveBuffer( void )
{
return ( SPI_RxHead != SPI_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/**********************************************************************/
/* initialize UART */
/**********************************************************************/
void init_UART( void )
{
//UBRR = BAUDRATE; /* set the baud rate */
UBRRL = LOBYT(BAUDRATE);
UBRRH = HIBYT(BAUDRATE);
/* enable UART receiver and transmitter, and
receive interrupt */
//UART 115200,8,N,1 type
UCSRA = 0;
UCSRB = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
UCSRC = ( (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) );
/* flush buffer */
UART_RxTail = 0;
UART_RxHead = 0;
UART_TxTail = 0;
UART_TxHead = 0;
}
/**********************************************************************/
/* interrupt of UART RX. */
/**********************************************************************/
SIGNAL (SIG_UART_RECV)
{
unsigned char data;
unsigned char tmphead;
data = UDR; /* read the received data */
/* calculate buffer index */
tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
UART_RxHead = tmphead; /* store new index */
if ( tmphead == UART_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART_RxBuf[tmphead] = data; /* store received data in buffer */
}
/**********************************************************************/
/* interrupt of UART UDRIE. */
/**********************************************************************/
SIGNAL (SIG_UART_DATA)
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART_TxHead != UART_TxTail )
{
/* calculate buffer index */
tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
UART_TxTail = tmptail; /* store new index */
UDR = UART_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSRB &= ~(1<<UDRIE); /* disable UDRE interrupt */
}
}
/**********************************************************************/
/* UART Buffer Read and write and Buffer check functions */
/**********************************************************************/
unsigned char UARTReceiveByte( void )
{
unsigned char tmptail;
while ( UART_RxHead == UART_RxTail ) /* wait for incomming data */
;
tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;/* calculate buffer index */
UART_RxTail = tmptail; /* store new index */
return UART_RxBuf[tmptail]; /* return data */
}
void UARTTransmitByte( unsigned char data )
{
unsigned char tmphead;
tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK; /* calculate buffer index */
while ( tmphead == UART_TxTail )/* wait for free space in buffer */
;
UART_TxBuf[tmphead] = data; /* store data in buffer */
UART_TxHead = tmphead; /* store new index */
UCSRB |= (1<<UDRIE); /* enable UDRE interrupt */
}
unsigned char UARTDataInReceiveBuffer( void )
{
return ( UART_RxHead != UART_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/**********************************************************************/
/*main program */
/**********************************************************************/
int main(void)
{
unsigned char temp;
init_system(); //init MCU
init_UART(); //init UART
init_SPI(); //init SPI
sei(); //enable global interrupt
while(1)
{
// wdt_reset(); //reset wdt
if( SPIDataInReceiveBuffer() ) //if SPI received data
{
temp = SPIReceiveByte(); //get SPI data
UARTTransmitByte(temp); //send to UART buffer
}
if( UARTDataInReceiveBuffer() ) //if UART received data
{
if( SPI_SendFlag == 0 ) //if send first SPI data
{
temp = UARTReceiveByte(); //get uart data
SPI_DATA(temp); //send SPI SPCR to start SPI
SPI_SendFlag = 1; //SPI send status
// UARTTransmitByte(temp); //test SPI send
}
else //if send other SPI data continued
{
temp = UARTReceiveByte(); //get uart data
SPITransmitByte(temp); //send to SPI buffer
// UARTTransmitByte(temp); //test SPI send
}
}
}
}
//end of program |
|