STC15系列单片机SPI使用教程(三)

    科技2022-07-11  161

    软件模拟SPI

    以STC15W408AS单片机为例

    一、硬件接线

    STC15系列单片机SPI使用教程(一)

    二、程序编写

    1、相关宏定义和引脚定义

    //数据类型重定义 #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif //IO端口定义 sbit MISO = P2^2; //主机读从设备(主入从出) sbit MOSI = P2^3; //主机写从设备(主出从入) sbit SCK = P2^1; //时钟信号 sbit CE = P2^5; sbit CS = P2^4; //片选信号(控制芯片是否被选中) sbit IRQ = P3^2; //INT0

    2、SPI数据交换代码

    uchar SPI_RW(uchar byte) { uchar bit_ctr; for(bit_ctr = 0; bit_ctr < 8; bit_ctr++){ MOSI = (byte & 0x80); //获得byte的最高位数据 byte = (byte << 1); //移动下一位到MSB SCK = 1; //设置SCK为高 byte |= MISO; //从MISO获得的一位数据 SCK = 0; //设置SCK为低 } return byte; //最后返回从MISO读出的数据 }

    3、NRF24L01读写例程

    //NRF24L01相关宏定义 #define NOP 0xFF //空操作 #define READ_REG 0x00 #define WRITE_REG 0x20 #define TX_ADDR 0x10 //SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 uchar SPI_RW_Reg(uchar reg, uchar value) { uchar status; CS = 0; // 使能SPI传输 status = SPI_RW(reg); //返回从MISO读出的数据,status应为上次向该寄存器内写的value SPI_RW(value); //写入寄存器的值 CS = 1; // 禁止SPI传输 return status; // 返回状态值 } //读取SPI寄存器值 //reg:要读的寄存器 uchar SPI_Read(uchar reg) { uchar reg_val; CS = 0; // 使能SPI传输 SPI_RW(reg); // 发送寄存器号 reg_val = SPI_RW(NOP); // 读取寄存器内容 CS = 1; // 禁止SPI传输 return reg_val; // 返回状态值 } //在指定位置写指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //bytes:数据长度 //返回值,此次读到的状态寄存器值 uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) { uchar status,byte_ctr; CS = 0; // 使能SPI传输 status = SPI_RW(reg);// 发送寄存器值(位置),并读取状态值 for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++){ // 写入数据 SPI_RW(*pBuf++); } CS = 1;//关闭SPI传输 return status; // 返回读到的状态值 } //在指定位置读出指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //bytes:数据长度 //返回值,此次读到的状态寄存器值 unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes) { uchar status,byte_ctr; CS = 0; // 使能SPI传输 status = SPI_RW(reg); // 发送寄存器值(位置),并读取状态值 for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++){ pBuf[byte_ctr] = SPI_RW(NOP); // 读出数据 } CS = 1; // 关闭SPI传输 return status; // 返回读到的状态值 } //检测24L01是否存在 //返回值:0,成功;1,失败 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;//检测24L01错误 return 0; //检测到24L01 } //主函数 void main(void) { Init_Uart(); EA = 1; //开总中断 NRF24L01_Check(); //切换SPI后需要读多几次,等待SPI稳定 NRF24L01_Check(); if(!NRF24L01_Check()){ SendString("NRF24L01 Checked OK!\r\n"); } else{ SendString("NRF24L01 Checked Fail!\r\n"); } while(1); }

    4、串口代码

    STC15系列单片机SPI使用教程(一)

    Processed: 0.010, SQL: 8