Гость Влад

STM32 & NRF24l01 +

23 сообщения в этой теме

Гость Влад   
Гость Влад

Помогите, не могу через SPI получить от NRF состояние регистров.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00

А ты библиотеку сам набросал, или готовую взял? Я просто сам написал библиотеку, вот только не работают функция отправки и получения байта, что на меге, что на стм

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Вот мой код, я без библиотек. И я просто хочу спросить NRF и все. А оно мне ничего не шлет. Или NRF тоже настроить нужно? Тогда как? В инете ничего нету.

#include "stm32f10x.h"

int a = 0;
void RCC_Init(){
    RCC_DeInit(); //Відключаємо всі генератори.
    RCC->CR |= RCC_CR_HSION; //Вмикаємо внутрішній генератор
    ////////////////////////////////////////////////////////
    RCC->APB2ENR = RCC_APB2ENR_AFIOEN // Тактування альтернативних функцій
    | RCC_APB2ENR_IOPAEN // Тактування порта А
    | RCC_APB2ENR_SPI1EN; // Тактування SPI
}
void GPIO_REG_Init(){
    GPIOA->CRL = 0xBBB30000;
    GPIOA->ODR = 0x0010;
}
void SPI_REG_Init(){
    SPI1->CR1 |= SPI_CR1_BR;
    SPI1->CR1 |= SPI_CR1_SSM;
    SPI1->CR1 |= SPI_CR1_SSI;
    SPI1->CR1 |= SPI_CR1_MSTR;
    SPI1->CR1 |= SPI_CR1_SPE;
}
void SPI_Transmit(char data){
    GPIOA->ODR &= 0xFFEF;
    SPI1->DR = data; // Передати дані по SPI
    while(!(SPI1->SR & SPI_SR_TXE)); // Робити цей цик поки буфер буде повний
    GPIOA->ODR = 0x0010;
}
int SPI_Read_1(){
    //while(!(SPI1->SR & SPI_SR_RXNE)); 
    return SPI1->DR;
}
void delay(uint32_t time_delay)
{    
    uint32_t i;
    for(i = 0; i < time_delay; i++);
}
int main(){
    RCC_Init();
    GPIO_REG_Init();
    SPI_REG_Init();
    
    while(1){
        GPIOA->ODR &= 0xFFEF;
        SPI1->DR = 0x21;
        a = SPI1->DR;
        while(!(SPI1->SR & SPI_SR_TXE));
        SPI1->DR = 0x1C;
        a = SPI1->DR;
        while(!(SPI1->SR & SPI_SR_TXE));
        SPI1->DR = 0x01;
        a = SPI1->DR;
        while(!(SPI1->SR & SPI_SR_TXE));
        delay(100);
        //while(!(SPI1->SR & SPI_SR_RXNE));
        a = SPI1->DR;
        GPIOA->ODR = 0x0010;
    }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

nrf нужно настроить, мощность передатчика, прием или передача, включить его, настроить номер канала и его идентификатор, и много чего еще, опрашивать и настраивать, а ты просто по SPI в него данные грузишь, так никогда не заработает, в даташите есть все регистры с которыми нужно работать

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Вот вот, я хочу настроить регистр хотя б 1. Настроить и считать, а оно мне кидает да не то. За пересылку я вообще молчу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
snn_krs    3
5 hours ago, Guest Влад said:

delay(100);

Слишком маленькая задержка. Я делал ожидание флага BSY и все работало

5 hours ago, Guest Влад said:

GPIOA->ODR = 0x0010;

GPIOA->ODR   |= 0x0010;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Я настроил передачу по протоколу SPI между двумя контроллерами нормально. А вот спросить NRF не получается. Функция вот такая:

GPIOA->ODR &= 0xFFEF; // Опускаю линию на ноль

SPI1->DR = 0x20; // Отправил чтение и сам регистр

while(!(SPI1->SR & SPI_SR_TXE));

SPI1->DR = 0xFF; // Записал значение регистра

while(!(SPI1->SR & SPI_SR_TXE));

GPIOA->ODR &= 0x0010; // Поднимаю линию на 3.3

 

GPIOA->ODR &= 0xFFEF;

SPI1->DR = 0x00; // Считал регистр 00 Config

a = SPI1->DR; // Считали в переменую а, то что пришло в ответ.

while(!(SPI1->SR & SPI_SR_TXE));

GPIOA->ODR &= 0x0010;

 

Или я что не понимаю, или хз.

Напишите как у вас в програме.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
snn_krs    3
6 hours ago, Guest Влад said:

while(!(SPI1->SR & SPI_SR_TXE));

GPIOA->ODR &= 0x0010; // Поднимаю линию на 3.3

Флаг TXE устанавливается после пересылке в сдвиговый регистр. Флаг BSY устанавливается после завершения передачи

while ( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_BSY ) == SET ) {}

