?? spi_2dpj_master.c
字號:
/*****************************************************
**** AVR SPI總線使用范例(兩個mega16) ***
**** 作者: liugangdi ***
**** 編譯器:WINAVR20050214 ***
**** 日期:2005.11.15 ***
******************************************************/
/*
主機功能簡介:通過SPI實現兩機通訊, 采用中斷方式實現雙全工通訊。
本例用兩MEGA16實現,連接為:
MISO----MISO
MOSI----MOSI
SCK ----SCK
/SS ----/SS
將要發送的數據加載到發送緩沖區的函數fill_tx_buffer()
和從接收緩沖區讀出數據的函數read_rx_buffer() */
//注: 內部函數_delay_ms() 最高延時 262.144mS@1MHz
// ffor()/while()語句計算延時時間較麻煩。
// 為了使 _delay_ms()函數的延時正確,須在makefile中設定F_CPU為實際的系統時鐘頻
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#define uint unsigned int
#define uchar unsigned char
#define SPI_RX_BUFFER_SIZE 11
#define SPI_RX_BUFFER_MASK SPI_RX_BUFFER_SIZE - 1
#define SPI_TX_BUFFER_SIZE 11
#define SPI_TX_BUFFER_MASK SPI_TX_BUFFER_SIZE - 1
unsigned char SPI_RxBuf[SPI_RX_BUFFER_SIZE];
volatile unsigned char SPI_RxHead;
unsigned char SPI_TxBuf[SPI_TX_BUFFER_MASK];
volatile unsigned char SPI_TxHead;
uchar Tx_counter,spi_trans_com;
//***************************************************
//七段數碼管顯示函數
//***************************************************
void disp(unsigned char data)
{ DDRB=0xFF;
DDRA=0xFF;
PORTA&=~(1<<6);
PORTB=data;
}
//***************************************************
// 要發送的數據加載到發送緩沖區的函數fill_tx_buffer()
//***************************************************
void fill_tx_buffer(void)
{
uchar SPI_TxBuf[SPI_TX_BUFFER_MASK]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
}
//***************************************************
// 從接收緩沖區讀出數據的函數read_rx_buffer()
//***************************************************
void read_rx_buffer(void)
{
/*for(uint i=1;i<SPI_TX_BUFFER_SIZE;i++)
{disp(SPI_RxBuf[i]);
for (uint k=0;k<50 ;k++) _delay_ms(20);}*/
if(SPI_RxBuf[1]==0xc0 && SPI_RxBuf[2]==0xf9)
if (SPI_RxBuf[3]==0xa4 && SPI_RxBuf[4]==0xb0)
if(SPI_RxBuf[5]==0x99 && SPI_RxBuf[6]==0x92 )
if(SPI_RxBuf[7]==0x82 && SPI_RxBuf[8]==0xf8)
if (SPI_RxBuf[9]==0x80 && SPI_RxBuf[10]==0x90)
PORTC&=~(1<<5); //如果接收的都正確則燈點亮
}
//******************************************
// SPI 中斷服務程序 interrupt [SPI_STC]:11
//******************************************
SIGNAL (SIG_SPI)
{
SPI_RxBuf[SPI_RxHead] = SPDR; //從ISP口讀出收到的字節
if (SPI_RxHead == SPI_RX_BUFFER_MASK) //如果是接收幀的最后一個數據
{
SPI_RxHead = 0; //已接收數據還原
spi_trans_com=1; //置接收完成標志
}
else
{
SPI_RxHead++; //已接收數據計數器加1
}
if (Tx_counter) //如果發送緩沖區中有待發的數據
{
--Tx_counter;
SPDR=SPI_TxBuf[SPI_TxHead]; //發送一個字節數據,并調整指針
if (++SPI_TxHead ==SPI_TX_BUFFER_MASK)
{SPI_TxHead = 0;
Tx_counter=SPI_TX_BUFFER_MASK;
}
}
}
//**************************************************************
// SPI 初始化 (MEGA16 PB4——/SS,PB5——MOSI,PB6——MISO,PB7——SCK)
//**************************************************************
void spi_init(void)
{
unsigned char temp;
DDRB = 0xB0; //MISO=input and MOSI,SCK,SS = output
PORTB = 0x40; //MISO上拉電阻有效
SPCR = 0xD5; //SPI允許,主機模式,MSB,允許SPI中斷,極性方式01,1/16系統時鐘速率
SPSR = 0x00;
temp = SPSR;
temp = SPDR; //清空SPI,和中斷標志,使SPI空閑
}
//***************************************************************
//發送數據0XFF,啟動發送,(接收方接收到的第一個數據為0xFF應忽略 )
//***************************************************************
void spi_send(void)
{
fill_tx_buffer(); //調用fill_tx_buffer函數,將要發送的數據加載到發送緩沖區
spi_init(); //初始化spi為主方式
SPDR=0xFF; //開始發送,接收方接收到的第一個數據為0xFF應忽略
sei(); //開總中斷
SPCR|=(1<<SPIE)|(1<<SPE); //使能SPI,開SPI中斷
SPI_TxHead = 0; //已發送數據計數器清0
}
int main(void)
{
PORTC=0xFF;
DDRC=0xFF; //PC口設為輸出高電平,燈滅
SPI_RxHead=0;
SPI_TxHead=0;
Tx_counter=SPI_TX_BUFFER_MASK;
spi_send();
while(1)
{
if(spi_trans_com==1) //如果接收完成標志為1,表明有所數據已接收
{
read_rx_buffer(); //調用read_rx_buffer函數,將接收到的數據從接收緩沖區讀出
spi_trans_com=0; //讀完清除接收完成標志
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -