⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_2dpj_slave.c

📁 arm的功能测试模块
💻 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() 
注意:从机程序和主机程序基本相同,只是将该单片机该为从同步方式即可,2机运行时,从机先开机等待甲机SPI发送*/


//注: 内部函数_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&&SPI_RxBuf[3]==0xa4&&SPI_RxBuf[4]==0xb0&&SPI_RxBuf[5]==0x99
    &&SPI_RxBuf[6]==0x92&&SPI_RxBuf[7]==0x82&&SPI_RxBuf[8]==0xf8&&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 = 0xC5;      //SPI允许,从机模式,MSB,允许SPI中断,极性方式01,1/16系统时钟速率    
  SPSR = 0x00;    
  temp = SPSR;    
  temp = SPDR;    //清空SPI,和中断标志,使SPI空闲    
}    

//*************************************************************** 
//将数据0XFF送给SPDR,等待主机发送,(接收方接收到的第一个数据为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 + -