魔兽燃烧的远征:avr单片机SPI串行外设接口初始化配置及说明

来源:百度文库 编辑:九乡新闻网 时间:2024/05/01 09:41:57
作者:未知    AVR单片机来源:网络    点击数: 540    更新时间:2010-3-11    
串行外设接口 SPI允许 ATmega16 和外设或其他 AVR 器件进行高速的同步数据传输。7 种可编程的比特率,主机或从机操作,全双工, 3 线同步数据传输,可以从闲置模式唤醒 ,作为主机时具有倍速模式 (CK/2)
/*
PB7       SCK (SPI 总线的串行时钟 )
PB6       MISO (SPI 总线的主机输入 / 从机输出信号 )
PB5       MOSI (SPI 总线的主机输出 / 从机输入信号 )
PB4       SS (SPI 从机选择引脚 )
SCK – 端口 B, Bit 7    SCK :SPI 通道的主机时钟输出,从机时钟输入端口。工作于从机模式时,不论 DDB7 设
置如何,这个引脚都将设置为输入。工作于主机模式时,这个引脚的数据方向由 DDB7 控
制。设置为输入后,上拉电阻由 PORTB7 控制。
MISO – 端口 B, Bit 6   MISO :SPI 通道的主机数据输入,从机数据输出端口。工作于主机模式时,不论 DDB6 设
置如何,这个引脚都将设置为输入。工作于从机模式时,这个引脚的数据方向由 DDB6 控
制。设置为输入后,上拉电阻由 PORTB6 控制。
MOSI – 端口 B, Bit 5   MOSI : SPI 通道的主机数据输出,从机数据输入端口。工作于从机模式时,不论 DDB5 设
置如何,这个引脚都将设置为输入。当工作于主机模式时,这个引脚的数据方向由 DDB5
控制。设置为输入后,上拉电阻由 PORTB5 控制。
SS – 端口 B, Bit 4     SS: 从机选择输入。工作于从机模式时,不论 DDB4设置如何,这个引脚都将设置为输入。
当此引脚为低时 SPI 被激活。工作于主机模式时,这个引脚的数据方向由 DDB4 控制。设
置为输入后,上拉电阻由 PORTB4 控制。
简单定义:
引脚   方向SPI主机                     方向SPI从机
MOSI   用户定义                         输入
MISO   输入                             用户定义
SCK    用户定义                         输入
SS     用户定义                         输入
//*************************************SPI 控制寄存器SPCR***************************************
SPI 控制寄存器SPCR
bit7      bit6      bit5      bit4      bit3     bit2      bit1      bit0
SPIE      SPE       DORD     MSTR       CPOL     CPHA      SPR1      SPR0
SPIE: 使能SPI 中断
置位后,只要SPSR 寄存器的SPIF 和SREG 寄存器的全局中断使能位置位,就会引发
SPI 中断
SPE: 使能SPI
SPE 置位将使能SPI。进行任何SPI 操作之前必须置位SPE
DORD: 数据次序
DORD 置位时数据的LSB 首先发送;否则数据的MSB 首先发送
MSTR: 主/ 从选择
MSTR置位时选择主机模式,否则为从机。如果MSTR为"1”,SS配置为输入,但被拉
低,则MSTR 被清零,寄存器SPSR 的SPIF 置位。用户必须重新设置MSTR 进入主机
模式。
CPOL: 时钟极性
CPOL 置位表示空闲时SCK 为高电平;否则空闲时SCK 为低电平。
CPOL 功能
CPOL                   起始沿结束沿                         CPOL
0                    上升沿下降沿                           0
1                    下降沿上升沿                           1
SPR1, SPR0: SPI 时钟速率选择1 与0
确定主机的SCK 速率。SPR1 和SPR0 对从机没有影响。SCK 和振荡器的时钟频率fosc
关系如下表所示:
SCK 和振荡器频率的关系
SPI2X                SPR1                SPR0                 SCK
0                    0                   0                fosc/4
0                    0                   1                fosc/16
0                    1                   0                fosc/64
0                    1                   1               fosc/128
1                    0                   0                fosc/2
1                    0                   1                fosc/8
1                    1                   0                fosc/32
1                    1                   1                fosc/64
CPHA :数据模式
决定数据是在 SCK 的起始沿采样还是在 SCK 的结束沿采样
相对于串行数据, SCK 的相位和极性有4 种组合。CPHA 和CPOL 控制组合的方式。SPI
数据传输格式。每一位数据的移出和移入发生于SCK不同的信号跳变沿,以保证有足够的时
间使数据稳定。
CPOL 与CPHA 功能
模式             起始沿       结束沿       SPI
CPOL 0 CPHA=0    采样(上升沿) 采样(下降沿)    0
CPOL 0 CPHA=1    设置(上升沿) 采样(下降沿)    1
CPOL 1 CPHA=0    采样(下降沿) 采样(上升沿)    2
CPOL 1 CPHA=1    采样(下降沿) 采样(上升沿)    3
///****************************SPI 状态寄存器SPSR*********************************************
SPI 状态寄存器SPSR
bit7      bit6      bit5      bit4      bit3      bit2      bit1      bit0
SPIF      WCOL       –        –        –         –        –      SPI2X
SPIF: SPI 中断标志
串行发送结束后,SPIF 置位。若此时寄存器SPCR 的SPIE 和全局中断使能位置位
SPI中断即产生。如果SPI 为主机, SS 配置为输入,且被拉低, SPIF 也将置位
进入中断服务程序后SPIF自动清零。或者可以通过先读SPSR,紧接着访问SPDR来对
SPIF清零。
WCOL: 写碰撞标志
在发送当中对SPI 数据寄存器SPDR写数据将置位WCOL。WCOL可以通过先读SPSR,紧接
着访问SPDR 来清零。
Bit 5..1 – Res: 保留
保留位,读操作返回值为零。
SPI2X: SPI 倍速
置位后SPI 的速度加倍。若为主机,则SCK 频率可达CPU 频率的一半。若为从机,
只能保证fosc /4。
ATmega16的SPI接口同时还用来实现程序和EEPROM的下载和上载。
//********************************SPI 数据寄存器SPDR**************************************
SPI 数据寄存器SPDR
bit7      bit6      bit5      bit4      bit3      bit2      bit1      bit0
MSB                                                                    LSB
SPI 数据寄存器为读/写寄存器,用来在寄存器文件和SPI移位寄存器之间传输数据。写
寄存器将启动数据传输,读寄存器将读取寄存器的接收缓冲器。
*/
#include
#include
#pragma interrupt_handler SPI_END: iv_SPI_STC
void SPI_MasterInit(void)// 初始化为主机
{
DDRB = (1<SPCR = (1<}
void SPI_MasterTransmit(char cData) //主机数据发送
{
SPDR = cData; // 启动数据传输
while(!(SPSR & (1<}
void SPI_SlaveInit(void)// 将SPI初始化为从机
{
DDRB = (1<SPCR = (1<}
char SPI_SlaveReceive(void)//从机数据接收
{
while(!(SPSR & (1<return SPDR;// 返回数据
}
void SPI_END()
{
//add your code here!
}