Rp2040 прерывание по таймеру

Есть плата RP2040 Zero. Надо выводить информацию на экран по прерыванию по таймеру каждые 5 секунд. Выводится должно значение переменной t1 в микросекундах. Нашел библиотеку подключил ее, но не понимаю пример ее использования п.п. 1.2.
Ссылка на библиотеку:

Сам код программы:


//--RP2040 zero 1602 Led
#include "RPi_Pico_TimerInterrupt.h"   //1.0   //https://github.com/khoih-prog/RPI_PICO_TimerInterrupt
//----------------------------------
RPI_PICO_Timer ITimer1(1); //1.1
//----------------------------------
// interval (in us), callback is ISR
bool setInterval(unsigned long interval, pico_timer_callback callback); //1.2
//----------------------------------
void TimerHandler()
{
  // Doing something here inside ISR
}
#define TIMER_INTERVAL_MS        5000L
//----------------------------------
// Init RPI_PICO_Timer
RPI_PICO_Timer ITimer(0);
//----------------------------------
#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);//Выводы индикатора (RS,E,D4,D5,D6,D7);
unsigned long t1;
//----------------------------------------------
void setup()
{lcd.begin(16, 2);}
//----------------------------------------------
void loop()
{
   t1=micros();
  {lcd.clear();lcd.setCursor(2, 0);lcd.print(t1); }
  delay(500);
}
//----------------------------------------------

у @dts есть библиотека аналогичная этой и он тут присутствует

Выводить информацию на экран из прерывания это фундаментально неправильное программирование.

1 лайк

Выводить информацию из прерывания это только для проверки правильности работы. На самом деле необходимо считывать информацию с аналогового входа с равными интервалами времени с частотой около 100 кгц. Типа частота квантования у осциллографа.

Обычно это делается не непосредственно в прерывании, а через DMA. А прерывания - только по заполнению буфера.
Другими словами, у Вас изначально неверная структура программы.
Это, если ориентироваться на описание.
А если заглянуть в текст программы, можно обнаружить, что он не соответствует описанию.

В ацп есть свой таймер, задающий частоту семплов.

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

Выкладываю полностью работоспособную программу для платы Arduino UNO. Главная проблема у меня, что в 72 строке слишком сложное выражение преобразования входного сопротивления на аналоговых входах в частоту. Поэтому процессор не справляется и пришлось сделать частоту опроса аналогового таймера 5 кгц. У платы RP2040 вроде с этим должно быть лучше и можно будет поднять частоту. Поэтому у меня вопрос по строке 63 с вызовом таймера для того чтобы поднять эту частоту.

