STM32F407VG коммуникация обнаружения SPI (nrf24l01 + pa + lna) - PullRequest
0 голосов
/ 02 мая 2020

Попытка настроить связь между обнаружением stm32f407VG и nrf24l01 через SPI. Похоже, что чтение данных из регистров идет нормально, но есть проблема с записью в них, потому что, не имеет значения, пишу ли я что-то для регистрации или нет, всегда отображаются одинаковые значения, разные для каждого регистра и не 0x00 или 0xFF. Я посмотрел на библиотеку Arduino для nrf24l01, и мои функции регистра чтения / записи выглядят одинаково, поэтому похоже, что проблема в настройке SPI или функциях передачи. Я попытался подключить этот чип к Arduino, и он работал нормально, поэтому чип точно не сломан. Google мало чем помог, потому что на stm32f4 почти нет информации о конфигурации SPI, большая часть информации о серии stm32f1. Любая идея, что там может быть не так?
Файл SPI:

#ifndef SPI_H
#define SPI_H
#include "stm32f4xx.h"
void SPI1_init(void){
    RCC->AHB1ENR |= 1;
    RCC->APB2ENR |= 0x1000;

    GPIOA->MODER &= ~0x0000FC00;
    GPIOA->MODER |= 0x0000A800;
    GPIOA->OTYPER &= ~0b11100000;
    GPIOA->PUPDR &= ~0b1111110000000000;
    GPIOA->PUPDR |= 0b0101100000000000;
    GPIOA->AFR[0] &= ~0xFFF00000;
    GPIOA->AFR[0] |= 0x55500000;
    GPIOA->MODER &= ~0x00000300;
    GPIOA->MODER |= 0x00000100;
    GPIOA->MODER &= ~(3<<6);
    GPIOA->MODER |= (1<<6);
    SPI1->CR1 = 0x31C;
    SPI1->CR2 = 0;
    SPI1->CR1 |= 0x40;
}
void SPI1_write(unsigned char data){
    while(!(SPI1->SR & SPI_SR_TXE));
    //GPIOA->BSRRH = 0x0010;
    SPI1->DR = data;
    while(!(SPI1->SR & 0x80));
    //GPIOA->BSRRL = 0x0010;
}
unsigned char SPI1_read(void){
    while(!(SPI1->SR & SPI_SR_RXNE));
    //GPIOA->BSRRH = 0x0010;
    return SPI1->DR;
    //GPIOA->BSRRL = 0x0010;
}
uint8_t SPI_comm(uint8_t data){
    while(!(SPI1->SR & SPI_SR_TXE));
    //GPIOA->BSRRH = 0x0010;
    SPI1->DR = data;
    //while(!(SPI1->SR & 0x80));
    while(!(SPI1->SR & SPI_SR_RXNE));
    data = SPI1->DR;
    //GPIOA->BSRRL = 0x0010;
    return data;
}
void SPI1_bufWrite(uint8_t * buf, uint8_t size){
    for(uint8_t i=0;i<size;i++){
        while(!(SPI1->SR & 2));
        SPI1->DR = buf[i];
        while(!(SPI1->SR & 0x80));
    }
}
void SPI1_bufRead(uint8_t * buf, uint8_t size){
    for(uint8_t i=0;i<size;i++){
        while(!(SPI1->SR & SPI_SR_RXNE));
        buf[i]=SPI1->DR;
    }
}
#endif

, на случай, если это будет полезно, есть другой файл с функциями CS low / high и функциями nrf24l01:

#ifndef RF24LIB_H
#define RF24LIB_H
#include "spi.h"
#include "rf24.h"
#include "timer.h"

#define TX_ADR_WIDTH 3
#define TX_PLOAD_WIDTH 2
uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0xb3,0xb4,0x01};
uint8_t RX_BUF[TX_PLOAD_WIDTH] = {0};

void CSN_L(void){
    GPIOA->BSRRH = 0x0010;
}
void CSN_H(void){
    GPIOA->BSRRL = 0x0010;
}
void CE_L(void){
    GPIOA->BSRRH = (1<<3);
}
void CE_H(void){
    GPIOA->BSRRL = (1<<3);
}
uint8_t nRF24_ReadReg(uint8_t reg){
    CSN_L();
    SPI_comm(R_REGISTER|(REGISTER_MASK & reg));
    reg = SPI_comm(0xFF);
    CSN_H();
    return reg;
}
void nRF24_WriteReg(uint8_t reg, uint8_t val){
    CSN_L();
    SPI1_write(W_REGISTER | ( REGISTER_MASK & reg ));
    SPI1_write(val);
    CSN_H();
}
uint8_t nRF24_ReadMReg(uint8_t reg, uint8_t * buffer, uint8_t size){
    CSN_L();
    SPI1_write(R_REGISTER|(REGISTER_MASK&reg));
    for(int i=0;i<size;i++){
        SPI1_write(0xff);
    }
    SPI1_bufRead(buffer, size);
    CSN_H();
    return reg;
}
uint8_t nRF24_WriteMReg(uint8_t reg, uint8_t * buffer, uint8_t size){
    CSN_L();
    SPI1_write(W_REGISTER|(REGISTER_MASK&reg));
    delayUs(1);
    SPI1_bufWrite(buffer, size);
    CSN_H();
    return reg;
}
void flush_rx(void){
    CSN_L();
    SPI_comm(FLUSH_RX);
    delayUs(1);
    CSN_H();
}
void flush_tx(void){
    CSN_L();
    SPI_comm(FLUSH_TX);
    delayUs(1);
    CSN_H();
}
void NRF24L01_RX_Mode(void)
{
  uint8_t regval=0x00;
  regval = nRF24_ReadReg(CONFIG);
  regval |= (1<<PWR_UP)|(1<<PRIM_RX);
  nRF24_WriteReg(CONFIG,regval);
  CE_L();
  delayUs(150);
  flush_rx();
    flush_tx();
}
void nRF24_ToggleFeatures(void){
    CSN_L();
    SPI1_write(ACTIVATE);
    delayUs(1);
    SPI1_write(0x73);
    CSN_H();
}
void nRF24_init(void){
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
    GPIOD->MODER = 0x55000000;
    CE_H();
    delayMs(5);
    nRF24_WriteReg(CONFIG, 0x0A);
    delayMs(5);
    nRF24_WriteReg(EN_AA, 0x01);
    nRF24_WriteReg(EN_RXADDR, 0x01);
    nRF24_WriteReg(SETUP_AW, 0x01);//addr width
    nRF24_WriteReg(SETUP_RETR, 0x5F);
    nRF24_ToggleFeatures();
    nRF24_WriteReg(FEATURE, 0);
    nRF24_WriteReg(DYNPD, 0);
    nRF24_WriteReg(STATUS, 0x70);
    nRF24_WriteReg(RF_CH, 76);
    nRF24_WriteReg(RF_SETUP, 0x06);
    nRF24_WriteMReg(TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
  nRF24_WriteMReg(RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
    nRF24_WriteReg(RX_PW_P0, TX_PLOAD_WIDTH);
    NRF24L01_RX_Mode();
    GPIOD->ODR = 0xF000;
}
#endif
...