Это для STM32F030F4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Я отправляю 0x21 и значение регистра а оно мне напостой возврат 0xE

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
snn_krs    3
8 hours ago, Guest Влад said:

а оно мне напостой возврат 0xE

При передаче первого байта в ответ присылается СТАТУС = 0xE - ФИФО буфер передатчика пуст, готов к передачи

При передаче следующих будут данные если команда - СЧИТАТЬ регистр (0x2А - это запись, 0x0А - чтение)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Всем спасибо, все получилось.

Я не правильно считал регистр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тебе удалось что-то передать и принять? На какой частоте настроенo тактирование  SPI, и в каком режиме полный или полудуплекс? А то набросал библиотеку на Атмегу, с номерами каналов, регулировкой выходной мощности, с номером идентификатора канала, и прочими настройками с приемом по прерыванию, и перенес это все на STM32 в IAR и не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

Вот мой код.

 

#include "stm32f10x.h"

/* Команди */

#define nRF_CMD_R_REGISTER         0x00 // Команда для зчитування регістрів
#define nRF_CMD_W_REGISTER         0x20 // Команда для запису в регістри
#define nRF_CMD_R_RX_PAYLOAD     0x61 // 
#define nRF_CMD_W_TX_PAYLOAD     0xA0 //
#define nRF_CMD_FLUSH_TX             0xE1 // 
#define nRF_CMD_FLUSH_RX             0xE2 // 
#define nRF_CMD_REUSE_TX_PL     0x71 // 
#define nRF_CMD_R_RX_PL_WID     0x60 // 
#define nRF_CMD_W_ACK_PAYLOAD 0xA8 // 
#define nRF_CMD_W_NO_ACK_PAYLOAD 0xB0
#define nRF_CMD_NOP                     0xFF // Команда затичка

/* Регістри nRF24l01+ */

#define nRF_CONFIG             0x00
#define nRF_EN_AA             0x01
#define nRF_EN_RXADDR     0x02
#define nRF_SETUP_AW         0x03
#define nRF_SETUP_RETR     0x04
#define nRF_RF_CH             0x05
#define nRF_RF_SETUP         0x06
#define nRF_STATUS             0x07
#define nRF_OBSERVE_TX     0x08
#define nRF_RPD                 0x09
#define nRF_RX_ADDR_P0     0x0A
#define nRF_RX_ADDR_P1     0x0B
#define nRF_RX_ADDR_P2     0x0C
#define nRF_RX_ADDR_P3     0x0D
#define nRF_RX_ADDR_P4     0x0E
#define nRF_RX_ADDR_P5     0x0F
#define nRF_TX_ADDR         0x10
#define nRF_RX_PW_P0         0x11
#define nRF_RX_PW_P1         0x12
#define nRF_RX_PW_P2         0x13
#define nRF_RX_PW_P3         0x14
#define nRF_RX_PW_P4         0x15
#define nRF_RX_PW_P5         0x16
#define nRF_FIFO_STATUS 0x17
#define nRF_DYNPD             0x1C
#define nRF_FEATURE         0x1D


/* SCRIPT */

#define nRF_CMD_MASK         0x1F
#define CSS_L (GPIOA->ODR &= ~GPIO_ODR_ODR4);
#define CSS_H (GPIOA->ODR |= GPIO_ODR_ODR4);
#define CE_H (GPIOA->ODR |= GPIO_ODR_ODR3);
#define CE_L (GPIOA->ODR &= ~GPIO_ODR_ODR3);

/////////////////////////////////////////////////////////////////////////////
/* Змінні */

int a = 0;
uint8_t buff [5];
uint8_t ADDR_TX [] = {0xC1, 0xC2, 0xC3, 0xC4, 0xC5};
uint8_t Buff_write [] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};

void delay(uint32_t time_delay)
{    
    uint32_t i;
    for(i = 0; i < time_delay; i++);
}

