搜索
bottom↓
12
返回列表 发新帖
楼主: Paul

代码共享:AVR单片机SPI实例

[复制链接]

出0入0汤圆

发表于 2009-7-16 20:52:00 | 显示全部楼层
学习ING !!呵呵,我也初学SPI!

出0入0汤圆

发表于 2009-7-16 22:15:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-16 23:34:54 | 显示全部楼层
必须mark

出0入0汤圆

发表于 2009-7-17 15:55:30 | 显示全部楼层
好贴,顶一个

出0入0汤圆

发表于 2009-7-18 08:59:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-22 10:02:33 | 显示全部楼层
学习,学习,学习

出0入0汤圆

发表于 2009-7-22 11:51:36 | 显示全部楼层
Must mark, keep learning

出0入0汤圆

发表于 2009-7-22 12:31:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-6 23:58:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-7 07:55:53 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2009-8-11 11:23:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-11 14:14:13 | 显示全部楼层
顶了又顶~

出0入0汤圆

发表于 2009-8-16 16:52:06 | 显示全部楼层
此代码为本人原创,如有改进请不吝指正。
==================================================
难道楼主是:《AVR单片机原理及测控工程应用》的作者??

《AVR单片机原理及测控工程应用》78 页

2.4.5两个AVR实现硬件SPI双机通信

例程中,将要发送的数据加载到发送缓冲区的函数fill_tx_buffer
和从接收缓冲区读出数据的函数read_rx_buffer未给出, 根据各自需求请自己完成。
==============================================================================
#define SS     4
#define MOIS   5
#define MISO   6
#define SCK    7

#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 PIN_SS_L    {PINB&(~BIT(SS))}
unsigned char SPI_RxBuf[SPI_RX_BUFFER_SIZE];
volatile unsigned char SPI_RxHead = 0;
unsigned char SPI_TxBuf[SPI_TX_BUFFER_SIZE];
volatile unsigned char SPI_TxHead = 0;

volatile  unsigned char Spi_Trans_Com = 0;//接收完成标志
volatile  unsigned char Spi_Mode = 0;   //接收或者发送状态标志
volatile  unsigned char Spi_Sending = 0;//正在发送标志


void Init_Spi(void)
{
   SPCP = BIT(SPE)|BIT(MSTR);//初始化为主机方式
   SPI_TxHead = 0;
   SPI_RxHead = 0;
}

void Spi_Send(void)
{
   if (Spi_Sending == 0)//发送中标志为0,表明SPI发送空闲
   {
      Fill_Tx_Buffer();//调用Fill_Tx_Buffer()函数,将要发送的数据加载到发送缓冲区
          while (PIN_SS_L==0);//ss为低,总线被接受方式占用,等待接收方式发送
          Init_Spi();//初始化为主机方式
          DDRB|=BIT(SS)|BIT(MOIS)|BIT(MISO);
          PORTB &= ~BIT(SS);//降SS拉低强迫接收方进入接收方式
          Spi_Mode = 1;
          _delay_us(10);
          Spi_Sending = 1;
          SPDR = 0XFF;
          
          SPCR |= 1<<SPIE;   //开SPI中断
          SPI_TxHead = 0;//已发送数据计数器清零
          
          
          
   }
}

//一个字节发送或接收完成中断
SIGNAL(SIG_SPI)
{
        unsigned char data = 0;
        if (Spi_Mode == 0)//如果Spi_Mode = 0为0,表明是接收状态
        {
          data = SPDR;    //读取接收到的数据
          SPI_RxBuf[SPI_RxHead-1] =data;//降接收到的数据存入接收缓冲区
          if (SPI_RxHead==SPI_RX_BUFFER_MASK)//如果是接收帧的最后一个数
          {
             SPI_RxHead = 0;//已接收数据还原
                 SPCR |= 1<<MSTR; //接收完成,将SPI设置成主方式
                 Spi_Trans_Com = 1;//设置接收完成标志
          }
          else
          {
           SPI_RxHead++;  //已发送计数器加一
          }
          
        }
       
    else //如果是Spi_Mode = 1,表明是发送状态
        {
          if (SPI_TxHead<=SPI_TX_BUFFER_MASK)
          {
            SPDR = SPI_TxBuf[SPI_TxHead];
                SPI_TxHead++;
          }
          else
          {
            SPI_TxHead = 0; //已发送数据计数器还原
                DDRB &= ~BIT(SS);
                PORTB |=BIT(SS); //释放总线以接收方式进入主发送
                Spi_Mode = 0;        //进入接收状态
                Spi_Sending = 0;//清空发送中标志
               
          }
        }
}

