【Let'sdo第1期-功率检测与控制系统DIY】使用nucle-F411RE SPITFTLCD液晶屏显示INA219模块检测电流
参加EEPW论坛2025 Let'sdo第1期-功率检测与控制系统DIY,大概任务就是使用nucle-F411RE开发板和INA219模块来检测开发板和用电器模块运行时的电压和电流,不过我这边对实验用器件做出了一些个人意向的修改,首先是我不太喜欢使用OLED屏进行显示,因为OLED屏能显示的信息太少,并且使用不当容易烧坏,因此我使用自己提供的SPITFTLCD液晶屏来显示,除此之外像INA219模块驱动代码都是完全一致的。这个课程需要占用PB8 PB9用作模拟I2C接口,占用PA5 PA6 PA7用作SPI1接口,以及一些GPIO作为液晶屏信号控制,然后再占用一组SPI2与NRF24L01模块进行通信,由于液晶屏和NRF24L01模块的SPI参数有差异,因此不使用同一组SPI接口:



void FAKE_I2C_INA_Delay()
{
uint8_t x;
for(x=1;x>0;x--)
{
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
void FAKE_I2C_INA_PB8_PB9_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
FAKE_I2C_INA_SCL_PB8_CLK_ENABLE;
FAKE_I2C_INA_SDA_PB9_CLK_ENABLE;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = FAKE_I2C_INA_SCL_PB8_PIN;
HAL_GPIO_Init(FAKE_I2C_INA_SCL_PB8_PORT , &GPIO_InitStruct);
GPIO_InitStruct.Pin = FAKE_I2C_INA_SDA_PB9_PIN;
HAL_GPIO_Init(FAKE_I2C_INA_SDA_PB9_PORT , &GPIO_InitStruct);
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_SDA_PB9_HIGH;
}
void FAKE_I2C_INA_PB8_PB9_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = FAKE_I2C_INA_SDA_PB9_PIN;
HAL_GPIO_Init(FAKE_I2C_INA_SDA_PB9_PORT , &GPIO_InitStruct);
}
void FAKE_I2C_INA_PB8_PB9_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = FAKE_I2C_INA_SDA_PB9_PIN;
HAL_GPIO_Init(FAKE_I2C_INA_SDA_PB9_PORT , &GPIO_InitStruct);
}
void FAKE_I2C_INA_PB8_PB9_Start(void)
{
FAKE_I2C_INA_SDA_PB9_HIGH;
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SDA_PB9_LOW;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SCL_PB8_LOW;
}
void FAKE_I2C_INA_PB8_PB9_Stop(void)
{
FAKE_I2C_INA_SDA_PB9_LOW;
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SDA_PB9_HIGH;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SCL_PB8_LOW;
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_SDA_PB9_HIGH;
}
bool FAKE_I2C_INA_PB8_PB9_ACK_Read(void)
{
bool ack;
FAKE_I2C_INA_SDA_PB9_HIGH;
FAKE_I2C_INA_PB8_PB9_SDA_IN();
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_Delay();
if(FAKE_I2C_INA_SDA_PB9_READ == SET)
ack = false;
else ack=true;
FAKE_I2C_INA_SCL_PB8_LOW;
FAKE_I2C_INA_PB8_PB9_SDA_OUT();
return ack;
}
void FAKE_I2C_INA_PB8_PB9_ACK_Send(bool ack)
{
FAKE_I2C_INA_SCL_PB8_LOW;
if(ack == true)
{
FAKE_I2C_INA_SDA_PB9_LOW;
}
else
{
FAKE_I2C_INA_SDA_PB9_HIGH;
}
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SCL_PB8_LOW;
}
void FAKE_I2C_INA_PB8_PB9_Send_Byte(uint8_t byte)
{
uint8_t i;
FAKE_I2C_INA_SCL_PB8_LOW;
for(i=0;i<8;i++)
{
if(byte & 0x80)
{
FAKE_I2C_INA_SDA_PB9_HIGH;
}
else
{
FAKE_I2C_INA_SDA_PB9_LOW;
}
FAKE_I2C_INA_SCL_PB8_HIGH;
FAKE_I2C_INA_Delay();
FAKE_I2C_INA_SCL_PB8_LOW;
FAKE_I2C_INA_Delay();
byte <<= 1;
}
FAKE_I2C_INA_PB8_PB9_ACK_Read();
}
uint8_t FAKE_I2C_INA_PB8_PB9_Read_Byte(void)
{
uint8_t i,byte=0;
FAKE_I2C_INA_PB8_PB9_SDA_IN();
for(i=0;i<8;i++)
{
FAKE_I2C_INA_SCL_PB8_HIGH;
byte<<=1;
if(FAKE_I2C_INA_SDA_PB9_READ == SET)
{
byte |= 0x01;
}
else
{
byte &= 0xFE;
}
FAKE_I2C_INA_SCL_PB8_LOW;
FAKE_I2C_INA_Delay();
}
FAKE_I2C_INA_PB8_PB9_SDA_OUT();
return byte;
}
void FAKE_I2C_INA_PB8_PB9_Read_Bytes(unsigned char reg,unsigned char *data)
{
FAKE_I2C_INA_PB8_PB9_Start();
FAKE_I2C_INA_PB8_PB9_Send_Byte(INA219_ADDRESS);
FAKE_I2C_INA_PB8_PB9_Send_Byte(reg);
FAKE_I2C_INA_PB8_PB9_Start();
FAKE_I2C_INA_PB8_PB9_Send_Byte(INA219_ADDRESS + 0x01);
*data = FAKE_I2C_INA_PB8_PB9_Read_Byte();
data++;
FAKE_I2C_INA_PB8_PB9_ACK_Send(1);
*data = FAKE_I2C_INA_PB8_PB9_Read_Byte();
FAKE_I2C_INA_PB8_PB9_ACK_Send(0);
FAKE_I2C_INA_PB8_PB9_Stop();
}
void FAKE_I2C_INA_PB8_PB9_REG_Write(unsigned char reg,unsigned int data)
{
unsigned char data_temp[2];
data_temp[0]=(unsigned char )(data>>8);
data_temp[1]=(unsigned char )(data & 0xFF);
FAKE_I2C_INA_PB8_PB9_Start();
FAKE_I2C_INA_PB8_PB9_Send_Byte(INA219_ADDRESS);
FAKE_I2C_INA_PB8_PB9_Send_Byte(reg);
FAKE_I2C_INA_PB8_PB9_Send_Byte(data_temp[0]);
data++;
FAKE_I2C_INA_PB8_PB9_Send_Byte(data_temp[1]);
FAKE_I2C_INA_PB8_PB9_Stop();
}
void INA_Init(void)
{
FAKE_I2C_INA_PB8_PB9_Init();
FAKE_I2C_INA_PB8_PB9_REG_Write(INA219_REG_CONFIG , INA219_CONFIG_value);
FAKE_I2C_INA_PB8_PB9_REG_Write(INA219_REG_CALIBRATION , INA_CAL);
}
unsigned int INA_GET_Voltage_MV(void)
{
unsigned char data_temp[2];
FAKE_I2C_INA_PB8_PB9_Read_Bytes(0x02 , data_temp);
return (int)((((data_temp[0]<<8) + data_temp[1]) >> 3)*4);
}
unsigned int INA_GET_Current_MA(void)
{
unsigned char data_temp[2];
FAKE_I2C_INA_PB8_PB9_REG_Write(INA219_REG_CONFIG , INA219_CONFIG_value);
FAKE_I2C_INA_PB8_PB9_Read_Bytes(INA219_REG_CURRENT , data_temp);
return (int)((((data_temp[0]<<8) + data_temp[1]))*IAN_I_LSB);
}
unsigned int INA_GET_Power_MW(void)
{
unsigned char data_temp[2];
FAKE_I2C_INA_PB8_PB9_Read_Bytes(INA219_REG_POWER , data_temp);
return (int)(((data_temp[0]<<8) + data_temp[1]) * INA_Power_LSB);
}
这里使用模拟I2C逻辑来驱动INA219模块,可以很方便移植到别的平台上,并且不受GPIO引脚限制。INA219模块的模拟I2C时序跟一般常用的I2C器件如BMP280 MPU9250 DS3231的时序有细微差别,两者的代码无法直接通用。
#define FAKE_I2C_INA_SCL_PB8_PORT GPIOB #define FAKE_I2C_INA_SCL_PB8_PIN GPIO_PIN_8 #define FAKE_I2C_INA_SCL_PB8_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE(); #define FAKE_I2C_INA_SCL_PB8_HIGH HAL_GPIO_WritePin(FAKE_I2C_INA_SCL_PB8_PORT , FAKE_I2C_INA_SCL_PB8_PIN , GPIO_PIN_SET); #define FAKE_I2C_INA_SCL_PB8_LOW HAL_GPIO_WritePin(FAKE_I2C_INA_SCL_PB8_PORT , FAKE_I2C_INA_SCL_PB8_PIN , GPIO_PIN_RESET); #define FAKE_I2C_INA_SDA_PB9_PORT GPIOB #define FAKE_I2C_INA_SDA_PB9_PIN GPIO_PIN_9 #define FAKE_I2C_INA_SDA_PB9_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE(); #define FAKE_I2C_INA_SDA_PB9_HIGH HAL_GPIO_WritePin(FAKE_I2C_INA_SDA_PB9_PORT , FAKE_I2C_INA_SDA_PB9_PIN , GPIO_PIN_SET); #define FAKE_I2C_INA_SDA_PB9_LOW HAL_GPIO_WritePin(FAKE_I2C_INA_SDA_PB9_PORT , FAKE_I2C_INA_SDA_PB9_PIN , GPIO_PIN_RESET); #define FAKE_I2C_INA_SDA_PB9_READ HAL_GPIO_ReadPin(FAKE_I2C_INA_SDA_PB9_PORT , FAKE_I2C_INA_SDA_PB9_PIN) #define INA219_ADDRESS (0x40 << 1)
INA2219的地址选位0x40,其实是可以通过拨码开关设置为0x45的,使用起来没有任何区别。
然后再使用SPI1(PA5 PA6 PA7)来点SPITFTLCD彩屏:
uint8_t SPI1_PA5_PA6_PA7_Read_Write_Byte(uint8_t TxData)
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&hspi1 , &TxData , &Rxdata , 1 , 1000);
return Rxdata;
}
void SPI1_PA5_PA7_Write_Byte(uint8_t TxData)
{
HAL_SPI_Transmit(&hspi1 , &TxData , 1 , 1000);
}
void SPI1_PA5_PA6_PA7_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA , &GPIO_InitStruct);
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi1);
hdma_spi1_rx.Instance = DMA2_Stream0;
hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi1_rx);
__HAL_LINKDMA(&hspi1 , hdmarx , hdma_spi1_rx);
hdma_spi1_tx.Instance = DMA2_Stream2;
hdma_spi1_tx.Init.Channel = DMA_CHANNEL_2;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi1_tx);
__HAL_LINKDMA(&hspi1 , hdmatx , hdma_spi1_tx);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}
还需要PA4 PA8 PB7三个GPIO来控制液晶屏的片选,复位,DC选择:
#define SPITFTLCD_ST7789_CS_GPIO_PORT GPIOA #define SPITFTLCD_ST7789_CS_GPIO_PIN GPIO_PIN_4 #define SPITFTLCD_ST7789_CS_GPIO_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE(); #define SPITFTLCD_ST7789_CS_HIGH HAL_GPIO_WritePin(SPITFTLCD_ST7789_CS_GPIO_PORT , SPITFTLCD_ST7789_CS_GPIO_PIN , GPIO_PIN_SET); #define SPITFTLCD_ST7789_CS_LOW HAL_GPIO_WritePin(SPITFTLCD_ST7789_CS_GPIO_PORT , SPITFTLCD_ST7789_CS_GPIO_PIN , GPIO_PIN_RESET); #define SPITFTLCD_ST7789_RESET_GPIO_PORT GPIOA #define SPITFTLCD_ST7789_RESET_GPIO_PIN GPIO_PIN_8 #define SPITFTLCD_ST7789_RESET_GPIO_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE(); #define SPITFTLCD_ST7789_RESET_HIGH HAL_GPIO_WritePin(SPITFTLCD_ST7789_RESET_GPIO_PORT , SPITFTLCD_ST7789_RESET_GPIO_PIN , GPIO_PIN_SET); #define SPITFTLCD_ST7789_RESET_LOW HAL_GPIO_WritePin(SPITFTLCD_ST7789_RESET_GPIO_PORT , SPITFTLCD_ST7789_RESET_GPIO_PIN , GPIO_PIN_RESET); #define SPITFTLCD_ST7789_DC_GPIO_PORT GPIOB #define SPITFTLCD_ST7789_DC_GPIO_PIN GPIO_PIN_7 #define SPITFTLCD_ST7789_DC_GPIO_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE(); #define SPITFTLCD_ST7789_DC_HIGH HAL_GPIO_WritePin(SPITFTLCD_ST7789_DC_GPIO_PORT , SPITFTLCD_ST7789_DC_GPIO_PIN , GPIO_PIN_SET); #define SPITFTLCD_ST7789_DC_LOW HAL_GPIO_WritePin(SPITFTLCD_ST7789_DC_GPIO_PORT , SPITFTLCD_ST7789_DC_GPIO_PIN , GPIO_PIN_RESET);
使用显示ASCII字符的函数显示必要信息:
void SPITFTLCD_ST7789_ShowChar1632(uint16_t x , uint16_t y , uint8_t num , uint16_t fc , uint16_t bc , uint8_t mode)
{
uint8_t temp,sizex,t,m=0;
uint16_t i,TypefaceNum;
uint16_t x0=x;
sizex=16;
TypefaceNum=(sizex/8+((sizex%8)?1:0))*32;
num=num-' ';
SPITFTLCD_ST7789_Address_Set(x,y,x+sizex-1,y+32-1);
for(i=0;i<TypefaceNum;i++)
{
temp = ascii_3216[num][i];
for(t=0;t<8;t++)
{
if(!mode)
{
if(temp&(0x01<<t))SPITFTLCD_ST7789_WR_DATA(fc);
else SPITFTLCD_ST7789_WR_DATA(bc);
m++;
if(m%sizex==0)
{
m=0;
break;
}
}
else
{
if(temp&(0x01<<t))SPITFTLCD_ST7789_DrawPoint(x , y , fc);
x++;
if((x-x0)==sizex)
{
x=x0;
y++;
break;
}
}
}
}
}
void SPITFTLCD_ST7789_ShowString1632(uint16_t x , uint16_t y , const uint8_t *p , uint16_t fc , uint16_t bc , uint8_t mode)
{
while(*p != '\0')
{
SPITFTLCD_ST7789_ShowChar1632(x,y,*p,fc,bc,mode);
x += 16;
p++;
}
}定时器2和定时器3初始化:
TIM_HandleTypeDef TIM2_Handler;
TIM_HandleTypeDef TIM3_Handler;
void TIM2_Init(uint16_t arr,uint16_t psc)
{
__HAL_RCC_TIM2_CLK_ENABLE();
TIM2_Handler.Instance=TIM2;
TIM2_Handler.Init.Prescaler=psc;
TIM2_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;
TIM2_Handler.Init.Period=arr;
TIM2_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&TIM2_Handler);
HAL_TIM_Base_Start(&TIM2_Handler);
}
void TIM3_Init(uint16_t arr,uint16_t psc)
{
__HAL_RCC_TIM3_CLK_ENABLE();
TIM3_Handler.Instance=TIM3;
TIM3_Handler.Init.Prescaler=psc;
TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;
TIM3_Handler.Init.Period=arr;
TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&TIM3_Handler);
HAL_TIM_Base_Start(&TIM3_Handler);
}
定时器2和定时器3设置参数,定时器2为100ms溢出,定时器3为500ms溢出:
TIM2_Init(1000 - 1 , 5000 - 1); TIM3_Init(5000 - 1 , 5000 - 1);
INA219模块的测量口正负极直接接在开发板的供电跳帽上,就可以获取开发板运行电流以及运行功率了:


SPI2初始化:
uint8_t SPI2_PB10_PC2_PC3_Read_Write_Byte(uint8_t TxData)
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&hspi2 , &TxData , &Rxdata , 1 , 1000);
return Rxdata;
}
void SPI2_PB10_PC2_PC3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_SPI2_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
GPIO_InitStruct.Pin = GPIO_PIN_10;
HAL_GPIO_Init(GPIOB , &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOC , &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
HAL_GPIO_Init(GPIOC , &GPIO_InitStruct);
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi2);
}通过SPI2接口设置NRF24L01模块收发模式以及收发函数:
uint8_t NRF24L01_Check(void)
{
uint8_t buf[5]={0xa5 , 0xa5 , 0xa5 , 0xa5 , 0xa5};
uint8_t i;
NRF24L01_Write_Buf(NRF_WRITE_REG + TX_ADDR , buf , 5);
NRF24L01_Read_Buf(TX_ADDR , buf , 5);
for(i=0;i<5;i++)
if(buf[i]!=0XA5)
break;
if(i!=5)
return 1;
return 0;
}
uint8_t NRF24L01_RxPacket(uint8_t *rxbuf)
{
uint8_t sta;
sta = NRF24L01_Read_Reg(STATUS);
NRF24L01_Write_Reg(NRF_WRITE_REG + STATUS , sta);
if(sta & RX_OK)
{
printf("sta = 0x%x RX_OK.\n" , sta);
NRF24L01_Read_Buf(RD_RX_PLOAD , rxbuf , RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(FLUSH_RX , 0xff);
return 0;
}
return 1;
}
uint8_t NRF24L01_TxPacket(uint8_t *txbuf)
{
uint8_t sta;
NRF24L01_CE_LOW;
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
NRF24L01_CE_HIGH;
while(NRF24L01_IRQ_READ() != 0);
sta = NRF24L01_Read_Reg(STATUS);
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta);
if(sta&MAX_TX)
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);
return MAX_TX;
}
if(sta&TX_OK)
{
return TX_OK;
}
return 0xff;
}
void NRF24L01_RX_Mode(void)
{
NRF24L01_CE_LOW;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);
NRF24L01_CE_HIGH;
}
void NRF24L01_TX_Mode(void)
{
NRF24L01_CE_LOW;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(uint8_t*)TX_ADDRESS,TX_ADR_WIDTH);//дTX½ÚµãµØÖ·
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);
NRF24L01_CE_HIGH;
}演示视频:
https://www.bilibili.com/video/BV16DMJzbE4z/?vd_source=06455e7f94c397f493f40aba56679e79
我要赚赏金
