RF24 + Висока швидкість PWD

Я використовую arduino для генерації Pwd 100kHz за допомогою таймера 1

void setup() {
 //put your setup code here, to run once:

  //Timer 1 Fast PWM mode *toggling* OC1A at 50kHz with *two* OCR1A counts
  //And 7.32 bits 0-159 PWM on OC1B at 100kHz
  //Output on OC1B  
  //Set at TOP, Clear at OCR1B
  //WGM =15 0b1111 

   DDRB |= bit(DDB1) | bit(DDB2); //atmega168/UNO OC1A and OC1B (Tested by OP/Luis)

   TCCR1A =  bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1)  ;//Toggle OC1A, Clear on OC1B    
   TCCR1B = біт (WGM13) | біт (WGM12) | біт (CS10);//Set/1 prescaler
   OCR1A  = 159 ;//79;   //Set TOP count to 16000000/(2*PreScaler*Ftoggle)
                         //or 16000000/(PreScaler *Ftimer)
   OCR1B  = 10;          //10/160 duty cycle
   TCNT1 = 0 ;
}

void loop() {
 //put your main code here, to run repeatedly:
  OCR1B = 160/4 -1 ;//25% duty cycle. 
}

Я використовував це для тестування модулів:

Receiver
#include 
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int LED1 = 3;

void setup(void){
 Serial.begin(9600);
 radio.begin();
 radio.openReadingPipe(1,pipe);
 radio.startListening();
 pinMode(LED1, OUTPUT);}

void loop(void){
 if (radio.available()){
   bool done = false;    
   while (!done){
     done = radio.read(msg, 1);      
     Serial.println(msg[0]);
     if (msg[0] == 111){delay(10);digitalWrite(LED1, HIGH);}
     else {digitalWrite(LED1, LOW);}
     delay(100);}}
 else{Serial.println("No radio available");}}

Передавач

#include  
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int SW1 = 7;

void setup(void){
 Serial.begin(9600);
 radio.begin();
 radio.openWritingPipe(pipe);}

void loop(void){
 if (digitalRead(SW1) == HIGH){
 msg[0] = 111;
 radio.write(msg, 1);}}

I'm using this library https://github.com/TMRh20/RF24

І це добре, зараз перша проблема полягає в тому, що і RF24, і pwm використовують pin 10, але бібліотека дозволяє вам змінити її, так що тепер я використовую PIN-код 7. Я тестував це знову і все ще добре працює.

Але коли я додаю рядки під час налаштування, щоб використовувати PWD, зв'язок не працює

   DDRB |= bit(DDB1) | bit(DDB2); //atmega168/UNO OC1A 

   TCCR1A =  bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1)  ;//Toggle OC1A, Clear on OC1B    
   TCCR1B = біт (WGM13) | біт (WGM12) | біт (CS10);//Set/1 prescaler
   OCR1A  = 159 ;//79;   //Set TOP count to 16000000/(2*PreScaler*Ftoggle)
                         //or 16000000/(PreScaler *Ftimer)
   OCR1B  = 10;          //10/160 duty cycle
   TCNT1 = 0 ;

Я намагаюся створити рядки за рядком, і проблема тут:

TCCR1B = біт (WGM13) | біт (WGM12) | біт (CS10);//Set/1 prescaler

При встановленні попереднього скасування на 1.

Яка залежність RF24 від цього таймера? і які варіанти я повинен зробити це працювати

РЕДАГУВАТИ

Тепер я використовую контакти 6 і 7 для CE і CS Також видалите "| bit (COM1A0)" форму реєстру

Все-таки не працює

Я це

void setup(void)
{

  /// RF settings

  Serial.begin(9600);
 radio.begin();
 //radio.openReadingPipe(1,pipe);
 //radio.startListening();
 pinMode(LED1, OUTPUT);

 /// end RF settings


  //// pwd settings
 DDRB |= bit(DDB1) | bit(DDB2);  
   OCR1A  = max_count;      //16000000/(PreScaler *Ftimer)
   OCR1B  = 10;           
   TCCR1A =  bit(WGM11) | bit(WGM10) |  bit(COM1B1);//bit(COM1A0) | Toggle OC1A, Clear on OC1B    
   TCCR1B = біт (WGM13) | біт (WGM12) | біт (CS10);//Set/1 prescaler
   TCNT1 = 0 ;

  //// 
 }

Якщо я встановлю параметри для ШІМ перед настройками для RF24, то ШІМ не спрацює, на перших порах параметри РЧ-сигналу не працюють.

radio.begin() повинен бути перезаписаний регістрами, але я не знайшов як.

1
Може бути, той факт, що у вас є pin 10, як PWM, перешкоджає модулю SPI, який вимагає, щоб PIN-10 для виходу SPI працював?
додано Автор Majenko, джерело
NRF не потребує PIN 10, але SPI це робить. Це апаратна річ. Якщо ви можете запустити pwm без штампу 10, це може довести або спростувати це.
додано Автор Majenko, джерело
"TCCR1A = bit (WGM11) | біт (WGM10) | біт (COM1A0) | біт (COM1B1);//Ввімкнути лінію OC1A, Clear на OC1B", налаштувати PWM для керування контактами OC1A та OC1B, які складають 9 і 10 на Arduino Uno, чи шпилька 9 перешкоджає RF24 на радіостанцію RF24 (9,10 \ 7); лінія? Якщо так, ви можете вилучити частину "| bit (COM1A0)", щоб звільнити pin 9, а не PWM.
додано Автор Dave X, джерело
@DaveX Я намагаюся, все одно не працює
додано Автор Luis Ramon Ramirez Rodriguez, джерело
@Маєнко, якщо RF24 не потрібно використовувати pin 10, як я можу перевірити, чи викликає бібліотека SPI
додано Автор Luis Ramon Ramirez Rodriguez, джерело

1 Відповіді

Може, робити PWM 100kHz з таймером 2 замість таймера 1 буде добре. Реєстри виглядають схожими на таймер1, але вони лише 8 біт, тому ви не можете переходити більше, ніж 255 у регістр порівняння та підрахунку. Попередній розрядник буде таким самим, а контролери з таймером контролюватимуться D11 і D3:

  //// pwm settings for 100kHz on Timer 2
  //// Toggle OC2A/D11/PB3 at 50kHz, PWM OC2B/D3/PD3 at 100kHz:
   DDRB |= bit(DDB3); //Enable output
   DDRD |= bit(DDD3); //Enable output 
  //WGM2x=0b111 for fast PWM with TOP=OCR2A
  //COM2Ax=0b01 for toggle OC2A at OCR2A
  //COM2Bx=0b10 for [email protected]@match_OCR2B PWM 
   TCCR2A =   bit(WGM21)  | bit(WGM20)  
            | bit(COM2B1) //PWM on OC2B
            | bit(COM2A0);//Toggle OC2A    
   TCCR2B =   bit(WGM22) | bit(CS20); //Set /1 prescaler
   OCR2A  = 159;      //16000000/(PreScaler *Ftimer)-1
   OCR2B  = 10;       //6.25% PWM
   TCNT2 = 0 ;

Я не протестував це на Uno/Atmega328P, але це виглядає розумно через datasheet (стор 153-157) .

Якщо ви не хочете, щоб обидва перемикачі потужністю 50 кГц і ШІМ потужністю 100 кГц (як у вашому відправленому коді) могли відключити один або інший та налаштувати частоту, коли це необхідно.

1
додано