出0入0汤圆

发表于 2009-8-16 18:33:33 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-8-16 20:10:50 | 显示全部楼层
刚学。。不是很清楚、、先谢了!!

出0入0汤圆

 楼主| 发表于 2009-8-16 22:43:16 | 显示全部楼层
回romanticye:
    我不是写那本书的人.请看一下我发这个贴的日期:2005-01-05,16:13:55 ,我不知道《AVR单片机原理及测控工程应用》是什么时候出版的,但我可以肯定不会早过发贴的日期.
   《AVR单片机原理及测控工程应用》作者是哪位?

出0入0汤圆

发表于 2009-8-17 01:14:30 | 显示全部楼层
LZ你好!这是主从都可以用的程序?

请问M16可以套用你这个程序吗?

好像都差不多,只要加个头文件就可以?

出0入0汤圆

 楼主| 发表于 2009-8-17 08:38:38 | 显示全部楼层
是的,主从都用这个程序,基本适合所有AVR.
92楼有一个实例.
顶楼的代码通讯中如有一方复位将导致以后一直出错,92楼的就没有这个问题了.

出0入0汤圆

发表于 2009-8-17 16:48:17 | 显示全部楼层
不错,顶一下,

出0入0汤圆

发表于 2009-9-2 15:18:16 | 显示全部楼层
好东东,顶

出0入0汤圆

发表于 2009-9-4 16:38:25 | 显示全部楼层
顶一下,好贴!

出0入0汤圆

发表于 2009-9-9 14:21:34 | 显示全部楼层
我这有一本《AVR单片机原理及测控工程应用》--基于mega48/mega16 刘海成编著
上面的SPI代码和楼主的一模一样

不知道是不是一个人

出0入0汤圆

发表于 2009-9-18 21:45:26 | 显示全部楼层
那本書是08年出的,而lz的是05年,我感覺是lz本人的原創

出0入0汤圆

发表于 2009-9-19 00:25:21 | 显示全部楼层
不错

出0入0汤圆

发表于 2009-9-20 10:57:15 | 显示全部楼层
好东西正在做谢谢!

出0入10汤圆

发表于 2009-9-20 12:33:13 | 显示全部楼层
收藏

出0入0汤圆

发表于 2009-9-20 13:25:20 | 显示全部楼层
mark1

出0入0汤圆

发表于 2009-9-20 13:26:11 | 显示全部楼层
mark1

出0入0汤圆

发表于 2009-9-21 15:23:53 | 显示全部楼层
好東西,頂頂!!!

出0入0汤圆

发表于 2009-9-21 15:39:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-22 17:48:07 | 显示全部楼层
看了樓主92樓的程序, 有點暈, 不知道如何執行,流程?
知道,看得懂的請說一下...

while (1)
      {
      
      if(spi_trans_com==1)         
         read_rx_buffer();
      if(send_failure==1)
         spi_send();
      };
都沒看到哪個機子發送初始數據, 究竟主從是入何操作數據?(發送,接收) ,沒看到有誰開始 發數據.........

出0入0汤圆

发表于 2009-10-7 14:21:37 | 显示全部楼层
好难

出0入0汤圆

发表于 2009-10-16 17:21:06 | 显示全部楼层
ding

出0入0汤圆

发表于 2009-11-3 20:48:03 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2009-11-4 00:27:58 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2009-12-9 22:00:09 | 显示全部楼层
好贴,正在学习中。。。

出0入0汤圆

发表于 2009-12-9 22:30:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-9 22:42:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-11 10:54:08 | 显示全部楼层
顶你格非

出0入0汤圆

发表于 2010-1-25 09:23:54 | 显示全部楼层
9494 狂挺你

出0入0汤圆

发表于 2010-1-25 17:41:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-25 21:04:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-25 21:35:40 | 显示全部楼层
收藏先

出0入0汤圆

发表于 2010-1-26 17:19:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-27 14:31:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-31 16:33:24 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-4-12 16:34:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-22 15:46:44 | 显示全部楼层
不错。

出0入0汤圆

发表于 2010-4-22 17:37:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-22 17:43:00 | 显示全部楼层
mark

出0入4汤圆

发表于 2010-5-7 21:49:02 | 显示全部楼层
好贴,实用性很强,谢谢Paul

出0入0汤圆

发表于 2010-5-7 23:11:12 | 显示全部楼层
不错!

出0入0汤圆

发表于 2010-5-7 23:49:44 | 显示全部楼层
ding

出0入0汤圆

发表于 2010-5-18 21:51:30 | 显示全部楼层
有没有51的SPI的

