AVR单片机(学习ing)—(十)、ATMEGA16的同步串行接口SPI—03
扫描二维码
随时随地手机看文章
十、ATMEGA16的同步串行接口SPI
十—(03)、ATMEGA16的同步串行接口SPI的串行通讯实验—通过效率最高的中断法~~
然后就是程序了~~
IAR10_2_M.c
//------------------------------------------------------------------------------
//这是ATMEGA16作为主机发送的文件
//主机每隔1s发送数组的一个数据给从机,从机收到后则发送自己的数组的一个数据给主机,这样实现数组内容的交换
//数组的内容在主机和从机的数码管上显示
#include"ioavr.h"
#include"intrinsics.h"
#include"delayics.h"
#include"bitics.h"
#include"macroandconst.h"
//------------------------------------------------------------------------------
#define SPIF 7
#define SS4
uchar __flash seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管
uchar __flash act[4]={0xfe,0xfd,0xfb,0xf7};//位选
uchar tx_buffer[10]={0,1,2,3,4,5,6,7,8,9};
uchar rx_buffer[10];
uchar i=0;
uchar master_flag=0;
//------------------------------------------------------------------------------
//端口初始化函数
void port_init()
{
DDRA=0XFF;
PORTA=0X00;
DDRB=0XB0;//SCK、MOSI、SS置位为输出,MISO设置为输入
PORTB=0X10;//SS输出高电平,其余都输入/输出低电平(SS输出高电平,不进行发送,要想发送要将SS拉低,激活从机SPI接口~~)
DDRC=0XFF;
PORTC=0XFF;
}
//------------------------------------------------------------------------------
//SPI初始化函数
void spi_init()
{
SPCR=0xd1;//SPI中断使能;SPI使能;数据的MSB先发送;选择为主机模式;
//时钟极性:上升沿为起始沿,结束眼为下降沿;时钟相位:起始沿采样;16分频
}
//------------------------------------------------------------------------------
//芯片初始化函数
void device_init()
{
__disable_interrupt();
port_init();
spi_init();
__enable_interrupt();
}
//------------------------------------------------------------------------------
//main
void main()
{
uchar count;
device_init();
for(count=0;count<10;count++)
{
PORTA=seg[tx_buffer[count]];
PORTC=act[0];
delay_s(1);
}
CLR_BIT(PORTB,SS);//清除SS,准备发送
SPDR=tx_buffer[0];//给主机的发送缓冲区送一个数
while(1)
{
if(master_flag==1)
{
for(count=0;count<10;count++)
{
PORTA=seg[rx_buffer[count]];
PORTC=act[0];
delay_s(1);
}
}
}
}
//------------------------------------------------------------------------------
//SPI_STC
#pragma vector=SPI_STC_vect
__interrupt void spi_stc()
{
rx_buffer[i]=SPDR;
if(i>=9)
{
SET_BIT(PORTB,SS);//结束发送
master_flag=1;//置位标志位
goto end;//这个语句必须要有~~!!!!!
}
i++;
SPDR=tx_buffer[i];
end://发送结束,不再进行中断~~
;
}
IAR10_2_S.c
//------------------------------------------------------------------------------
//这是ATMEGA16作为从机接收的文件
//主机每隔1s发送数组的一个数据给从机,从机收到后则发送自己的数组的一个数据给主机,这样实现数组内容的交换
//数组的内容在主机和从机的数码管上显示
#include"ioavr.h"
#include"intrinsics.h"
#include"delayics.h"
#include"bitics.h"
#include"macroandconst.h"
//------------------------------------------------------------------------------
#define SPIF 7
#define SS4
uchar __flash seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管
uchar __flash act[4]={0xfe,0xfd,0xfb,0xf7};//位选
uchar tx_buffer[10]={9,8,7,6,5,4,3,2,1,0};
uchar rx_buffer[10];
uchar i=0;
uchar slave_flag=0;
//------------------------------------------------------------------------------
//端口初始化函数
void port_init()
{
DDRA=0XFF;
PORTA=0X00;
DDRB=0X40;//SCK、MOSI、SS置位为输入,MISO设置为输出
PORTB=0X10;//SS输入高电平,其余都输入/输出低电平(SS输入高电平,不进行接收,要想发送要将SS拉低,激活从机SPI接口~~)
DDRC=0XFF;
PORTC=0XFF;
}
//------------------------------------------------------------------------------
//SPI初始化函数
void spi_init()
{
SPCR=0xc1;//SPI中断使能;SPI使能;数据的MSB先发送;选择为从机模式;
//时钟极性:上升沿为起始沿,结束眼为下降沿;时钟相位:起始沿采样;16分频
}
//------------------------------------------------------------------------------
//芯片初始化函数
void device_init()
{
__disable_interrupt();
port_init();
spi_init();
__enable_interrupt();
}
//------------------------------------------------------------------------------
//main
void main()
{
uchar count;
device_init();
for(count=0;count<10;count++)
{
PORTA=seg[tx_buffer[count]];
PORTC=act[0];
delay_s(1);
}
SPDR=tx_buffer[0];//给从机的发送缓冲区送一个数,等待移出
while(1)
{
if(slave_flag==1)
{
for(count=0;count<10;count++)
{
PORTA=seg[rx_buffer[count]];
PORTC=act[0];
delay_s(1);
}
}
}
}
//------------------------------------------------------------------------------
//SPI_STC
#pragma vector=SPI_STC_vect
__interrupt void spi_stc()
{
rx_buffer[i]=SPDR;
if(i>=9)
{
SET_BIT(PORTB,SS);//结束发送
slave_flag=1;//置位标志位
goto end;//这个语句必须要有的~~!!!!!!
}
i++;
SPDR=tx_buffer[i];
end://到达end结束发送,不再进行发送~~
;
}