发 帖  
原厂入驻New
[问答]

怎样使用两个51单片机软件去模拟实现SPI完成通信?

67 51单片机 SPI 通信
分享
SPI内部的工作机制是怎样的?
怎样使用两个51单片机软件去模拟实现SPI完成通信,相互接收和发送数据?
0
2021-7-7 06:27:03   评论 分享淘帖 邀请回答
1个回答
  本文我们拟使用两个51单片机软件模拟实现SPI完成通信,相互接收和发送数据。即在A电脑上发送字符,B电脑上接收到字符,反之相同。
  MODE1:
  CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。
  MODE2:
  CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。
  MODE3:
  CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。
  MODE4:
  CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。
  这里我们所用的是模式3:第一个跳变沿即上升沿发送数据,第二个跳变沿即下降沿接收数据,空闲状态为高电平。
  SPI通信时序图:
  SPI内部的工作机制:
  
  #include 《reg52.h》//头文件#include 《intrins.h》//头文件#define uchar unsigned char#define uint unsigned intsbit SCK = P1^0;//位定义时钟sbit SDI = P1^2;//位定义Inputsbit SDO = P1^3;//位定义Output//定义延时函数void delay(uint z){ uint x,y; for(x = z; x 》 0; x--) for(y = 114; y 》 0 ; y--); } /* 函数声明 */void Spisend(uchar dat1);//数据发送函数uchar Spireceive(); //数据接收函数void UARTInit(); //中断处理函数uchar i; //定义全局变量i//SPI模式2:第一个跳变沿即上升沿发送,第二个跳变沿即下降沿接收,空闲状态为高电平/*----主函数-----*/void main(){ UARTInit(); //中断处理 while(1) //大循环 { SBUF = SpiReceive();// 循环接收数据 } }/*-----SPI发送函数----*//*-----上升沿发送-----*//*----- 高位先发 -----*/void Spisend(uchar dat1){ for (i=0; i《8; ++i)//8bit,一位一位发送 { SCK = 0; //先把电平降下来,才会有上升沿 if (dat1 & 0x80)//逻辑与,判断当前最高位为1还是0,0x80为10000000 { SDO = 1; //待将数据1发送出去 } else { SDO = 0; //待将数据0发送出去 } SCK = 1; //上升沿发送数据,一位一位的发,共8次 dat1 《《= 1; //左移1位,下一位进行发送 delay(5); //延时5毫秒 }}/*-----SPI接收函数-----*//*-----下降沿接收-----*/uchar Spireceive(){ uchar dat0; dat0 = 0x00; //dat0初始化 for (i=0; i《8; ++i) //8bit,一位一位读 { dat0 《《= 1;//高位先接受,将接收到的数据逐位移到高位 while(SCK == 1); while(SCK == 0)//等待下降沿,下降沿读取数据 dat0 = SDI; //读取数据 } return (dat0); //返回接收到的dat0 }/*-----------串口中断服务函数-----------*/void UART() interrupt 4//串口中断入口为4{ if (RI == 1)//判断是否接收完成 { RI = 0;//软件清零接收位 Spisend(SBUF); //转发出接收到暂时保存在接收SBUF的数据 } if (TI == 1)//判断是否发送完成 { TI = 0;//软件清零 } }/*串口(中断)初始化函数*/void UARTInit(){ EA = 1;//开启总中断 ES = 1;//打开串口中断 SM0 = 0;SM1 = 1;//串口工作方式1,8位UART波特率可变 REN = 1;//串口允许接收 TR1 = 1;//启动定时器1 TMOD= 0X20;//定时器1,工作模式2 8位自动重装 TH1 =0XFD;//设置波特率9600 代入公式计算 TL1 =0XFD;//设置波特率9600 且TL1先加满溢出 } 单片机连接方式:用杜邦线进行连接,两者共地,且两者的数据线即P1.2和P1.3相互对接。两块开发板都连接上电源,烧录好程序,即可开始实验。
2021-7-7 09:33:17 评论

举报

只有小组成员才能发言,加入小组>>

45个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /9 下一条

快速回复 返回顶部 返回列表