/********** mySpi.h****************/
#ifndef __MY_SPI_H
#define __MY_SPI_H
#include "stm32f10x.h"
#include #define SPI1_CSN_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_1); #define SPI1_CSN_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_1); #define SPI2_CSN_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_12); #define SPI2_CSN_LOW() GPIO_ResetBits(GPIOB,GPIO_Pin_12); void mySpi1Config(void); u8 mySpi1SendByte(u8 byte); void mySpi2Config(void); u8 mySpi2SendByte(u8 byte); #endif /**********mySpi.c************/ #include "mySpi.h" void mySpi1Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //SCK,MISO,MOSI GPIOA^5,GPIOA^6,GPIOA^7 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用功能 GPIO_Init(GPIOA, &GPIO_InitStructure); //CSN GPIOA^1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); SPI1_CSN_HIGH(); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全雙工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主機模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //時鐘空閑時為低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一個邊沿有效 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由軟件產生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分頻=9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } void mySpi2Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI2, ENABLE); //SCK,MISO,MOSI GPIOB^13,GPIOB^14 GPIOB^15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用功能 GPIO_Init(GPIOB, &GPIO_InitStructure); //CSN GPIOB^12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); SPI2_CSN_HIGH(); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全雙工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主機模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //時鐘空閑時為低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一個邊沿有效 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由軟件產生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分頻=9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); } u8 mySpi1SendByte(u8 byte) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// 當SPI發送緩存不為空 SPI_I2S_SendData(SPI1, byte);//通過SPI發送數據 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //當SPI接收緩存不為空 return SPI_I2S_ReceiveData(SPI1); //讀取緩存數據 } u8 mySpi2SendByte(u8 byte) { while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);// 當SPI發送緩存不為空 SPI_I2S_SendData(SPI2, byte);//通過SPI發送數據 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //當SPI接收緩存不為空 return SPI_I2S_ReceiveData(SPI2); //讀取緩存數據 } /***********myNRF24L01.h********************/ #ifndef __MY_NRF24L01_H #define __MY_NRF24L01_H #include "stm32f10x.h" #include /********** NRF24L01寄存器操作指令 ***********/ #define nRF_READ_REG 0x00 //讀配置寄存器-低5位是寄存器地址 #define nRF_WRITE_REG 0x20 // 寫配置寄存器-低5位是寄存器地址 #define RD_RX_PLOAD 0x61 //讀RX有效數據 1~32字節 #define WR_TX_PLOAD 0xA0 //寫TX有效數據 1~32字節 #define FLUSH_TX 0xE1 // 清除TX的FIFO寄存器-發送模式使用 #define FLUSH_RX 0xE2 // 清除RX的FIFO寄存器-接收模式使用 #define REUSE_TX_PL 0xE3 //重新使用上一包數據-CE為高時數據包被不斷發送 #define NOP 0xFF // 空操作-用于讀狀態寄存器 /********** NRF24L01寄存器地址 *************/ #define CONFIG 0x00 // 配置寄存器地址 #define EN_AA 0x01 // 使能自動應答功能 #define EN_RXADDR 0x02 //接收地址允許 #define SETUP_AW 0x03 // 設置地址寬度 #define SETUP_RETR 0x04 //建立自動重發 #define RF_CH 0x05 //RF通道 #define RF_SETUP 0x06 // RF寄存器 #define STATUS 0x07 //狀態寄存器 #define OBSERVE_TX 0x08 //發送檢測寄存器 #define CD 0x09 // 載波檢測寄存器 #define RX_ADDR_P0 0x0A //數據通道0接收地址 #define RX_ADDR_P1 0x0B // 數據通道1接收地址 #define RX_ADDR_P2 0x0C // 數據通道2接收地址 #define RX_ADDR_P3 0x0D //數據通道3接收地址 #define RX_ADDR_P4 0x0E //數據通道4接收地址 #define RX_ADDR_P5 0x0F //數據通道5接收地址 #define TX_ADDR 0x10 // 發送地址寄存器 #define RX_PW_P0 0x11 // 接收數據通道0有效數據寬度(1~32字節) #define RX_PW_P1 0x12 // 接收數據通道1有效數據寬度(1~32字節) #define RX_PW_P2 0x13 // 接收數據通道2有效數據寬度(1~32字節) #define RX_PW_P3 0x14 // 接收數據通道3有效數據寬度(1~32字節) #define RX_PW_P4 0x15 // 接收數據通道4有效數據寬度(1~32字節) #define RX_PW_P5 0x16 // 接收數據通道5有效數據寬度(1~32字節) #define FIFO_STATUS 0x17 // FIFO狀態寄存器 /****** STATUS寄存器BIT位定義 *******/ #define MAX_TX 0x10 //達到最大發送次數中斷 #define TX_OK 0x20 //TX發送完成中斷 #define RX_OK 0x40 //接收到數據中斷 void myNrfConfig(void); u8 myNrfWriteReg(u8 reg,u8 dat); u8 myNrfReadReg(u8 reg); u8 myNrfWriteBuf(u8 reg,u8 *pBuf,u8 byte); u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 byte); u8 myNrfCheck(void); void myNrfRxMode(void); void myNrfTxMode(void); u8 myNrfTxDat(u8 *txbuf); u8 myNrfRxDat(u8 *rxbuf); #endif /*******************myNRF24L01.c*********************/ #include "myNRF24L01.h" #include "mySpi.h" #define NRF_CE_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_2); #define NRF_CE_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_2); #define NRF_READ_IRQ() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) //IRQ #define myNrfSpiConfig mySpi1Config //替換NRF的SPI配置函數 #define myNrfSpiSendByte mySpi1SendByte //替換NRF的SPI讀寫函數 #define NRF_CSN_LOW SPI1_CSN_LOW //替換NRF的SPI的CSN宏定義 #define NRF_CSN_HIGH SPI1_CSN_HIGH #define CHANAL 0 //頻道選擇 #define TX_ADR_WIDTH 5 //5字節地址寬度 #define RX_ADR_WIDTH 5 //5字節地址寬度 #define TX_PLOAD_WIDTH 32 //32字節有效數據寬度 #define RX_PLOAD_WIDTH 32 //32字節有效數據寬度 u8 RX_BUF[RX_PLOAD_WIDTH]; //接收數據緩存 u8 TX_BUF[TX_PLOAD_WIDTH]; //發送數據緩存 u8 TX_ADDRESS[TX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF}; //靜態地址 u8 RX_ADDRESS[RX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF}; void myNrfConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //NRF CE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //NRF IRQ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉輸入 GPIO_Init(GPIOA, &GPIO_InitStructure); //NRF SPI配置 myNrfSpiConfig(); } //指定寄存器寫入指定數據 u8 myNrfWriteReg(u8 reg,u8 dat) { u8 status; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg);// myNrfSpiSendByte(dat); // NRF_CSN_HIGH(); return(status); } //從指定寄存器讀取數據 u8 myNrfReadReg(u8 reg) { u8 reg_val; NRF_CE_LOW(); NRF_CSN_LOW(); myNrfSpiSendByte(reg); // reg_val = myNrfSpiSendByte(NOP); // NRF_CSN_HIGH(); return reg_val; } //從指定寄存器讀取一串數據 u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 bytes) { u8 status, byte_cnt; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg); // for(byte_cnt=0;byte_cnt pBuf[byte_cnt] = myNrfSpiSendByte(NOP); // } NRF_CSN_HIGH(); return status; // } //向指定寄存器寫入一串數據 u8 myNrfWriteBuf(u8 reg ,u8 *pBuf,u8 bytes) { u8 status,byte_cnt; NRF_CE_LOW(); NRF_CSN_LOW(); status = myNrfSpiSendByte(reg); for(byte_cnt=0;byte_cnt myNrfSpiSendByte(*pBuf++); // } NRF_CSN_HIGH();
上一篇:STM32 SysTick 精準延時 簡單分析
下一篇:STM32自帶溫度傳感器
推薦閱讀
史海拾趣
設計資源 培訓 開發板 精華推薦
- 納祥科技2W 24位數字功放NX4920,可用于AI語音播報、WIFI播放器
- 常用解調器的定義和工作原理
- 從性能與網絡傳輸出發,講講鐵威馬MAX系列為什么一騎絕塵
- 惠普選中Hailo下一代人工智能加速器,革新零售業與酒店業運營模式
- 跨國商務溝通困局破解之道:時空壺 W4Pro 全場景應用解析
- 從矢量降噪到雙向同傳,時空壺 W4Pro 如何重構 AI 同傳技術標準?
- LoRa+NB-IoT雙模融合,地下車庫信號盲區電梯場景等的冗余通信
- LoRa與UWB的“定位之戰”,成本敏感場景高精度需求的場景切割
- 時空壺X1再升級:引領AI同傳新時代,革新演講翻譯體驗
- ARXML 規則下 ECU 總線通訊與 ADTF 測試方案