1

Тема: Частотомер

  
     volatile int  mon_flag;
     unsigned long freq;

void setup() {
 Serial.begin(9600);
pinMode(PA15,INPUT_PULLDOWN); // вход частотометра
    RCC_BASE->APB1ENR|= (1<<2)|(1<<1)|(1<<0); //включить тактирование tim-2,3,4
    RCC_BASE->APB2ENR|= (1<<3)|(1<<11)|(1<<2)|(1<<0)|(1<<4);////включить тактирование port-a-b-c,tim1
    AFIO_BASE->MAPR=(1<<8)|(1<<6); //tim 1 && tim 2 Partial remap

}

void loop() {
 freq_meter();
 Serial.println(freq);

}

void freq_meter(){  // http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino#comment-296530
   __asm volatile( "cpsid i" );
   /// Timer2 счёт младших 16 бит
    TIMER2_BASE->CR1=0;//стоп таймер
    TIMER2_BASE->CCER=0; TIMER2_BASE->PSC=0;  TIMER2_BASE->CNT=0; 
    TIMER2_BASE->CCR1=0; TIMER2_BASE->CCR2=0; TIMER2_BASE->CCR3=0; 
    TIMER2_BASE->CCR4=0;TIMER2_BASE->PSC=0;TIMER2_BASE->SR=0;
    TIMER2_BASE->CCMR2=0;
    TIMER2_BASE->CR2=1<<5; //MMS:010 управление подчинённым в режиме "Update" 
    TIMER2_BASE->SMCR= (1<<14);// ECE & TS:000  режим 2 внешнего тактирования & разрешение работы от таймера1
    TIMER2_BASE->ARR=65535; //считать до максимума
    TIMER2_BASE->EGR=1; //перечитать регистры.
    TIMER2_BASE->CR1|=(1<<0);//start timer2
   /// Timer3 счёт старших 16 бит
    TIMER3_BASE->CR1=1<<0;//стоп таймер
    TIMER3_BASE->CCER=0; TIMER3_BASE->PSC=0; TIMER3_BASE->CNT=0; 
    TIMER3_BASE->CCR1=0; TIMER3_BASE->CCR2=0; TIMER3_BASE->CCR3=0; 
    TIMER3_BASE->CCR4=0;TIMER3_BASE->PSC=0;TIMER3_BASE->SR=0;TIMER3_BASE->CR2=0;  
    TIMER3_BASE->CCMR1=0; 
    TIMER3_BASE->SMCR=(1<<2)|(1<<1)|(1<<0)|(1<<4);//SMS:111 && TS:001  такт брать от 2-го таймера  
    TIMER3_BASE->ARR=65535; //считать до 
    TIMER3_BASE->EGR=1; //перечитать регистры.
    TIMER3_BASE->CR1|=(1<<0);//start timer3
 /// настройка времени разрешения на таймере1 для таймера2
    TIMER1_BASE->CR1=(1<<3)|(1<<2);//один импульс, без прерываний
    TIMER1_BASE->CNT=0;
    TIMER1_BASE->CR2=(1<<4);  //MMS:001 сигнал разрешения работы другим таймерам
    TIMER1_BASE->CCER=0;// отключить выходы таймера на физ ноги
    TIMER1_BASE->PSC=F_CPU/36000 -1;// 1999; // 72000000/2000= 36000кГц тактовая таймера 
    TIMER1_BASE->ARR=36000;//считать до 36000 (1секунда) 
    TIMER1_BASE->EGR=1; //перечитать регистры.
    TIMER1_BASE->CR1|=(1<<0);
    __asm volatile( "cpsie i" );
    while (TIMER1_BASE->CR1&1) {asm volatile("nop"); if(mon_flag) {return;}  }
    freq = TIMER3_BASE->CNT<<16  | TIMER2_BASE->CNT ; 
} 

2

Re: Частотомер

#include <LedControl.h>//https://github.com/wayoda/LedControl/archive/master.zip  
     LedControl lc = LedControl(PB1,PB10,PB11,1);// DIN(PB1), CLK(PB10), CS(PB11)
     
     volatile int  mon_flag;
     unsigned long freq;
     byte fq[8],pd,x;

