51/AVR单片机技术驿站!  <在线翻译>     便利工具    特色网址   无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

当前位置:首页 > 单片机技术文章 > AVR单片机 > 详细内容
AVR单片机SPI实例(mega8515)
发布时间:2009/7/22  阅读次数:1530  字体大小: 【】 【】【

来源:网络 源鹏 发表

AVR单片机SPI实例(mega8515)

--------------------------------------------------------------------------------

东营科技开发网

本人的一个SPI的实例,通过SPI实现两机通讯,
采用中断方式实现双全工通讯。
本例用两MEGA8515实现,连接为:
MISO----MISO
MOSI----MOSI
SCK ----SCK
/SS ----/SS
将要发送的数据加载到发送缓冲区的函数fill_tx_buffer
和从接收缓冲区读出数据的函数read_rx_buffer未给出,
根据各自需求请自己完成。

#define SPI_RX_BUFFER_SIZE 10
#define SPI_RX_BUFFER_MASK ( SPI_RX_BUFFER_SIZE - 1 )
#define SPI_TX_BUFFER_SIZE 10
#define SPI_TX_BUFFER_MASK ( SPI_TX_BUFFER_SIZE - 1 )
#define SET_SPI_MODE PORTB.4
#define SPI_MODE PINB.4

static unsigned char SPI_RxBuf[SPI_RX_BUFFER_SIZE];
static volatile unsigned char SPI_RxHead;
static unsigned char SPI_TxBuf[SPI_TX_BUFFER_SIZE];
static volatile unsigned char SPI_TxHead;
//******************************************
// SPI 中断服务程序
//******************************************
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
if(spi_m==0)                                                                         //如果spi_m为0,表明是接收状态
   {
     data = SPDR;                                                                   //读入接受到的数据  
           SPI_RxBuf[SPI_RxHead-1] = data;                       //将接收到的数据存入接收缓存区
           if ( SPI_RxHead   == SPI_RX_BUFFER_MASK )     //如果是接收帧的最后一个数据    
               {
                 SPI_RxHead = 0;                                                 //已接收数据还原
                 MSTR=1;                                                                 //接收完成,将SPI设回主方式
                 spi_trans_com=1;                                               //置接收完成标志
               }
           else
               {      
                 SPI_RxHead++;                                                     //已接收数据计数器加1
               }
      
   }
else                                                                                         //如果spi_m为1,表明是发送状态
     {
                                                                              
             if ( SPI_TxHead <= SPI_TX_BUFFER_MASK)       //如果要发送的数据还未全部发完
               {      
                 SPDR = SPI_TxBuf[SPI_TxHead];                     //从发送缓存区取数发送
                 SPI_TxHead++;                                                     //已发送数据计数器加1
               }
             else                                                                           //如果要发送的数据已全部发完
                 {
                     SPI_TxHead=0;                                                 //已发送数据计数器还原
                     DDRB.4=0;
                     SET_SPI_MODE=1;                                             //释放总线,以便接收方进入主发送。
                     spi_m=0;                                                            
                     spi_sending=0;                                               //清空发送中标记
                 }
        
     }

}

//******************************************
// SPI 初始化
//******************************************
void InitSPI(void)
{

SPCR=0x52;
SPI_RxHead = 0;
SPI_TxHead = 0;

}

//******************************************
//发送数据
//******************************************
void spi_send(void)
{
if(spi_sending==0)           //发送中标记为0,表明spi发送空闲
     {
        
       fill_tx_buffer();     //调用fill_tx_buffer函数,将要发送的数据加载到发送缓冲区
       while(PINB.4==0)       //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
         {;}
        
       InitSPI();                   //初始化spi为主方式
       DDRB.4=1;  
       SET_SPI_MODE=0;         //将PORTB.4拉低,强迫接收方进入从接收方式
       spi_m=1;                       //置spi_m标志表明为发送状态
       delay_us(10);
       spi_sending=1;           //置spi_sending标志表明发送进行中
       SPDR=0xFF;                   //开始发送,接收方接收到的第一个数据为0xFF应忽略
       SPIE=1;                         //开SPI中断,
       SPI_TxHead = 0;         //已发送数据计数器清0
     }
}

void main(void)
{

...
while(1)
   {
     ...
      
     if(spi_trans_com==1) //如果接收完成标志为1,表明有所数据已接收
         {
           read_rx_buffer(); //调用read_rx_buffer函数,将接收到的数据从接收缓冲区读出
           spi_trans_com=0;   //读完清除接收完成标志
         }
     ...

   }  

}
  

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:522422171
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号