出0入0汤圆

发表于 2010-8-17 00:09:14 | 显示全部楼层
有个问题:
就是如果主从机都用那个代码  那怎么定义SS脚呢  连接的主从机不是电平一样吗  ??

    while(PINB.4==0)    //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。
     {;}

这句怎么初始化理解??

出0入0汤圆

发表于 2010-8-17 08:30:08 | 显示全部楼层
回复【楼主位】Paul
-----------------------------------------------------------------------

dddddddddddddd

出0入0汤圆

发表于 2010-8-17 11:34:48 | 显示全部楼层
有个问题:
就是如果主从机都用那个代码  那怎么定义SS脚呢  连接的主从机不是电平一样吗  ??

    while(PINB.4==0)    //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。  
     {;}

这句怎么初始化理解??

急急急急急!!!!!!!!!

出0入0汤圆

 楼主| 发表于 2010-8-17 12:48:23 | 显示全部楼层
没有通讯时两个都是一样的都在主模式,SS都是输入上拉,任何一方想发就把SS设为输出并拉低,这样另一方就进入从模式了。看看AVR的手册,讲的很明白的。

出0入0汤圆

发表于 2010-8-17 12:55:19 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-8-17 12:55:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-18 15:55:42 | 显示全部楼层
M

出0入0汤圆

发表于 2010-8-18 17:09:46 | 显示全部楼层
mark  好贴!

出0入0汤圆

发表于 2010-8-18 17:54:39 | 显示全部楼层
我的意思是两通信机 的SS脚连在一起  自然他的电平就是一样的啊  读取PINA.4的时候  怎么去分辨主从机呢???

高手指点????????

出0入0汤圆

发表于 2010-8-18 23:54:06 | 显示全部楼层
谢谢分享~

出0入0汤圆

发表于 2010-8-20 00:14:07 | 显示全部楼层
有个问题:  

就是如果主从机都用那个代码  
    while(PINB.4==0)    //如果PINB.4为低,表明总线被接受方占用,等待直至接受方发送完成。   
     {;}  

那怎么定义SS脚呢  连接的主从机不是电平一样吗  ??  

怎么初始化理解??

出0入0汤圆

发表于 2010-8-24 16:22:54 | 显示全部楼层
怎么就没人回答呢
俺比较菜啊

高手指点下啊

急急急急急!!!!!!!!!

出0入0汤圆

发表于 2010-8-25 10:28:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-25 12:26:07 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-8-27 15:51:16 | 显示全部楼层
回复【171楼】wulong  
-----------------------------------------------------------------------

其实你和我想法一样的,,我也不太明白。。其实按道理说主从机的SS线是连到一起的,那么电平应该是一样的才对啊。。(本人没有用过AVR硬件SPI。。呵呵。。今天研究了一下,所以又点不太明白)

出0入0汤圆

发表于 2010-10-20 20:54:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-28 01:22:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-28 18:49:09 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-12-4 16:43:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-7 10:08:46 | 显示全部楼层
写得不错

出0入0汤圆

发表于 2010-12-7 11:44:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-10 19:15:54 | 显示全部楼层
有年头的贴子!

出0入0汤圆

发表于 2011-3-22 23:46:14 | 显示全部楼层
好,MARK

出0入0汤圆

发表于 2011-3-23 09:56:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-23 22:32:52 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-3-29 21:31:10 | 显示全部楼层
顶!

出0入0汤圆

发表于 2011-5-23 10:36:55 | 显示全部楼层
回复【92楼】Paul
-----------------------------------------------------------------------
有个问题不太明白:
在 read_rx_buffer()函数中,以下两句代码:
DDRB.2=1;   
SET_SPI_BUS_MODE=0;                     //处理数据中,禁止发送方发送
如此,发送方岂不是一下子变为从机?而且进入了一次SPI中断?那进入中断后的数据(无效数据)怎么处理?

出0入0汤圆

发表于 2011-8-22 14:28:51 | 显示全部楼层
学习中,谢谢楼主的无私奉献!

出0入0汤圆

发表于 2011-8-22 17:32:50 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-8-27 20:17:01 | 显示全部楼层
看看

出0入0汤圆

发表于 2013-2-26 20:47:18 | 显示全部楼层
谢谢楼主分享   我写STM32与FPGA通信  都10天了   数据总数不全正确  希望能在这里找到错误

出0入0汤圆

发表于 2015-10-20 14:26:48 | 显示全部楼层
楼主有没有用单片机的SPI结合CH432T芯片来扩展串口呢?我最近在做这个,但是网上很少有这方面的例程,搞得我无从下手
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 05:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表