void setup() {
 Serial.begin(9600);
      lc.shutdown(0, false); 
      lc.setIntensity(0,8); // яркость 0-15
      lc.clearDisplay(0); 
    pinMode(PA15,INPUT_PULLDOWN); // вход частотометра
 
    RCC_BASE->APB1ENR|= (1<<2)|(1<<1)|(1<<0); //включить тактирование tim-2,3,4
    RCC_BASE->APB2ENR|= (1<<3)|(1<<11)|(1<<2)|(1<<0)|(1<<4);////включить тактирование port-a-b-c,tim1
    AFIO_BASE->MAPR=(1<<8)|(1<<6); //tim 1 && tim 2 Partial remap
  
}

void loop() {
 freq_meter();
 Serial.println(freq);
  fq[7]= freq/10000000%10;
  fq[6]= freq/1000000%10;
  fq[5]= freq/100000%10;
  fq[4]= freq/10000%10;
  fq[3]= freq/1000%10;
  fq[2]= freq/100%10;
  fq[1]= freq/10%10;
  fq[0]= freq%10%10;

  if(freq>=10000000){x=8;}
  if(freq<10000000){lc.setRow(0,7,0);x=7;}
  if(freq<1000000){lc.setRow(0,6,0);x=6;}
  if(freq<100000){lc.setRow(0,5,0);x=5;}
  if(freq<10000){lc.setRow(0,4,0);x=4;}
  if(freq<1000){lc.setRow(0,3,0);x=3;}
  if(freq<100){lc.setRow(0,2,0);x=2;}
  if(freq<10){lc.setRow(0,1,0);x=1;}
  
  for(int i = 0;i < x;i++){
  if(i==3){pd=true;}
  else if(i==6){pd=true;}
  else if(i==9){pd=true;}
  else{pd=false;}
  lc.setDigit(0,i,fq[i],pd);}

 // delay(100);

}

void freq_meter(){  // http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino#comment-296530
   __asm volatile( "cpsid i" );
   /// Timer2 счёт младших 16 бит
    TIMER2_BASE->CR1=0;//стоп таймер
    TIMER2_BASE->CCER=0; TIMER2_BASE->PSC=0;  TIMER2_BASE->CNT=0; 
    TIMER2_BASE->CCR1=0; TIMER2_BASE->CCR2=0; TIMER2_BASE->CCR3=0; 
    TIMER2_BASE->CCR4=0;TIMER2_BASE->PSC=0;TIMER2_BASE->SR=0;
    TIMER2_BASE->CCMR2=0;
    TIMER2_BASE->CR2=1<<5; //MMS:010 управление подчинённым в режиме "Update" 
    TIMER2_BASE->SMCR= (1<<14);// ECE & TS:000  режим 2 внешнего тактирования & разрешение работы от таймера1
    TIMER2_BASE->ARR=65535; //считать до максимума
    TIMER2_BASE->EGR=1; //перечитать регистры.
    TIMER2_BASE->CR1|=(1<<0);//start timer2
   /// Timer3 счёт старших 16 бит
    TIMER3_BASE->CR1=1<<0;//стоп таймер
    TIMER3_BASE->CCER=0; TIMER3_BASE->PSC=0; TIMER3_BASE->CNT=0; 
    TIMER3_BASE->CCR1=0; TIMER3_BASE->CCR2=0; TIMER3_BASE->CCR3=0; 
    TIMER3_BASE->CCR4=0;TIMER3_BASE->PSC=0;TIMER3_BASE->SR=0;TIMER3_BASE->CR2=0;  
    TIMER3_BASE->CCMR1=0; 
    TIMER3_BASE->SMCR=(1<<2)|(1<<1)|(1<<0)|(1<<4);//SMS:111 && TS:001  такт брать от 2-го таймера  
    TIMER3_BASE->ARR=65535; //считать до 
    TIMER3_BASE->EGR=1; //перечитать регистры.
    TIMER3_BASE->CR1|=(1<<0);//start timer3
 /// настройка времени разрешения на таймере1 для таймера2
    TIMER1_BASE->CR1=(1<<3)|(1<<2);//один импульс, без прерываний
    TIMER1_BASE->CNT=0;
    TIMER1_BASE->CR2=(1<<4);  //MMS:001 сигнал разрешения работы другим таймерам
    TIMER1_BASE->CCER=0;// отключить выходы таймера на физ ноги
    TIMER1_BASE->PSC=F_CPU/36000 -1 ;// 1999; // 72000000/2000= 36000кГц тактовая таймера 
    TIMER1_BASE->ARR=36000;//считать до 36000 (1секунда) 
    TIMER1_BASE->EGR=1; //перечитать регистры.
    TIMER1_BASE->CR1|=(1<<0);
    __asm volatile( "cpsie i" );
    while (TIMER1_BASE->CR1&1) {asm volatile("nop"); if(mon_flag) {return;}  }
    freq = TIMER3_BASE->CNT<<16  | TIMER2_BASE->CNT ; 
} 

