软件模拟SPI
以STC15W408AS单片机为例
一、硬件接线
STC15系列单片机SPI使用教程(一)
二、程序编写
1、相关宏定义和引脚定义
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
sbit MISO = P2^2;
sbit MOSI = P2^3;
sbit SCK = P2^1;
sbit CE = P2^5;
sbit CS = P2^4;
sbit IRQ = P3^2;
2、SPI数据交换代码
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;
SCK = 0;
}
return byte;
}
3、NRF24L01读写例程
#define NOP 0xFF
#define READ_REG 0x00
#define WRITE_REG 0x20
#define TX_ADDR 0x10
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CS = 0;
status = SPI_RW(reg);
SPI_RW(value);
CS = 1;
return status;
}
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CS = 0;
SPI_RW(reg);
reg_val = SPI_RW(NOP);
CS = 1;
return reg_val;
}
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CS = 0;
status = SPI_RW(reg);
for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++){
SPI_RW(*pBuf++);
}
CS = 1;
return status;
}
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
uchar status,byte_ctr;
CS = 0;
status = SPI_RW(reg);
for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++){
pBuf[byte_ctr] = SPI_RW(NOP);
}
CS = 1;
return status;
}
uchar NRF24L01_Check(void)
{
uchar buf[5]={
0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
uchar buf1[5];
uchar i;
CE = 0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, buf, 5);
SPI_Read_Buf(TX_ADDR, buf1, 5);
CE = 1;
for(i = 0; i < 5; i++)
if(buf1[i] != 0xA5)
break;
if(i!=5)
return 1;
return 0;
}
void main(void)
{
Init_Uart();
EA = 1;
NRF24L01_Check();
NRF24L01_Check();
if(!NRF24L01_Check()){
SendString("NRF24L01 Checked OK!\r\n");
}
else{
SendString("NRF24L01 Checked Fail!\r\n");
}
while(1);
}
4、串口代码
STC15系列单片机SPI使用教程(一)