传一个程序,SPI全双工通信,在计算机课上学习了全双工通信的原理,又细细的看了DATASHEET,又看了张军编的关于avr书,才搞出来的。主机与从机互相交换一下各自存储的字符串,然后按UP键,从机传给主机一首音乐,按START键,主机开始唱,音乐部分参考了本论坛上的程序。CLOCK时钟线是由主机控制的。有仿真,从仿真中能看到数据流的流向及时间。
请大家多多指教。
部分程序代码
<主机程序>
#include "iom16v.h"
#include "macros.h"
#define uchar unsigned char
#define uint unsigned int
#define UP 0XFE
#define DOWN 0XFD
#define START 0XFB
#define UNVALUE 10
#define SING_UP 252
#define SING_DOWN 253
#define END 254
uint music[100][2];
/************初始化**************/
void DeviceInit(void)
{
CLI(); //关闭中断
SPIMasterInit(); //SPI初始化
uart0_init(); //UART初始化
CTC_Init(); //比较输出初始化
TIMSK |= (1<<OCIE1A); //开启比较匹配中断
MCUCR=0X00;
DDRC=0X00;
PORTC=0XFF;
SEI(); //开全局中断
}
/****************MUSIC数据接收*****************/
void music_receive(void)
{
uchar i=0,j=0,flag=0,high=0,low=0;
while(flag==0)
{
for(i=0;i<2;i++)
{
SPI_SENT(UNVALUE); //*******发空数据,用于启动时钟
high=SPDR; //**************接受从机高八位
NOP(); //********************************等待从机接收完数据,并把待发送数据
NOP(); //********************************放入SPSR寄存器中
SPI_SENT(UNVALUE);
low=SPDR; //**************接受从机低八位
NOP(); //********************************等待从机接收完数据,并把待发送数据
NOP(); //********************************放入SPSR寄存器中
music[j]=high*256+low;
if((high==END)|(low==END)) {flag=1;music[j+1][1]= END; break;}
}
j++;
}
}
/*****************choose_key*******************/
uchar choose_key(void)
{
uchar key;
key=PINC;
delay_ms(50);
if(key==PINC)
{
delay_ms(50);
if(key==PINC)
{
return key;
}
}
}
/*****************选择传输的音乐**************/
void music_choose(void)
{
switch(choose_key())
{
case UP:
{
SPI_SENT(SING_UP);
music_receive(); break;
}
case DOWN:
{
SPI_SENT(SING_DOWN);
music_receive(); break;
}
case START: {
music_play(music);break;
}
default:break;
}
}
/****************主函数***********************/
void main(void)
{
uchar k=0,flag=0,high=0,low=0,slave_data[80];
uchar master_data[]="I am the slave cpu and receive the data of the master's cpu!! SLAVE SLAVE SLAVE SLAVE SLAVE";
//存储的数据用于发送给从机
DeviceInit();
delay_ms(10); //***让从机先进入工作状态
while(1)//************************************循环发送送与接收数据
{
SPI_SENT(master_data[k]);
slave_data[k]=SPDR; //**************接受从机的数据
Uart0Send(slave_data[k]);///*******发送到串口
if(slave_data[k]==END)break;
k++;
}
while(1)
{
music_choose();
}
}
|