3

Re: Частотомер

Может разумно использовать  oled i2c?

4

Re: Частотомер

LCD показывает 0, не реагирует на подачу сигнала на PA7

//////////
HardwareTimer pwmtimer4(4);
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
/////////
volatile int  mon_flag;
unsigned long freq;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(PA7, INPUT_PULLDOWN); // вход частотометра
  RCC_BASE->APB1ENR |= (1 << 2) | (1 << 1) | (1 << 0); //включить тактирование tim-2,3,4
  RCC_BASE->APB2ENR |= (1 << 3) | (1 << 11) | (1 << 2) | (1 << 0) | (1 << 4); ////включить тактирование port-a-b-c,tim1
  AFIO_BASE->MAPR = (1 << 8) | (1 << 6); //tim 1 && tim 2 Partial remap

}

void loop() {
  freq_meter();
  Serial.println(freq);
  lcd.setCursor(0, 0);
  lcd.print("FREQ ");
  lcd.print(freq); //


}

void freq_meter() { // http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino#comment-296530
  __asm volatile( "cpsid i" );
  /// Timer2 счёт младших 16 бит
  TIMER2_BASE->CR1 = 0; //стоп таймер
  TIMER2_BASE->CCER = 0; TIMER2_BASE->PSC = 0;  TIMER2_BASE->CNT = 0;
  TIMER2_BASE->CCR1 = 0; TIMER2_BASE->CCR2 = 0; TIMER2_BASE->CCR3 = 0;
  TIMER2_BASE->CCR4 = 0; TIMER2_BASE->PSC = 0; TIMER2_BASE->SR = 0;
  TIMER2_BASE->CCMR2 = 0;
  TIMER2_BASE->CR2 = 1 << 5; //MMS:010 управление подчинённым в режиме "Update"
  TIMER2_BASE->SMCR = (1 << 14); // ECE & TS:000  режим 2 внешнего тактирования & разрешение работы от таймера1
  TIMER2_BASE->ARR = 65535; //считать до максимума
  TIMER2_BASE->EGR = 1; //перечитать регистры.
  TIMER2_BASE->CR1 |= (1 << 0); //start timer2
  /// Timer3 счёт старших 16 бит
  TIMER3_BASE->CR1 = 1 << 0; //стоп таймер
  TIMER3_BASE->CCER = 0; TIMER3_BASE->PSC = 0; TIMER3_BASE->CNT = 0;
  TIMER3_BASE->CCR1 = 0; TIMER3_BASE->CCR2 = 0; TIMER3_BASE->CCR3 = 0;
  TIMER3_BASE->CCR4 = 0; TIMER3_BASE->PSC = 0; TIMER3_BASE->SR = 0; TIMER3_BASE->CR2 = 0;
  TIMER3_BASE->CCMR1 = 0;
  TIMER3_BASE->SMCR = (1 << 2) | (1 << 1) | (1 << 0) | (1 << 4); //SMS:111 && TS:001  такт брать от 2-го таймера
  TIMER3_BASE->ARR = 65535; //считать до
  TIMER3_BASE->EGR = 1; //перечитать регистры.
  TIMER3_BASE->CR1 |= (1 << 0); //start timer3
  /// настройка времени разрешения на таймере1 для таймера2
  TIMER1_BASE->CR1 = (1 << 3) | (1 << 2); //один импульс, без прерываний
  TIMER1_BASE->CNT = 0;
  TIMER1_BASE->CR2 = (1 << 4); //MMS:001 сигнал разрешения работы другим таймерам
  TIMER1_BASE->CCER = 0; // отключить выходы таймера на физ ноги
  TIMER1_BASE->PSC = F_CPU / 36000 - 1; // 1999; // 72000000/2000= 36000кГц тактовая таймера
  TIMER1_BASE->ARR = 36000; //считать до 36000 (1секунда)
  TIMER1_BASE->EGR = 1; //перечитать регистры.
  TIMER1_BASE->CR1 |= (1 << 0);
  __asm volatile( "cpsie i" );
  while (TIMER1_BASE->CR1 & 1) {
    asm volatile("nop");
    if (mon_flag) {
      return;
    }
  }
  freq = TIMER3_BASE->CNT << 16  | TIMER2_BASE->CNT ;
}

