SPI协议工作过程详解文档,内含实例代码

发布者:GoldenDream最新更新时间:2019-10-28 来源: 51hei关键字:SPI协议  工作过程  AVR 手机看文章 扫描二维码
随时随地手机看文章

SPI:一种3线(有的没有SS线(选择主或从机模式))或4线的通信方式:
           MOSI:主机出从机进数据线
                 MISO:主机进从机从数据线
                 SCK: 时钟线
                 SS:  主从模式选择线
工作过程的理解:设置好相应的配置后就可以发送或接收数据,当放送或接收完成后就会是SPIF置位,此时如果开了中断就会就入中断服务程序。如果没开中断就可以通过查询该标志位来做相应的事。进入中段服务程序后,或者读(写)SPDR寄存器都可以清零SPIF标志位。从而可以开始下一次的传输
相应的寄存器
1:SCPR:控制寄存器:SPI的大部分设置
2:SPSR:标志寄存器:(查看一些标志(主要是SPIF位)和设置SPI速度)
3:SPDR:数据寄存器
SS引脚的说明:(实质就是当配置为输入时:是主机还是从机由输入的电平来决定)
从机模式: 当 SPI 配置为从机时,从机选择引脚 SS 总是为输入。SS 为低将激活 SPI 接口,MISO
成为输出 ( 用户必须进行相应的端口配置 ) 引脚,其他引脚成为输入引脚。当 SS 为高时
所有的引脚成为输入, SPI 逻辑复位,不再接收数据。
SS引脚对于数据包/字节的同步非常有用,可以使从机的位计数器与主机的时钟发生器同
步。当SS 拉高时SPI从机立即复位接收和发送逻辑,并丢弃移位寄存器里不完整的数据。

主机模式:当 SPI 配置为主机时 (SPCR 的 MSTR置位 ),用户可以决定 SS 引脚的方向。
若 SS 配置为输出,则此引脚可以用作普通的 I/O 口而不影响 SPI 系统。典型应用是用来
驱动从机的 SS 引脚。


如果 SS 配置为输入,必须保持为高以保证 SPI 的正常工作。若系统配置为主机,SS 为
输入,但被外设拉低,则 SPI 系统会将此低电平解释为有一个外部主机将自己选择为从
机。为了防止总线冲突, SPI 系统将实现如下动作:
1. 清零 SPCR 的 MSTR 位,使 SPI 成为从机,从而 MOSI 和 SCK变为输入。
2. SPSR 的 SPIF 置位。若 SPI 中断和全局中断开放,则中断服务程序将得到执行。
因此,使用中断方式处理 SPI 主机的数据传输,并且存在 SS 被拉低的可能性时,中断服
务程序应该检查 MSTR 是否为 "1”。若被清零,用户必须将其置位,以重新使能 SPI 主机
模式。
管脚配置

一:SCPR:控制寄存器:(SPI的大部分设置都在该寄存器)

二SPSR:标志寄存器:(查看一些标志和设置SPI速度,主要是用到SPIF这个标志位,接收完成和发送完成都会置位这个标志,进入中断服务程序或访问SPDR寄存  器都可以清零这个标志)

三SPDR:数据寄存器:



应用步骤:

1先根据是主还是从设置端口的模式(输入还是输出)

主机:SS   MOSI   SCK 为出 MISO为入

从机:SS   MOSI   SCK 为入 MISO 为出

2配置相应的寄存器(就三个寄存器,注意用到中断时要先开总中断)

3用中断或查询法发送或接收数据

注意:主机或者从机都可以发送或接收。发送完之后就可以马上发下一个数据了。接收也是只要接收完了也可以马上接收下一个数据了

一:发送:(一般用查询方式发送比较好:此时只要查询发送完毕的标志位SPIF是否置位)