//------------------------------------------------------------------------------------------------------
#include "CyberLib.h"                                                                         
//------------------------------------------------------------------------------------------------------
#include <LiquidCrystal.h>                                                                              
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);                                                                    
//---Входные переменные---------------------------------------------------------------------------------
long   Peak            =   42000 ;        
float  Alfa            =     1.0 ;        
int    R_bat           =    4000 ;                                 
int    F_ind           =       1 ;                           
int    as              =       1 ;                        
unsigned long F_gen    =16000000 ;        //Частота кварцевого генератора Гц                            
bool   Lcd_signal      =       1 ;                                   
//------------------------------------------------------------------------------------------------------
unsigned long Timeout;                                               
boolean       signal_out,signal_out_old;                   
boolean       sig_Lcd,sig_MA;                                                                           
int           R_in[100],n_r=100;                        
int           R_int;                                                             
int           n_int=50;           
int           k_n_plus[30],k_n_minus[30],n_as=30;  
int           n_out=10;              
int           temp_analog_in;                       
int           U_bat_analog_in;                           
int           value_in;                                           
int           i,in;                                         
int           n,n_plus,n_minus;                                                                         
int           R_home,R_min,U_out;                                                                       
unsigned int  ovf_tic_timer_1,ovf_tic_timer_1_int;                                                      
long          signal_sum;                                                                               
unsigned long times,times1;                                                                             
unsigned long tik_timer_1,sum_n_plus,sum_n_minus,out_plus,out_minus,sum_R_in;                           
float         sr_sum_n_plus,sr_sum_n_minus,y,U_bat;                                                     
float         k_sr[10],k_assm,sum_k_asmm,sr_sum,sr_sum_R_in,Speed_fast,sr_sum_old,Delta_r,Delta_r_max;  
//------------------------------------------------------------------------------------------------------
void setup()  {                                                                                         
//------------------------------------------------------------------------------------------------------
D8_Out;                                                                
D12_Out;                                                               
D13_Out;                                                                
signal_out=0;                                                                                           
//------------------------------------------------------------------------------------------------------
analogReference(DEFAULT);                                                   
ADCSRA |= ((1 << ADPS2)|(1 << ADPS1));               
ADCSRA &= ~ (1 << ADPS0);                                                               
//------------------------------------------------------------------------------------------------------
lcd.begin(20, 4);                                                         
lcd.clear();                                                                          
//---Определяем напряжение питания батареи--------------------------------------------------------------
U_bat_analog_in=analogRead(1);                                                                          
U_bat=(U_bat_analog_in*2*5.0)/1024;                                                                     
D13_Low ;delay(800);D13_High;delay(200);D13_Low ;delay(800);D13_High;delay(200);D13_Low ;delay(800);    
lcd.clear();                                                                          
//---Настройка таймера 1--------------------------------------------------------------------------------
TCCR1A  = 0;TCCR1B = 0;TCNT1  = 0;                                                                      
TCCR1B  = (1<<WGM12);                                                 
TCCR1B |= (1<<CS10);                                                             
OCR1A=3199;                                          
TIMSK1 |= (1 << OCIE1A);                                         
//------------------------------------------------------------------------------------------------------
}                                                                                                       
//---Начало прерывания по таймеру 1---------------------------------------------------------------------
ISR (TIMER1_COMPA_vect){                                                                                
ovf_tic_timer_1_int=ovf_tic_timer_1_int+1;                   
n=n+1;sig_MA=0;R_int=R_int+1;                                                                           
//------------------------------------------------------------------------------------------------------
temp_analog_in=analogRead(0);                                                                           
if (signal_out==0) value_in =      temp_analog_in;                                                      
if (signal_out==1) value_in = 1023-as-temp_analog_in;                                                   
in=value_in;                                                                                            
//---преобразование входное сопротивление в частоту-----------------------------------------------------
y=value_in/(-0.010007335*value_in+10.23);                                                               
value_in=(int)y;                                                                                        
if (value_in>=1000) value_in=1000;                                                                      
if (value_in<=10  ) value_in=10  ;                                                                      
//------------------------------------------------------------------------------------------------------
if (signal_out==0) signal_sum=(long)signal_sum+value_in;                                                
if (signal_out==1) signal_sum=(long)signal_sum-value_in;                                                
//------------------------------------------------------------------------------------------------------
if (signal_sum>= Peak) signal_out=1;                                                                    
if (signal_sum<=-Peak) signal_out=0;                                                                    
//------------------------------------------------------------------------------------------------------
if (signal_out_old==0 && signal_out==1) { n_plus=n;n=0;sig_MA=1;}                                       
if (signal_out_old==1 && signal_out==0) {n_minus=n;n=0;sig_MA=1;}                                       
//------------------------------------------------------------------------------------------------------
if (signal_out==0) {D8_High;D12_Low ;D13_Low ;}                                                         
if (signal_out==1) {D8_Low ;D12_High;D13_High;}                                                         
//---Условия заполнения массива данными значениями входного сопротивления-------------------------------
if (R_int>=n_int)                                                                                       
  {                                                                                                     
   R_in[0]=in;                                                                                          
   sum_R_in=0;R_int=0;                                                                                  
   for (i=(n_r-2);i>=0;i=i-1) {R_in[i+1]=R_in[i];}                                                      
   for (i=(n_r-1);i>=0;i=i-1) {sum_R_in =sum_R_in +R_in[i] ;}                                           
  }                                                                                                     
//------------------------------------------------------------------------------------------------------
if (sig_MA==1) {                                                                                        
//---Условия заполнения массива данными-----------------------------------------------------------------
for (i=(n_as-2);i>=0;i=i-1) {k_n_plus [i+1]=k_n_plus[i];k_n_minus[i+1]=k_n_minus[i];}                   
k_n_plus [0]=n_plus;k_n_minus[0]=n_minus;                                                               
//------------------------------------------------------------------------------------------------------
sum_n_plus=0;sum_n_minus=0;                                                                             
for (i=(n_as-1);i>=0;i=i-1) {sum_n_plus=sum_n_plus+k_n_plus[i];sum_n_minus=sum_n_minus+k_n_minus[i];}   
//------------------------------------------------------------------------------------------------------
}                                                                                                       
signal_out_old=signal_out;                                                                              
}                                                                                                       
//---Конец прерывания по таймеру 1----------------------------------------------------------------------
void loop()                                                                                             
{                                                                                                       
//------------------------------------------------------------------------------------------------------
ovf_tic_timer_1=ovf_tic_timer_1_int; tik_timer_1=(unsigned long)ovf_tic_timer_1*4000+TCNT1;//См OCR1A+1 
//---
if (tik_timer_1>=(F_gen/F_ind)) sig_Lcd=1;                                                              
//------------------------------------------------------------------------------------------------------
if (sig_Lcd==1)                                          
{                                                                                                       
U_bat_analog_in=analogRead(1);                                                                          
U_bat=(U_bat_analog_in*2*5.0)/1024;                                                                     
//------------------------------------------------------------------------------------------------------
sr_sum_R_in=sum_R_in /(n_r*1.0);                                                                        
if (sr_sum_R_in>=921.8) sr_sum_R_in=921.8;                                                              
if (sr_sum_R_in<=92.1) sr_sum_R_in=92.1;                                                                
R_home=(int)round(sr_sum_R_in/(-0.011013288*sr_sum_R_in+10.24));                                        
if (R_home>=9999) R_home=9999;                                                                          
if (R_home<=10  ) R_home=10  ;                                                                          
if (R_home<R_min) R_min=R_home;                                                                         
if (R_home>=R_bat) R_min=R_home;                                                                        
//------------------------------------------------------------------------------------------------------
out_plus=sum_n_plus;out_minus=sum_n_minus;                                                              
sr_sum_n_plus =out_plus /(n_as*1.0);                                                                    
sr_sum_n_minus=out_minus/(n_as*1.0);                                                                    
k_assm=(float)(100.0*2*(sr_sum_n_plus-sr_sum_n_minus))/(sr_sum_n_plus+sr_sum_n_minus);                  
//---Условия заполнения массива данными-----------------------------------------------------------------
for (i = (n_out-2); i >= 0; i = i - 1) {k_sr[i+1]=k_sr[i] ;}                                            
k_sr[0]=k_assm   ;                                                                                      
//------------------------------------------------------------------------------------------------------
sum_k_asmm=0.0;                                                                                         
for (i = (n_out-1); i >= 0; i = i - 1) {sum_k_asmm=sum_k_asmm+k_sr[i];}                                 
sr_sum=sum_k_asmm/(n_out*1.0);                                                                          
//------------------------------------------------------------------------------------------------------
sr_sum=abs(sr_sum);                                                                                     
if (sr_sum>99.99) sr_sum=99.99;                                                                         
sr_sum=(round(sr_sum*100.0))/100.0;                                                                     
//--блок ограничения скорости 
Speed_fast=(Alfa/F_ind)*1.0;                                                                            
if (sr_sum>(sr_sum_old+Speed_fast)               ) sr_sum=sr_sum_old+Speed_fast;                        
if (sr_sum<(sr_sum_old-Speed_fast)&& R_home<R_bat) sr_sum=sr_sum_old-Speed_fast;                        
sr_sum_old=sr_sum;                                                                                      
//------------------------------------------------------------------------------------------------------
Delta_r=sr_sum;                                                                                         
if (Delta_r>Delta_r_max) Delta_r_max=Delta_r;                                                           
if (Delta_r<5.0 && R_home>=R_bat) Delta_r_max=Delta_r;                                                  
//---
if (R_home>=R_bat                                   ) Timeout=millis();                                 
//---Начало вывода на LCD экран-------------------------------------------------------------------------
if (Lcd_signal==1) { 
lcd.clear();                                             //Очистка экрана                               
lcd.setCursor(0, 0);                                                                                    
//---
lcd.print(" R= ");                                                                                      
if (                  R_home<  10.0) lcd.print("   ");                                                  
if (R_home>=  10.0 && R_home< 100.0) lcd.print("  " );                                                  
if (R_home>= 100.0 && R_home<1000.0) lcd.print(" "  );                                                  
lcd.print(R_home);lcd.print("K");                                                                       
//---
lcd.print(" min= ");                                                                                    
if (                  R_min <  10.0) lcd.print("   ");                                                  
if (R_min >=  10.0 && R_min < 100.0) lcd.print("  " );                                                  
if (R_min >= 100.0 && R_min <1000.0) lcd.print(" "  );                                                  
lcd.print(R_min);lcd.print("K");                                                                        
lcd.setCursor(0, 1);                                                                                    
//------------------------------------------------------------------------------------------------------
lcd.print("dR=");                                                                                       
if (                  Delta_r    <10.00) lcd.print(" ");                                                
lcd.print(Delta_r,2);lcd.print("%");                                                                    
//------------------------------------------------------------------------------------------------------
lcd.print(" max=");                                                                                     
if (                  Delta_r_max<10.00) lcd.print(" ");                                                
lcd.print(Delta_r_max,2);lcd.print("%");                                                                
};                                     //Конец блока вывода на LCD экран                                
//---
times1=millis()-Timeout;                                                                                
lcd.setCursor(0, 3);                                                                                    
lcd.print(" T= ");                                                                                      
if (times1>=    0 && times1< 10000) { lcd.print("  "); }                                                
if (times1>=10000 && times1<100000) { lcd.print(" "); }                                                 
lcd.print (times1/1000);lcd.print(" S");                                                                
//---вывод времени работы прибора-----------------------------------------------------------------------
lcd.setCursor(12, 3);                                                                                   
times=millis()/1000;                                                                                    
if (times/60/60<10) { lcd.print("0"); }                                                                 
lcd.print (times/60/60);                                                                                
lcd.print (":");                                                                                        
if (times/60%60<10) { lcd.print ("0"); }                                                                
lcd.print ((times/60)%60);                                                                              
lcd.print (":");                                                                                        
if (times%60<10) { lcd.print ("0"); }                                                                   
lcd.print (times%60);                                                                                   
//---вывод напряжения питания---------------------------------------------------------------------------
if (U_bat>5.2 && U_bat<7.5){lcd.setCursor(0,2);lcd.print("Low Bat  U_bat=");lcd.print (U_bat,1);lcd.print("B");}
//---Конец вывода на LCD экран--------------------------------------------------------------------------
sig_Lcd=0;                                                                                              
ovf_tic_timer_1_int=0;tik_timer_1=0;                                                                    
}                                                                                                       
//------------------------------------------------------------------------------------------------------
}                                                                                                       
//------------------------------------------------------------------------------------------------------

Всем спасибо. Вопрос решен. Теперь прерывание по таймеру работает. Частоту таймера пробовал менять от 0.5 Гц до 500 кГц. На индикатор выводил частоту не более 2 Гц. Остановился на частоте опроса АЦП в 100 кГц. Полученный код для проверки работы таймера выкладываю.

#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);//Выводы индикатора (RS,E,D4,D5,D6,D7)
uint a1,a4=0; uint32_t a2;
//---------------------------------------------------------
void button_callback (uint gpio, uint32_t events) 
{a1=gpio;a2=events;a4=a4+1;}
//---------------------------------------------------------
int main() 
{
  lcd.begin(16, 2);
  long t1=0,t2=0,t3=0;
  //---------------------
  gpio_init(0);
  gpio_set_dir(0, GPIO_IN);
  gpio_pull_up(0);
  gpio_set_irq_enabled_with_callback(0, GPIO_IRQ_EDGE_RISE, 1, button_callback);
  //---------------------
  while (true) 
  {
   t2=micros();
   t3=t2-t1;
   if (t3>1000000)
    {
     lcd.clear();
     lcd.setCursor(9, 0);lcd.print(t1);
     lcd.setCursor(9, 1);lcd.print(t2);
     lcd.setCursor(9, 2);lcd.print(t3);
     a4=0;t1=0;t2=0;t3=0; t1=micros();
     }
  }
}

И где это в коде?

gpio_set_irq_enabled_with_callback(0, GPIO_IRQ_EDGE_RISE, 1, button_callback);

Мошт это?)

Может это, а может нет? Вам гуру от программирования виднее. Я же только начинаю программировать и делаю первые шаги.

С такими «познаниями» заявлять

Тупо, Вы не считаете так разве?

Я так не считаю. Прерывание по таймеру у меня работает. Я об этом и написал. А про тупо или остро это думайте как хотите сами.

Принял к сведению.