5

Re: Частотомер

Попробуйте так:

//////////
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
/////////
volatile int  mon_flag;
unsigned long freq;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(PA15, INPUT_PULLDOWN); // вход частотометра PA15
  RCC_BASE->APB1ENR |= (1 << 2) | (1 << 1) | (1 << 0); //включить тактирование tim-2,3,4
  RCC_BASE->APB2ENR |= (1 << 3) | (1 << 11) | (1 << 2) | (1 << 0) | (1 << 4); ////включить тактирование port-a-b-c,tim1
  AFIO_BASE->MAPR = (1 << 8) | (1 << 6); //tim 1 && tim 2 Partial remap

}

void loop() {
  freq_meter();
  Serial.println(freq);
  lcd.setCursor(0, 0);
  lcd.print("FREQ ");
  lcd.print(freq); //


}

void freq_meter() { // http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino#comment-296530
  __asm volatile( "cpsid i" );
  /// Timer2 счёт младших 16 бит
  TIMER2_BASE->CR1 = 0; //стоп таймер
  TIMER2_BASE->CCER = 0; TIMER2_BASE->PSC = 0;  TIMER2_BASE->CNT = 0;
  TIMER2_BASE->CCR1 = 0; TIMER2_BASE->CCR2 = 0; TIMER2_BASE->CCR3 = 0;
  TIMER2_BASE->CCR4 = 0; TIMER2_BASE->PSC = 0; TIMER2_BASE->SR = 0;
  TIMER2_BASE->CCMR2 = 0;
  TIMER2_BASE->CR2 = 1 << 5; //MMS:010 управление подчинённым в режиме "Update"
  TIMER2_BASE->SMCR = (1 << 14); // ECE & TS:000  режим 2 внешнего тактирования & разрешение работы от таймера1
  TIMER2_BASE->ARR = 65535; //считать до максимума
  TIMER2_BASE->EGR = 1; //перечитать регистры.
  TIMER2_BASE->CR1 |= (1 << 0); //start timer2
  /// Timer3 счёт старших 16 бит
  TIMER3_BASE->CR1 = 1 << 0; //стоп таймер
  TIMER3_BASE->CCER = 0; TIMER3_BASE->PSC = 0; TIMER3_BASE->CNT = 0;
  TIMER3_BASE->CCR1 = 0; TIMER3_BASE->CCR2 = 0; TIMER3_BASE->CCR3 = 0;
  TIMER3_BASE->CCR4 = 0; TIMER3_BASE->PSC = 0; TIMER3_BASE->SR = 0; TIMER3_BASE->CR2 = 0;
  TIMER3_BASE->CCMR1 = 0;
  TIMER3_BASE->SMCR = (1 << 2) | (1 << 1) | (1 << 0) | (1 << 4); //SMS:111 && TS:001  такт брать от 2-го таймера
  TIMER3_BASE->ARR = 65535; //считать до
  TIMER3_BASE->EGR = 1; //перечитать регистры.
  TIMER3_BASE->CR1 |= (1 << 0); //start timer3
  /// настройка времени разрешения на таймере1 для таймера2
  TIMER1_BASE->CR1 = (1 << 3) | (1 << 2); //один импульс, без прерываний
  TIMER1_BASE->CNT = 0;
  TIMER1_BASE->CR2 = (1 << 4); //MMS:001 сигнал разрешения работы другим таймерам
  TIMER1_BASE->CCER = 0; // отключить выходы таймера на физ ноги
  TIMER1_BASE->PSC = F_CPU / 36000 - 1; // 1999; // 72000000/2000= 36000кГц тактовая таймера
  TIMER1_BASE->ARR = 36000; //считать до 36000 (1секунда)
  TIMER1_BASE->EGR = 1; //перечитать регистры.
  TIMER1_BASE->CR1 |= (1 << 0);
  __asm volatile( "cpsie i" );
  while (TIMER1_BASE->CR1 & 1) {
    asm volatile("nop");
    if (mon_flag) {
      return;
    }
  }
  freq = TIMER3_BASE->CNT << 16  | TIMER2_BASE->CNT ;
}

6

Re: Частотомер

Тоже самое

7

Re: Частотомер

A15 - вход

8

Re: Частотомер

Спасибо
работает.