预处理:
#include "avr/io.h"
#include "avr/iom128.h"
#define uint unsigned int
#define uchar unsigned char
//端口设置
#define DDR_SPI DDRB
#define DDR_SS DDB0
#define DDR_SCK DDB1
#define DDR_MOSI DDB2
#define DDR_MISO DDB3
#define PORT_SPI PORTB
#define PORT_SS PB0
//SPI引脚定义
#define SPI_MASTER_IO DDR_SPI |= (1<<DDR_MOSI) | (1<<DDR_SS) | (1<<DDR_SCK)//主机引脚定义
#define SPI_SLAVE_IO DDR_SPI |= (1<<DDR_MISO)//从机引脚定义
//状态寄存器-SREG
#define CLI() asm("cli")
#define SEI() asm("sei")
//SPI控制寄存器-SPCR
#define SPI_IE SPCR |=(1<<SPIE) //SPI中断使能
#define SPI_E SPCR |=(1<<SPE) //SPI使能
#define SPI_DORD SPCR |=(1<<DORD) //SPI数据发送LSB先
#define SPI_MSTR SPCR |=(1<<MSTR) //SPI为主机
//SPI工作模式
#define SPI_MODE1 SPCR |=(1<<CPHA) //工作模式1
#define SPI_MODE2 SPCR |=(1<<CPOL) //工作模式2
#define SPI_MODE3 SPCR |=(1<<CPOL) | (1<<CPHA) //工作模式3
//SPI时钟频率选择
#define SPI_16 SPCR |=(1<<SPR0) //F/16
#define SPI_64 SPCR |=(1<<SPR1) //F/64
#define SPI_128 SPCR |=(1<<SPR1) | (1<<SPR0) //F/128
//SPI状态寄存器-SPSR
#define SPI_Wait while(!(SPSR & (1<<SPIF))) //判断中断标志是否为1
#define SPI_WCOL while(SPSR & (1<<WCOL)) //写data时判断是否冲突
//SPI时钟倍速选择-SPI2X
#define SPI_2 SPSR |=(1<<SPI2X) //F/2
#define SPI_8 SPSR |=(1<<SPI2X);SPCR |=(1<<SPR0) //F/8
#define SPI_32 SPSR |=(1<<SPI2X);SPCR |=(1<<SPR1) //F/32
#define SPI_64 SPSR |=(1<<SPI2X);SPCR |=(1<<SPR1) | (1<<SPR0) //F/64
/*********************************************************************************************/
主机:
//函数申明
void SPI_MasterInitial(void);
//主函数
int main(void)
{
SPI_MasterInitial(); //初始化
while(1)
{
PORT_SPI &= ~(1<<PORT_SS); //唤醒从机
SPDR = 0X23; //数据
SPI_Wait; //等待数据传输完毕
PORTE = SPDR; //将接收的数据输出
PORT_SPI |= (1<<PORT_SS); //从机不接收
}
return 0;
}
//初始化
void SPI_MasterInitial(void)
{
DDRE = 0XFF;
SPI_MSTR; //主机模式
SPI_MASTER_IO; //主机模式
SPI_8; //clk/8
SPI_E; //SPI使能
SPI_DORD; //SPI数据发送LSB先
SPI_MODE1; //工作模式1
}
从机:
//函数申明
void SPI_SlaveInitial(void);
//主函数
int main(void)
{
SPI_SlaveInitial(); //初始化
while(1)
{
SPDR = 0X55; //发送的数据
SPI_Wait; //等待数据接收完毕
PORTE = SPDR; //将接收的数据输出
}
return 0;
}
//初始化
void SPI_SlaveInitial(void)
{
DDRE = 0XFF;
SPI_SLAVE_IO; //从机引脚定义
SPI_E; //SPI使能
SPI_DORD; //SPI数据发送LSB先
SPI_MODE1; //工作模式1
}
这是一个很简单的SPI双机通讯程序,主机将0x23传送给从机,同时从机将0x55传送给主机,并且两者都将接收到的数据在E端口输出,以便验证传送是否成功。这个程序有利于初学者学习SPI。
联系客服