永发信息网

求51单片机通过I/O口模拟spi实现双机通信的c语言代码??

答案:3  悬赏:0  手机版
解决时间 2021-01-28 09:57
  • 提问者网友:萌卜娃娃
  • 2021-01-27 20:53
求51单片机通过I/O口模拟spi实现双机通信的c语言代码??
最佳答案
  • 五星知识达人网友:躲不过心动
  • 2021-01-27 21:42
#include
#include
#define MODE 0 //MODE=1时 为发送代码 MODE=0时 为接收代码
typedef unsigned char uchar;
/
//长延时
void Delay(unsigned int s)
{
unsigned int i,j;
for(i=0;i<1000;i++)for(j=0;j}
//短延时
void delay_ms(unsigned int x)
{
unsigned int i,j;
i=0;
for(i=0;i {
j=108;;
while(j--);
}
}

uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI=(byte&0x80);

byte=(byte<<1);
SCK=1;
byte|=MISO;
//led=MISO;Delay(150);
SCK=0;
}
return(byte);
}
uchar SPI_RW_Reg (uchar reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
}
uchar SPI_Read (uchar reg )
{
uchar reg_val;
CSN=0;
SPI_RW(reg);
reg_val=SPI_RW(0);
CSN=1;
return(reg_val);
}
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status byte
for(byte_ctr=0; byte_ctr SPI_RW(*pBuf++);
CSN = 1; // Set CSN high again
return(status); // return nRF24L01 status byte
}
#if MODE

void TX_Mode(void)
{
CE=0;

SPI_RW_Reg(FLUSH_TX,0x00);
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
CE=1;
delay_ms(100);
}
void Transmit(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_RW_Reg(FLUSH_TX,0x00);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
delay_ms(150);
}
#else

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uchar status,uchar_ctr;

CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar

for(uchar_ctr=0;uchar_ctr pBuf[uchar_ctr] = SPI_RW(0); //

CSN = 1;
return(status); // return nRF24L01 status uchar
}


unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
//CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
//Delay(100);
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}


void RX_Mode(void)
{
CE=0;

SPI_RW_Reg(FLUSH_RX,0x00);
//SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack

SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);
CE=1;
delay_ms(130);
}
//************************************串口初始化*********************************************************
void StartUART( void )
{ //波特率9600
SCON = 0x50;
TMOD = 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
PCON = 0x00;
TR1 = 1;
}
//************************************通过串口将接收到数据发送给PC端**************************************
void R_S_Byte(uchar R_Byte)
{
SBUF = R_Byte;
while( TI == 0 ); //查询法
TI = 0;
}
#endif
//************************************主函数************************************************************
void main()
{
int i=0;
CE=0;
SCK=0;
CSN=1;
P1=0x00;
#if MODE //发送 模式代码
TX_Mode();
//SPI_RW_Reg(FLUSH_RX,0x00);
while(1)
{
Transmit(Tx_Buf);
Delay(10);
sta=SPI_Read(READ_REG + STATUS);
if(TX_DS)
{
P1=sta; //8位LED显示当前STATUS状态 发送中断应使bit5 = 1 灯灭
Delay(100);
SPI_RW_Reg(WRITE_REG + STATUS,sta);
}
if(MAX_RT) //如果是发送超时
{
P1=0x0f; //发送超时时 8位LED灯 bit4 = 1 灯灭
Delay(150);
SPI_RW_Reg(WRITE_REG + STATUS,sta);
}
}
#else //接收 模式代码
StartUART();
RX_Mode();
Delay(0);//防止编译警告

while(1)
{
if(nRF24L01_RxPacket(Rx_Buf))
{
for(i=0;i R_S_Byte(Rx_Buf[i]);
}
}
#endif
}参考资料:百度文库
全部回答
  • 1楼网友:走死在岁月里
  • 2021-01-27 22:48
现成的
  • 2楼网友:duile
  • 2021-01-27 22:20
这个proteus论坛上有很多了,随便找个下载都行。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