char SPI_TRANSMIT (char data){
    while(!(SPI1->SR & SPI_SR_TXE)); // Ждемо поки біт не підгутують до відправлення 
    while(SPI1->SR & SPI_SR_BSY); // Ждемо поки біт передадуть
    SPI1->DR = data; // Передаємо данні
    while(!(SPI1->SR & SPI_SR_TXE));
    while(SPI1->SR & SPI_SR_BSY);
    return SPI1->DR; // Повертаємо те що прийшло у відповідь
}

void RCC_REG_INIT(){
    RCC_DeInit();
    RCC->CR |= RCC_CR_HSION; // Включаємо внутрішній генератор 8 МГц
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Вмикаємо тактування альтернативних функцій
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Вмикаємо тактування Порта А
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Вмикаємо тактування SPI1
}

void GPIO_REG_INIT(){
    GPIOA->CRL = 0x00000000; // Очищуємо регістер від значень
    GPIOA->CRL |= GPIO_CRL_MODE7_1; // 2 МГц PA7
    GPIOA->CRL |= GPIO_CRL_MODE6_1; // 2 МГц PA6
    GPIOA->CRL |= GPIO_CRL_MODE5_1; // 2 МГц PA5
    GPIOA->CRL |= GPIO_CRL_MODE4_1; // 2 МГц PA4
    GPIOA->CRL |= GPIO_CRL_MODE3_1; // 2 МГц PA3
    
    
    GPIOA->CRL |= GPIO_CRL_CNF7_1; //    Альтернативна функція PA7 Push-pull
    GPIOA->CRL |= GPIO_CRL_CNF6_1; //    Альтернативна функція PA6 Push-pull
    GPIOA->CRL |= GPIO_CRL_CNF5_1; //    Альтернативна функція PA5 Push-pull
    
    
    GPIOA->ODR |= GPIO_ODR_ODR4; // Підтяжка до 3.3 В
    GPIOA->ODR |= GPIO_ODR_ODR5; // Підтяжка до 3.3 В
    GPIOA->ODR |= GPIO_ODR_ODR6; // Підтяжка до 3.3 В
    GPIOA->ODR |= GPIO_ODR_ODR7; // Підтяжка до 3.3 В
    
}

void SPI1_REG_INIT (){
    SPI1->CR1 = 0x00000000; // Очищуємо регістер від значень
    SPI1->CR1 |= SPI_CR1_MSTR; // Контролер у режимі мастера
    SPI1->CR1 |= SPI_CR1_SSM; // Дозволяємо програмно обрати слейва
    SPI1->CR1 |= SPI_CR1_SSI; // Високий рівень NSS
    SPI1->CR1 |= SPI_CR1_BR_1; // Частота передачі SPI1 8 MHz/4
    SPI1->CR1 |= SPI_CR1_SPE; // Вмикаємо SPI1
}

static char nRF_READ_REGISTER (char reg){
    char value;
    CSS_L // Скидаємо PA4 у низький рівень
    SPI_TRANSMIT(reg & nRF_CMD_MASK); // Відсилаємо запит на зчитування регістра
    value = SPI_TRANSMIT(nRF_CMD_NOP); // Відсилаємо пусту команду та забераємо дані які прийшли
    CSS_H // Піднімаємо PA4 високий рівень
    return value; // Повертає значення
}