常用:while(!(SPSR & (1<查询法:实质就是查询SPSR的SPIF位是否置位,接收完和发送完都可以置位,(如果开了中断的话就会进入相应的中断)

例子:

  • 主机发送(查询方式)(只要发送完毕了就可以继续发送了)

//主机模式下发送1-255

#include  

#define uint unsigned int

#define uchar unsigned char

void spi_init(void)

{

    PORTB |= (1<    DDRB |= (1<    SPCR = 0x73; //SPI使能,低位首发,主机模式,时钟模式00,上升沿采样;时钟速率Fosc/128

    SPSR = 0x00; //SPI2x=0

}

void SPI_send_data(char cData)

{

              PORTB &=~ (1<//              SPCR |= (1<              SPDR =cData;

              while(!(SPSR & (1<//              PORTB |= (1<

}


void Delay(uint z) //

{

   unsigned int i,j;

   for(i=z;i>0;i--)

    for(j=2000;j>0;j--);


}


int main(void)

{

              unsigned int i=0;

              spi_init();

              while(1)

              {

                            for(i=255;i>0;i--)

                            {

                                SPI_send_data(i);

                                          Delay(100);

                            }

              }

}



2从机接收(查询方式)


#include

#include

#define uchar              unsigned char

#define uint              unsigned int

void port_init(void)

{

              PORTA = 0x00;

              DDRA  = 0xFF;

              PORTB = 0xFF;

}


void spi_init(void)

{

    DDRB = (1<<5) |(1<<7);

              DDRB&=~(1<<4)|(1<<6);

              SPCR = 0x63; //                            SPI允许。从机方式

              SPSR = 0x00; //                            SPI倍速.频率为系统时钟

}


void init_devices(void)

{

              port_init();

              spi_init();

}

//主函数

int main(void)

              init_devices();

     while(1)

              {             

                            while(!(SPSR & (1<                            PORTA=SPDR;//把接收到的数据赋给A口

                            _delay_loop_2(900);

             

              }

}



3从机中断方式接收数据(注意:当进入中断服务程序后SPIF会自动清零)

/*中断方式接收数据*/

#include

#include

#define uchar              unsigned char

#define uint              unsigned int


//端口初始化

void port_init(void)

{

              PORTA = 0xFF;

              DDRA  = 0xFF;

}


void spi_init(void)

{

              PORTB |= (1<<4) | (1<<5) | (1<<6) | (1<<7); //

    DDRB |= (1<<5) | (1<<7) | (1<<4);     //Set MOSI, SCK AND SS as outputs 

    SPCR = 0xE3; //SPI中断使能,SPI使能,低位首发,从机模式,时钟模式00,上升沿采样;时钟速率Fosc/128

    SPSR = 0x00; //SPI2x=0

}


void init_devices(void)

{

              port_init();

              spi_init();

              sei();//开全局中断

}


//主函;

int main(void)

{

    init_devices();

              while(1);

}

//SPI中断函数

SIGNAL(SIG_SPI)

{


  PORTA=SPDR;


}

关键字:SPI协议  工作过程  AVR 引用地址:SPI协议工作过程详解文档,内含实例代码

上一篇:AVR128单片机最小系统串口,外部中断,跑马灯,uCOS-II移植
下一篇:AVR128_uC/OS-II 移植代码

推荐阅读最新更新时间:2024-11-05 15:24

数控电源AVR单片机C程序
编译环境为CodeWizardAVR #include mega8.h #include delay.h #include stdio.h #include stdlib.h #define Voltage_UP PINB.0 #define Voltage_Down PINB.2 #define UD PORTB.3 #define CS PORTB.5 #define INC PORTB.4 #define Voltage_LED PORTB.6 #define Current_LED PORTB.7 #define Current_Detect 0 #define Out_Detect 1 #define
[单片机]
单键开关电路在AVR单片机中的应用
 1 引 言   单键开关电路已经广泛应用于PDA、手机和电子词典等数码产品中,其实现方式多种多样。一般可采用RS触发器、计数器以及采用555集成电路等等。在单片机的一些实际应用中,以上的实现方式会增加整个电路的复杂度,不能达到简洁、实用的效果。本文将介绍一种可以在单片机应用中实现的,简易、稳定的轻触式单键开关电路。    2 电路原理   如图1所示,DC-DC为一个带有关断控制端的直流稳压电源芯片,MCU是一个单片机。当按下S1时,Q1和D1导通,稳压芯片工作,为单片机供电。单片机马上将相应的I/O引脚置为输出高,这时Q1和Q2导通,整个电路进入工作状态。而后单片机再将这个I/O引脚设置为输入,由于上拉电阻R4的存在,Q
[单片机]
单键开关电路在<font color='red'>AVR</font>单片机中的应用
AVR定时器程序
#include mega128.h //头文件 interrupt void timer0(void) //定时器中断服务函数 { TCNT0=0xff; // 重新设置TCNT0的初值 PORTD.4 = ~PORTD.4; // PD4反输出 } void main(void) { DDRD=0XF0; //PD口方向寄存器,高为输出,低为输入 PORTD=0XFF; //PD口数据寄存器全写1 TIMSK=0X01 ; //开定时器、计数器0 TCCR0=0X07; //定时器时钟控制寄存器 TCNT0=0XFF; //
[单片机]
AVR复位电路的设计
一、复位引脚的抗干扰设计: 与传统的51单片机相比,AVR单片机内置复位电路,并且在熔丝位里,可以控制复位时间,所以,AVR单片机可以不设外部上电复位电路,依然可以正常复位。 但是实际应用中,外界干扰对于RST引脚的影响是最大的,很容易引起单片机的意外复位。如果RST引脚外接线路较长,或是此引脚与板子的外部端口相连(比如,RST引脚常需要连接在ISP编程口上),此时就比较容易受到干扰。为增强抗干扰能力,可在RST引脚上接100nF电容到地,并且在RST与外部端口直接通过3K电阻相连,这样构成一个RC滤波电路可有效过滤串入复位脚的干扰,电路如下图所示。 需要注意的是,滤
[单片机]
采用AVR Flash微控制器的电动车窗防夹系统
汽车上可自动关闭的电动车窗或车门设备潜藏着卡死,挤压以及可能伤人的危险。它们必须能够反向移动以防止马达所施加的力超出正常限制。这种特性意味着必须持续监视速度、电流和玻璃的位置。 由于成本和简化的原因,本文所描述的系统使用普通的带有霍尔效应传感器的刷式马达。基于速度和扭矩导数的检测算法已通过健壮性和容错性的验证。该算法可用于所有带有A/D 转换器和通过变化引发中断的I/O 口的AtmelAVR Flash 微控制器。本文描述的是基本原理,Atmel网站上的应用笔记有关于实现的详细描述。 现代汽车中的电动设备 目前,在高端客用汽车中电子组件和系统在成本中已占20%以上。增加电子设备的数目可以更好的控制传感器和致动器,从而增
[单片机]
没有仿真器的情况下如何开发AVR
在开发单片机程序时,有许多人依赖于仿真机,一旦离开了仿真机开发程序时就感觉无从下手。其实对FLASH存贮器单片机,不要仿真机也能方便快速地开发程序。具体可以从以下几方面入手:   一、尽量使用高级语言开发系统程序 您有没有在写汇编程序时,标错一个标号而浪费您大把时间找错或跳转偏移量过大而不得不改动程序结构的经历。其实您如果使用高级语言开发程序,就不会有这样的痛苦。 在开发程序时,除了建立一个良好的开发文档外,使用语言的选择也很重要。有许多人认为使用汇编写程序比较精简,而用高级语言开发会浪费很多程序空间,其实这是一种误解。对一个有经验的,而且非常熟悉某种 单片机 的汇编高手而言,他是能写出比高级语言更精简的代码。而对汇编不是很熟的开
[嵌入式]
PIC单片机的工作过程
PIC单片机的工作过程: 单片机的工作过程实质上是执行程序的过程,单片机系统充电后,在程序计数器的控制下,按一定的顺序从程序存储器(ROM或EEPROM)中取出指令,经控制器分析后,送相应的部件去执行. 也就是说,单片机的工作过程是----------周而复始地取指令,分析指令和执行指令的过程.
[单片机]
一个avr单片机的汇编程序,注意几个宏指令
//晶振1MHz //LED接PB0 //使用定时器1,1024分频,0.5秒中断一次,LED闪烁一次 程序如下: .include m8def.inc .equ led =0 .equ flash =$60 .org $0000//中断向量表 rest: rjmp START INT0addre: ; External Interrupt0 Vector Address reti INT1addre: ; External Interrupt1 Vector Address reti OC2addre : ; Output Compare2 Interrupt Vector Address reti OVF2addre: ;
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved