单片机交流
直播中

听我讲

9年用户 685经验值
擅长:电源/新能源 MEMS/传感技术
私信 关注
[问答]

怎样通过STC15W408AS单片机去模拟SPI?求解

宏的定义是什么?引脚的定义是什么?

怎样通过STC15W408AS单片机去模拟SPI?

回帖(1)

李杨

2021-7-14 10:12:11
  软件模拟SPI
  以STC15W408AS单片机为例
  一、硬件接线
  二、程序编写
  1、相关宏定义和引脚定义
  //数据类型重定义#ifndef uchar #define uchar unsigned char#endif#ifndef uint #define uint unsigned int#endif//IO端口定义***it MISO = P2^2; //主机读从设备(主入从出)***it MOSI = P2^3; //主机写从设备(主出从入)***it SCK = P2^1; //时钟信号***it CE = P2^5; ***it CS = P2^4; //片选信号(控制芯片是否被选中)***it 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 != 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!rn”); } else{ SendString(“NRF24L01 Checked Fail!rn”); } while(1);}
  4、串口代码
举报

更多回帖

发帖
×
20
完善资料,
赚取积分