static void nRF_WRITE_REGISTER (char REG, char data){
    CSS_L;
    SPI_TRANSMIT(nRF_CMD_W_REGISTER | (REG & nRF_CMD_MASK));
    SPI_TRANSMIT(data);
    CSS_H;
}

 static void nRF_READ_REGISTER_TO_BUFFER(uint8_t reg, uint8_t *pBuf, uint8_t count) {
     CSS_L;
     SPI_TRANSMIT(reg);
     while (count--) {
         *pBuf++ = SPI_TRANSMIT(nRF_CMD_NOP);
     }
     CSS_H;
 }

 static void nRF_Write_REGISTER_OUT_BUFFER(uint8_t reg, uint8_t *pBuf, uint8_t count) {
     CSS_L;
     SPI_TRANSMIT(nRF_CMD_W_REGISTER | (reg & nRF_CMD_MASK));
     while (count--) {
         SPI_TRANSMIT(*pBuf++);
     }
     CSS_H;
 }
 
 static void nRF_INIT(){
     //nRF_WRITE_REGISTER(nRF_EN_RXADDR, 0x01); // Вмикаємо 0 канал для приймання автопідтвердження.
     nRF_WRITE_REGISTER(nRF_SETUP_AW, 0x03); // Встановлюємо довжину адреси у 5 байт
     nRF_Write_REGISTER_OUT_BUFFER(nRF_RX_ADDR_P0, ADDR_TX, 5); // Встановляємо адресу по якій буде приходити підтвердження
     nRF_Write_REGISTER_OUT_BUFFER(nRF_TX_ADDR, ADDR_TX, 5); // Встановляємо адресу приймача каналу P1
     nRF_WRITE_REGISTER(nRF_FEATURE, 0x01); // Включаємо підтримку передачі пакетів з підтвердженням та передачі не фіксованої довжини
     nRF_WRITE_REGISTER(nRF_CONFIG, 0x02); // Вмикаємо передавач
     delay(300);
 }
 
 void nRF_SEND(){
     nRF_Write_REGISTER_OUT_BUFFER(nRF_CMD_W_NO_ACK_PAYLOAD, Buff_write, 32);
     //CE_H;
     delay(50);
     //CE_L;
 }
 
 
int main (){
    RCC_REG_INIT();
    GPIO_REG_INIT();
    SPI1_REG_INIT();
    nRF_INIT();
    
    while(1) {
        nRF_SEND();
        nRF_READ_REGISTER(nRF_FIFO_STATUS);
        nRF_READ_REGISTER(nRF_STATUS);
    }
}
 

У меня получилось с nRF говорить, но передать в очередь теперь не получается. Сижу мучаюсь дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Skyluck    0

В nRF нужно смотреть в оба на регистры, потому что там хз что делается. По умолчанию одно а по факту другое, возможно нужно ставить подтяжки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость Влад   
Гость Влад

У меня все получилось, я передал биты и вроди все норм, ноооо, подтверждение я не могу выставить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я себе написал код и на передачу работает не проблема, причем сделал функции и настройку скорости передачи, и настройку мощности,и настройку номера канала, и настройку номера трубы, и на Атмеге все четко, а вот прием на СТМ 32 почему-то 2 раза заработал и опять не работает, а передача передаю с СТМ 32 на Атмегу все хорошо, теперь ломаю голову, прием делаю через IRQ на прерывание СТМ32

Изменено пользователем Электронщик

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...

  • Похожие публикации

    • Гость Илья
      Автор: Гость Илья
      Доброго времени суток, уважаемые читатели. Решил собрать зеркало в ванную комнату, такое, чтоб новости сообщало, погоду, время, и еще показания пары датчиков. Внешне будет смотреться органично, выложу проект, пока что заказываю комплектующие. 
      Возник следующий вопрос; возможно ли на stm32 сделать какую-никакую графику, чтоб при этом работала не как слайд шоу? K примеру, на дисплее погода, махнул рукой, появились новости, выбрал нужную, читаешь, перелистываешь.
      Встраивать малинку считаю нецелесообразным, все-таки зеркало, а не медиа-центр.
      Жду ваших советов!
    • Автор: nick32
      Здравствуйте. У st.com, похоже, что-то сломалось, и драйвер не скачивается. Скиньте, пожалуйста, установщик драйвера.
    • Автор: MDG_Lab
      Здравствуйте! 
      Ткните пожалуйста носом начинающего, как в Arduino IDE настроить частоту ШИМ. 
      Работаю с STM32F103, функции analogWrite(*); pwmWrite(*); Этими функциями задаю номер порта и коэффициент заполнения.
    • Автор: TIGER53501
      Привет, никак не могу разобраться с таймером в режиме сброса по внешнему событию,
      сам сброс работает, таймер сбрасывается, вопрос вот в чём, могу ли я в этом режиме использовать захват на оставшихся каналах?
      т.е. по внешнему событию сбрасывать таймер, и потом внешними событиями записывать сколько он протикал с момента сброса?
      STM32F429ZI
      СИ + VisualGDB + HAL + Cube
    • Автор: misterflud
      В общем нужна библиотека для вывода текста с STM32RB100 на экран 1602a. Соединение -- через 4 или 8 ножки. Я вам даю микроконтроллер и дисплей, а вы ищите или пишите библиотеку для этого. В общем нужно чтобы заработало. Если дисплей не работает, то подобрать другой.
      Пишите сюда либо на почту yurolejniko@yandex.ru