一个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; //读完清除接收完成标志
}
...
}
}
AVR单片机SPI通讯实例程序 (C语言源代码)
- ARM(361233)
相关推荐
51单片机C语言程序设计
(原创【全】) 51单片机C语言程序设计--速学教程实例(入门篇+进阶+高级综合).doc/(原创【全】) 51单片机C语言程序设计--速学教程实例(入门篇+进阶+高级综合).doc/(原创00
2021-07-14 07:17:51
51单片机C语言程序设计教程_电子版样章(王云编著)
案例来讲述单片机的工作原理。本书提供有配套课件,方便进行PPT教学;书中提供完整实例代码和课后作业参考例程,所有程序代码都可以在Keil编程软件上通过调试,并在YL51开发板上验证,方便读者参考并动手实践
2018-10-11 13:47:44
51单片机竞赛设计实例程序44例分享
51单片机竞赛设计实例程序44例(Proteus仿真资料) 51单片机竞赛设计实例程序44例(Proteus仿真资料).zip
2018-07-19 03:00:51
AVR单片机C语言例程(书籍 仿真)集合大全
本内容提供了AVR单片机C语言实例书籍集合,比较全面的介绍了AVR单片机的所有知识书籍适合新手及相关技术人员开发学习.基于AVR Studio+WinAVR(GCC)组合环境和Proteus硬件仿真
2018-10-15 15:03:34
AVR单片机C语言程序框架(单片机最简操作系统)及详解
本帖最后由 lvhoujun 于 2014-2-28 00:37 编辑
这是本人以ATMEGA128为例编写的C语言程序框架,做简单的修改即适合AVR所有单片机。可以说是一个单片机最简操作系统
2014-02-12 20:27:23
AVR单片机C语言开发入门与典型实例,单片机学习必看
本帖最后由 一只耳朵怪 于 2018-5-24 17:37 编辑
AVR单片机C语言开发入门与典型实例,是比较全面的,我之前在华清远见学习的时候的一些学习资料,分享给你们学学。
2018-05-24 15:17:10
AVR单片机C语言开发入门指导
AVR单片机C语言开发入门指导,PDF文档,希望对大家有用 AVR单片机C语言开发入门指导.pdf 15.76 MB, 下载次数: 64
2018-07-03 09:32:38
AVR单片机C语言编程及应用实例
AVR单片机C语言编程及应用实例本书针对Amel公司的AVR系列单片机和ImageCraft公司的ICC AVR开发环境,详细地介绍了AT9OLS8535的C语言程序设计。全书共有13章,其内容既
2010-03-19 21:28:42
AVR单片机C语言编程及应用实例
`<p>AVR单片机C语言编程及应用实例针对Atmel公司的AVR系列单片机和ImageCraft公司的ICC AVR开发环境,详细地介绍了AT90LS8535的C语言
2009-04-27 20:51:49
评论