Operácie

Meranie dĺžky impulzu: Rozdiel medzi revíziami

Z SensorWiki

(Literatúra)
 
(6 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 1: Riadok 1:
=== Literatúra ===
 
  
* [http://www.atmel.com/dyn/resources/prod_documents/doc2505.pdf AVR130: Setup and Use the AVR® Timers.] Aplication Note, Atmel Corporation 2002.<BR> + [http://www.atmel.com/dyn/resources/prod_documents/AVR130.zip software download]
+
=== Úloha ===
* [http://www.atmel.com/dyn/resources/prod_documents/doc8014.pdf AVR135: Using Timer Capture to Measure PWM Duty Cycle.] Aplication Note, Atmel Corporation 2005.<BR> + [http://www.atmel.com/dyn/resources/prod_documents/AVR135.zip software download]
+
 
 +
# Vytvoriť simulátor PWM signálu snímača teploty:  SMT 160-30, resp. SMT 172
 +
#* TC0  bude na pine PD5 generovať PWM signál s 𝑓_𝑃𝑊𝑀=1𝑘𝐻𝑧 a plnením v intervale DC = (0,1 až 0,9). 
 +
#* DC budeme zadávať v %.
 +
# Na meranie parametrov PWM signálu: T1 - čas v log. 1 a T_opak – trvanie jednej periódy PWM signálu použijeme TC1 (16b). TC1 nastavíme do módu „odpamätanie“ stavu počítadla pri výskyte hrany na pine PB.0. Využijeme ISR().
 +
# Pomocou TC2, bude generovať presnú periodu vzorkovania. Periódu opakovania výpisov, ako aj zmeny plnenia o definovaný prírastok, napr. 1, budeme realizovať s krokom 0,5sek. Využijeme ISR().
 +
# Výpisy na LCD, resp. terminál treba realizovať vo formáte, xx,x. (Pevná rádova čiarka). Pri výpočtoch nemôže byť použitá float aritmetika.
 +
# Vo výpisoch sa musí objaviť: Nastavené plnenie. Trvanie T_1, resp. T_opak v SC a us. Ako aj plnenie v  % vo formáte: xx,x. Rovnako aj danému plneniu odpovedajúca teplota vo formáte +-xx,x °C .
 +
# Ako úloha naviac: Navrhnite filter typu kĺzavý priemer z 8-ich vzoriek.
 +
 
 +
<FONT Color="blue" Size="+1">
 +
[http://senzor.robotika.sk/mmp/cvicenie10.pdf Slajdy k teoretickému rozboru cvičenia]
 +
</font>
 +
 
 +
 
 +
<tabs>
 +
<tab name="main.c"><source lang="c++" style="background: LightYellow;">
 +
//Hlavný program
 +
#include <avr/io.h>                           
 +
#include <avr/interrupt.h>                     
 +
 
 +
 
 +
#include "p_f_1.h"
 +
#include "p_f_2.h"
 +
// deklarovanie premenných
 +
 
 +
int main(void){
 +
  /* Ini PORT‘s, TCx, prerušení
 +
    Konfiguracia UART:Tx, Rx */
 +
  ini_usart_0(MYUBRR);
 +
  ini_TC0(); ini_TC1(); ini_TC2();
 +
  sei();                                // Enable interrupts in general
 +
 
 +
  sprintf(Riadok,"Meranie plnenia impulzu \r\n" );
 +
  zob_text_UART(Riadok);
 +
  /* main loop */   
 +
  while (1) {
 +
    if(flag_Vypisov){  
 +
flag_Vypisov = 0;
 +
Vypis();
 +
Zmena_plnenia(); // DC = (10 az 90 %)
 +
}
 +
  }
 +
}
 +
</source></tab>
 +
<tab name="p_f_1.h"><source lang="c++" style="background: LightYellow;">
 +
// ********************************* p_f_1.h
 +
/*
 +
* p_f_1.h
 +
*/  
 +
 
 +
 
 +
#ifndef P_F_1_H_
 +
#define P_F_1_H_
 +
 
 +
#define F_CPU 16000000UL /* Define CPU frequency here 16MHz */
 +
#include <avr/io.h>
 +
#include <util/delay.h>
 +
#include <avr/interrupt.h>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
 
 +
 
 +
 
 +
void zob_text_UART(char *);
 +
void ini_usart_0(unsigned int );
 +
void USART_Transmit( unsigned char );
 +
 
 +
void zob_text(char *);
 +
 
 +
void Zmena_plnenia(void);
 +
unsigned char Prepocet_plnenia_PWM(unsigned char );
 +
void Vypis(void);
 +
 
 +
extern char Riadok[];
 +
 
 +
extern volatile unsigned int T1_no_vz;
 +
extern volatile unsigned int T1_st_vz;
 +
 
 +
extern volatile unsigned int pl_PWM_pocitane_Percent;
 +
extern volatile unsigned long T_log_1;
 +
extern volatile unsigned long T_log_1_us;
 +
extern volatile long  T_opak;
 +
 
 +
extern volatile int T_M;
 +
 +
extern unsigned char DC_PWM_percent;
 +
 
 +
extern uint8_t T_vypis; // cca 0,5 sek  , potom doladim   
 +
 
 +
 
 +
#define BAUD 115200
 +
 +
//UCSR0A.U2X0 = 1
 +
 
 +
#define MYUBRR
 +
 
 +
#endif /* P_F_1_H_ */
 +
 
 +
 
 +
</source></tab>
 +
<tab name="p_f_1.c"><source lang="c++" style="background: LightYellow;">
 +
 
 +
// ********************************* p_f_1.c
 +
/*
 +
* p_f_1.c
 +
*/
 +
 
 +
#include "p_f_1.h"
 +
#include "p_f_2.h"
 +
 
 +
// Inicializacia UARTu
 +
void ini_usart_0(unsigned int mybr){
 +
UBRR0 = mybr;
 +
...
 +
}
 +
 
 +
 
 +
void zob_text_UART(char *s){
 +
register unsigned char c;
 +
while((c = *s++)) USART_Transmit(c); // retazec konci "nulou"
 +
}
 +
 
 +
void USART_Transmit( unsigned char data ){
 +
/* Wait for empty transmit buffer */
 +
while ( !( UCSR0A & (1<<UDRE0)) );
 +
/* Put data into buffer, sends the data */
 +
UDR0 = data;
 +
}
 +
 
 +
void Vypis(void){
 +
// formátovaný výpis
 +
//printf("Plnenie:?????? ", DC_PWM_percent, T_log_1, T_opak  );
 +
Výpis:Plnenie: dd%, ddd [SC], ddd [SC]
 +
Výpis:Plnenie: dd%, ddd [us], ddd [us]  
 +
 
 +
printf("Plnenie:?????? ", DC_PWM_percent, pl_PWM_pocitane_Percent );
 +
Výpis:Plnenie: dd%, dd,d% 
 +
 
 +
zob_text_UART(Riadok);
 +
}
 +
 
 +
 
 +
void Zmena_plnenia(void){ // rozsah 10 az 90 %
 +
DC_PWM_percent+=?;
 +
if (DC_PWM_percent >90)DC_PWM_percent = 10;
 +
// prepocitam rozsah v percentach na odpovedajuce cislo
 +
  if (DC_PWM_Percent > 90) DC_PWM_Percent = 10;
 +
OCR0B = f(DC_PWM_Percent);
 +
}
 +
 
 +
unsigned char Prepocet_plnenia_PWM(unsigned char pln_per){
 +
...
 +
}
 +
 
 +
</source></tab>
 +
<tab name="p_f_2.h"><source lang="c++" style="background: LightYellow;">
 +
 
 +
 
 +
// ********************************* p_f_2.h
 +
/*
 +
* p_f_2.h
 +
*/
 +
 
 +
#ifndef P_F_2_H_
 +
#define P_F_2_H_
 +
 
 +
#define set_bit(Adress,Bit) (Adress |= (1<<Bit))
 +
#define clear_bit(Adress,Bit) (Adress &= ~(1<<Bit))
 +
#define toggle_bit(Adress,Bit) (Adress ^= (1<<Bit))
 +
 
 +
extern volatile unsigned char poc_T_vypis ;
 +
extern volatile unsigned char flag_Vypisov ;
 +
 
 +
#define f_opak_TC0 1000 // 1000 Hz <-> 1ms
 +
#define N_D_TC0 // Delic pre TC0
 +
#define OCR0A_f_opak_TC0 // Vysledkom je perioda opakovania 1ms !!!!!
 +
 
  
 +
#define f_opak_TC2 500 // 500 Hz -> 2ms
 +
#define N_D_TC2 // Delic pre TC2
 +
#define OCR2A_f_opak_TC2 // Vysledkom je 2ms casova vzorka !!!!!
 +
#define T__050 250 // 0,5 sek = 250 * 2ms
  
 +
void ini_TC0(void);
 +
void ini_TC1(void);
 +
void ini_TC2(void);
  
'''Príklad ([[Médiá:avrdemo7.hex|avrdemo7.hex]])'''
+
#endif /* P_F_2_H_ */
  
Na vstupe ICP1 (na doske Acrob D8, na čipe ATmega328P je to PB0, pin 14) máme pripojený [[555|zdroj externého kmitočtu]] cca 1Hz:
+
</source></tab>
 +
<tab name="p_f_2.c"><source lang="c++" style="background: LightYellow;">
 +
// ********************************* p_f_2.c
 +
/*
 +
* p_f_2.c
 +
*
 +
* Created: 4/12/2021 11:29:22 AM
 +
*  Author: Admin
 +
*/
  
[[Obrázok:Oscillogram7.png|center]]
+
#include <avr/io.h>
 +
#include "p_f_1.h"
 +
#include "p_f_2.h"
  
Nastavené máme spúšťanie ICR dobežnou hranou, počítadlo počíta 16 MHz:1024, vypisujeme  niekoľkokrát za sekundu stavy všetkých registrov
 
<source linenumbers lang="c">
 
Input D8 = 1  TCNT1 =  353  ICR =    0
 
Input D8 = 1  TCNT1 =  1543  ICR =    0
 
Input D8 = 1  TCNT1 =  2749  ICR =    0
 
Input D8 = 1  TCNT1 =  3956  ICR =    0
 
Input D8 = 1  TCNT1 =  5163  ICR =    0
 
Input D8 = 0  TCNT1 =  6369  ICR =  6070  D = 6070  T = 388.4800 ms
 
Input D8 = 0  TCNT1 =  7706  ICR =  6070 
 
Input D8 = 0  TCNT1 =  8961  ICR =  6070 
 
Input D8 = 0  TCNT1 = 10216  ICR =  6070 
 
Input D8 = 0  TCNT1 = 11488  ICR =  6070 
 
Input D8 = 0  TCNT1 = 12759  ICR =  6070 
 
Input D8 = 1  TCNT1 = 14031  ICR =  6070 
 
Input D8 = 1  TCNT1 = 15303  ICR =  6070 
 
Input D8 = 1  TCNT1 = 16574  ICR =  6070 
 
Input D8 = 1  TCNT1 = 17846  ICR =  6070 
 
Input D8 = 1  TCNT1 = 19117  ICR =  6070 
 
Input D8 = 1  TCNT1 = 20389  ICR =  6070 
 
Input D8 = 1  TCNT1 = 21661  ICR = 21591  D = 15521  T = 993.3441 ms
 
Input D8 = 0  TCNT1 = 23046  ICR = 21591 
 
Input D8 = 0  TCNT1 = 24334  ICR = 21591 
 
Input D8 = 0  TCNT1 = 25622  ICR = 21591 
 
Input D8 = 0  TCNT1 = 26910  ICR = 21591 
 
Input D8 = 0  TCNT1 = 28197  ICR = 21591 
 
Input D8 = 1  TCNT1 = 29485  ICR = 21591 
 
Input D8 = 1  TCNT1 = 30773  ICR = 21591 
 
Input D8 = 1  TCNT1 = 32061  ICR = 21591 
 
Input D8 = 1  TCNT1 = 33349  ICR = 21591 
 
Input D8 = 1  TCNT1 = 34636  ICR = 21591 
 
Input D8 = 1  TCNT1 = 35924  ICR = 21591 
 
Input D8 = 1  TCNT1 = 37212  ICR = 37110  D = 15519  T = 993.2161 ms
 
Input D8 = 0  TCNT1 = 38597  ICR = 37110 
 
Input D8 = 0  TCNT1 = 39885  ICR = 37110 
 
Input D8 = 0  TCNT1 = 41173  ICR = 37110 
 
Input D8 = 0  TCNT1 = 42461  ICR = 37110 
 
Input D8 = 0  TCNT1 = 43749  ICR = 37110 
 
Input D8 = 1  TCNT1 = 45037  ICR = 37110 
 
Input D8 = 1  TCNT1 = 46324  ICR = 37110 
 
Input D8 = 1  TCNT1 = 47612  ICR = 37110 
 
Input D8 = 1  TCNT1 = 48900  ICR = 37110 
 
Input D8 = 1  TCNT1 = 50188  ICR = 37110 
 
Input D8 = 1  TCNT1 = 51476  ICR = 37110 
 
Input D8 = 1  TCNT1 = 52763  ICR = 52630  D = 15520  T = 993.2800
 
Input D8 = 0  TCNT1 = 54149  ICR = 52630 
 
Input D8 = 0  TCNT1 = 55437  ICR = 52630 
 
Input D8 = 0  TCNT1 = 56724  ICR = 52630 
 
Input D8 = 0  TCNT1 = 58012  ICR = 52630 
 
Input D8 = 0  TCNT1 = 59300  ICR = 52630 
 
Input D8 = 1  TCNT1 = 60588  ICR = 52630 
 
Input D8 = 1  TCNT1 = 61876  ICR = 52630 
 
Input D8 = 1  TCNT1 = 63163  ICR = 52630 
 
Input D8 = 1  TCNT1 = 64451  ICR = 52630 
 
Input D8 = 1  TCNT1 =  203  ICR = 52630 
 
Input D8 = 1  TCNT1 =  1458  ICR = 52630 
 
Input D8 = 1  TCNT1 =  2730  ICR =  2619  D = 15525  T = 993.6000
 
Input D8 = 0  TCNT1 =  4083  ICR =  2619 
 
</source>
 
  
Ak chceme merať aj striedu, musíme meranie realizovať s prerušením a v obsluhe prerušenia preklopiť konfiguračný bit, ktorý rozhoduje o prepise
+
void ini_TC0(void){
TCNT do ICR registra. Je to bit ICES1, ktorý je v TCCR1B.6.
+
//  Nastavenie TC0
 +
set_bit(DDRD,PIND5); //OC0B PWM pin
 +
// 7 6        5 4        3      2    1 0
 +
// COM0A[1:0]  COM0B[1:0]              WGM0[1:0]
 +
TCCR0A = ??????;// OC0B  PWM mod = ?
 +
// 7 6 5 4  3      2  1  0
 +
//          WGM02  CS0[2:0]
 +
TCCR0B = ??????;// fosc/??
 +
OCR0B = 𝑓("DC_PWM_percent " );
 +
// nastvenie  frekvencie opakovania na 1ms
 +
OCR0A = OCR0A_f_opak_TC0;
  
<source lang="c">
+
}
#include <avr/interrupt.h> 
 
  
volatile int newTick = 0;  // The variable for interrupt should be declared as a volatile one!
 
                 
 
ISR(TIMER1_CAPT_vect)      // Timer 1 Capture Interrupt Service Routine
 
{
 
  TCCR1B = ??              // toggle Edge Select bit
 
  newTick = ICR1;
 
};
 
  
main()
+
void ini_TC1(void){
{
+
// Timer1 Capture
 +
DDRB &= ~(1<<DDB0);  //ICP1 = PORTB.0, input
 +
PORTB |= (1<<PORTB0); // Pullup Rezistor
 +
//  Nastavenie TC1
 +
// 7 6 5 4  3      2  1  0
 +
//          WGM12  CS1[2:0]
 +
// fTC1 = f(fosc) chceme max. presnosť merania
 +
TCCR1B ?= ????;
 +
TCCR1B ?= ????; // odchytenie na nabeznu hranu
  
  DDRB = ??                // Set ICR - Port B, pin0 as INPUT
+
  TIMSK1 ?= ????; // povolenie prerusenia od capture T1
TCCR1B = ??                // T1 clk = F_CPU : 1024, falling edge pin ICP1,
+
  // sei(); pre všetky naraz
TCCR1A = ??               // T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !!
 
  TCNT1 = 0x0000;          // initialize the counter (16-bit! Low+High bytes)
 
  TIFR1 = ??               // (1<<ICF1);   if a 1 is written to a ICF1 bit
 
                            //             - the ICF1 bit will be cleared
 
                     
 
  TIMSK1 = ??                // Enable ICR interrupt
 
  sei();                   // Enable ALL interrupts                     
 
  
  ....                      // TODO: display measured value somewhere
 
 
 
 
}
 
}
</source>
 
  
 +
void ini_TC2(void){
 +
//  Nastavenie TC2
 +
// 7 6        5 4        3      2    1 0
 +
// COM2A[1:0]  COM2B[1:0]              WGM2[1:0]
 +
TCCR2A ? = ????;// OC2B  PWM mod = 7
 +
// 7 6 5 4  3      2  1  0
 +
//          WGM02  CS0[2:0]
 +
TCCR2B ?= ????;// fosc/??
 +
 +
// nastavenie frekvencie opakovania na 2ms
 +
OCR2A ? = OCR2A_f_opak_TC2;
 +
// Enable interrupts @ overflow TC2 MOD 7
 +
TIMSK2 ? = ????;
 +
// sei(); pre všetky naraz
 +
 +
}
  
Ukážka pre Arduino využíva zabudovaný príkaz [http://arduino.cc/en/Reference/PulseIn PulseIn]:
+
ISR(TIMER2_OVF_vect)                         
<source lang="c">
+
{ /// tato slucka sa vykona kazde 2,0ms
#define SWITCH 8                // select the pin for Switch
+
    OCR2A = OCR2A_f_opak_TC2;
unsigned long duration;
+
//toggle_bit(PORTD,PIND2); //PD2 - change
 +
    poc_T_vypis--;
 +
if (!poc_T_vypis) {
 +
// prednastavim pocitadlo vypisov na 0,5s
 +
poc_T_vypis = T__050;
 +
flag_Vypisov = 1;// nastavim priznak vypisov
 +
//toggle_bit(PORTD,PIND2); //PD2 - change
 +
}
  
void setup()
 
{
 
pinMode(SWITCH, INPUT);        // this pin is an INPUT
 
Serial.begin(9600);
 
Serial.println("PulsIn test:");
 
 
}
 
}
  
void loop()                     // endless loop
+
ISR(TIMER1_CAPT_vect){
{
+
// globalne prerusenie je zakazane
  duration = pulseIn(SWITCH, HIGH);
+
// POCITADLO SA INKREMENTUJE KAZDU ?us
Serial.print(" T1 = ");
+
  if(TESTUJEM HRANU){// bola nábežna hrana
Serial.print(duration,DEC);
+
  ....; // tu prepnem na dobežnu hrana
  Serial.print(" [us]");
+
  T1_st_vz = T1_no_vz;  
 +
  T1_no_vz = ICR1; // odpamätám nový “čas“
 +
  T_opak = ... ;
 +
 
 +
  pl_PWM_pocitane_Percent = f(T_log_1,T_opak);
 +
  T_M = f( (T_log_1 ,T_opak);
 +
  }  else {// bola dobežna hrana
 +
    ....; // tu prepnem na nábežnu hrana
 +
   
 +
    T_log_1 = ICR1 - T1_no_vz; 
 +
    T_log_1_us =f(.....).
 +
}
  
duration = pulseIn(SWITCH, LOW);
 
Serial.print(" T0 = ");
 
Serial.print(duration,DEC);
 
Serial.println(" [us]");
 
 
}
 
}
</source>
+
</source></tab>
 +
</tabs>
 +
 
 +
=== Literatúra ===
 +
 
 +
* SMT 172 [http://senzor.robotika.sk/mmp/SMT172.pdf Temperature sensor Specification sheet]
 +
* SMT 160-30 [http://senzor.robotika.sk/mmp/SMT160.pdf Temperature sensor Specification sheet]
 +
* [http://ww1.microchip.com/downloads/en/AppNotes/Atmel-2505-Setup-and-Use-of-AVR-Timers_ApplicationNote_AVR130.pdf AVR130: Setup and Use the AVR® Timers.]  Aplication Note, Atmel Corporation 2002.<BR> + [http://www.atmel.com/dyn/resources/prod_documents/AVR130.zip software download]
 +
* [http://ww1.microchip.com/downloads/en/AppNotes/Atmel-8014-Using-Timer-Capture-to-Measure-PWM-Duty-Cycle_ApplicationNote_AVR135.pdf AVR135: Using Timer Capture to Measure PWM Duty Cycle.] Aplication Note, Atmel Corporation 2005.<BR> + [http://www.atmel.com/dyn/resources/prod_documents/AVR135.zip software download]
 +
* Pozn. pre autora: staršia verzia tohoto cvika je tu [[Meranie dĺžky impulzu 2]]
 +
 
 +
 
 +
 
  
  
 +
[[Mikropočítačové systémy (MIPS)#Cvičenia|Návrat na zoznam cvičení...]]
  
[[Category:AVR]][[Category:MMP]][[Category:DVPS]]
+
[[Category:AVR]][[Category:MMP]][[Category:MIPS]]

Aktuálna revízia z 14:26, 14. apríl 2021

Úloha

  1. Vytvoriť simulátor PWM signálu snímača teploty: SMT 160-30, resp. SMT 172
    • TC0 bude na pine PD5 generovať PWM signál s 𝑓_𝑃𝑊𝑀=1𝑘𝐻𝑧 a plnením v intervale DC = (0,1 až 0,9).
    • DC budeme zadávať v %.
  2. Na meranie parametrov PWM signálu: T1 - čas v log. 1 a T_opak – trvanie jednej periódy PWM signálu použijeme TC1 (16b). TC1 nastavíme do módu „odpamätanie“ stavu počítadla pri výskyte hrany na pine PB.0. Využijeme ISR().
  3. Pomocou TC2, bude generovať presnú periodu vzorkovania. Periódu opakovania výpisov, ako aj zmeny plnenia o definovaný prírastok, napr. 1, budeme realizovať s krokom 0,5sek. Využijeme ISR().
  4. Výpisy na LCD, resp. terminál treba realizovať vo formáte, xx,x. (Pevná rádova čiarka). Pri výpočtoch nemôže byť použitá float aritmetika.
  5. Vo výpisoch sa musí objaviť: Nastavené plnenie. Trvanie T_1, resp. T_opak v SC a us. Ako aj plnenie v  % vo formáte: xx,x. Rovnako aj danému plneniu odpovedajúca teplota vo formáte +-xx,x °C .
  6. Ako úloha naviac: Navrhnite filter typu kĺzavý priemer z 8-ich vzoriek.

Slajdy k teoretickému rozboru cvičenia


//Hlavný program
#include <avr/io.h>                             
#include <avr/interrupt.h>                      


#include "p_f_1.h"
#include "p_f_2.h"
// deklarovanie premenných

int main(void){ 
   /* Ini PORT‘s, TCx, prerušení
     Konfiguracia UART:Tx, Rx */
  ini_usart_0(MYUBRR);
  ini_TC0(); ini_TC1(); ini_TC2();
  sei();                                // Enable interrupts in general

  sprintf(Riadok,"Meranie plnenia impulzu \r\n" ); 	
  zob_text_UART(Riadok);	
  /* main loop */    
  while (1) {
     if(flag_Vypisov){  
		flag_Vypisov = 0;
		Vypis();
		Zmena_plnenia(); // DC = (10 az 90 %) 
	 }
  }
}
// ********************************* p_f_1.h
/*
 * p_f_1.h
 */ 


#ifndef P_F_1_H_
#define P_F_1_H_

#define F_CPU 16000000UL	/* Define CPU frequency here 16MHz */
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>



void zob_text_UART(char *);
void ini_usart_0(unsigned int );
void USART_Transmit( unsigned char );

void zob_text(char *);

void Zmena_plnenia(void);
unsigned char Prepocet_plnenia_PWM(unsigned char );
void Vypis(void);

extern char Riadok[];	

extern volatile unsigned int T1_no_vz;
extern volatile unsigned int T1_st_vz;

extern volatile unsigned int pl_PWM_pocitane_Percent;
extern volatile unsigned long T_log_1;
extern volatile unsigned long T_log_1_us;
extern volatile long  T_opak;

extern volatile int T_M;
 
extern unsigned char DC_PWM_percent;

extern uint8_t T_vypis; // cca 0,5 sek  , potom doladim    


#define BAUD 115200	
						
//UCSR0A.U2X0 = 1

#define MYUBRR 

#endif /* P_F_1_H_ */
// ********************************* p_f_1.c
/*
 * p_f_1.c
 */ 

#include "p_f_1.h"
#include "p_f_2.h"

// Inicializacia UARTu
void ini_usart_0(unsigned int mybr){
UBRR0 = mybr; 
...
}	


void zob_text_UART(char *s){
	register unsigned char c;
	while((c = *s++))	USART_Transmit(c); // retazec konci "nulou"
}

void USART_Transmit( unsigned char data ){
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}

void Vypis(void){
// formátovaný výpis
//printf("Plnenie:?????? ", DC_PWM_percent, T_log_1, T_opak  ); 
Výpis:Plnenie: dd%, ddd [SC], ddd [SC] 
Výpis:Plnenie: dd%, ddd [us], ddd [us]   

printf("Plnenie:?????? ", DC_PWM_percent, pl_PWM_pocitane_Percent ); 
Výpis:Plnenie: dd%, dd,d%   

zob_text_UART(Riadok);
}


void Zmena_plnenia(void){ // rozsah 10 az 90 % 
	 DC_PWM_percent+=?;
	 if (DC_PWM_percent >90)DC_PWM_percent = 10;
	 // prepocitam rozsah v percentach na odpovedajuce cislo
	  if (DC_PWM_Percent > 90) DC_PWM_Percent = 10;
	 OCR0B = f(DC_PWM_Percent);
}

unsigned char Prepocet_plnenia_PWM(unsigned char pln_per){
	...
}
// ********************************* p_f_2.h
/*
 * p_f_2.h
 */ 

#ifndef P_F_2_H_
#define P_F_2_H_

#define set_bit(Adress,Bit) (Adress |= (1<<Bit))
#define clear_bit(Adress,Bit) (Adress &= ~(1<<Bit))
#define toggle_bit(Adress,Bit) (Adress ^= (1<<Bit))

extern volatile unsigned char poc_T_vypis ; 
extern volatile unsigned char flag_Vypisov ;	

#define f_opak_TC0 1000		// 1000 Hz <-> 1ms
#define N_D_TC0 	// Delic pre TC0
#define OCR0A_f_opak_TC0 		// Vysledkom je perioda opakovania 1ms !!!!!


#define f_opak_TC2 500		// 500 Hz -> 2ms
#define N_D_TC2 			// Delic pre TC2
#define OCR2A_f_opak_TC2	// Vysledkom je 2ms casova vzorka !!!!!
#define T__050	250			// 0,5 sek = 250 * 2ms

void ini_TC0(void);
void ini_TC1(void);
void ini_TC2(void);

#endif /* P_F_2_H_ */
// ********************************* p_f_2.c
/*
 * p_f_2.c
 *
 * Created: 4/12/2021 11:29:22 AM
 *  Author: Admin
 */ 

#include <avr/io.h>
#include "p_f_1.h"
#include "p_f_2.h"


void ini_TC0(void){
	//  Nastavenie TC0
 set_bit(DDRD,PIND5); //OC0B PWM pin 
 // 7 6         5 4         3      2     1 0
 // COM0A[1:0]  COM0B[1:0]               WGM0[1:0]
 TCCR0A = ??????;// OC0B  PWM mod = ?
 // 7 6 5 4  3      2   1   0
 //          WGM02  CS0[2:0]
 TCCR0B = ??????;// fosc/??
 OCR0B = 𝑓("DC_PWM_percent " );
// nastvenie  frekvencie opakovania na 1ms
 OCR0A = OCR0A_f_opak_TC0; 

}


void ini_TC1(void){
		// Timer1 Capture
 DDRB &= ~(1<<DDB0);  	//ICP1 = PORTB.0, input
 PORTB |= (1<<PORTB0); // Pullup Rezistor
 //  Nastavenie TC1
 // 7 6 5 4  3      2   1   0
 //          WGM12  CS1[2:0]
 // fTC1 = f(fosc) chceme max. presnosť merania
 TCCR1B ?= ????;
 TCCR1B ?= ????; // odchytenie na nabeznu hranu 

 TIMSK1 ?= ????; // povolenie prerusenia od capture T1
 // sei(); pre všetky naraz

}

void ini_TC2(void){
	//  Nastavenie TC2
 // 7 6         5 4         3      2     1 0
 // COM2A[1:0]  COM2B[1:0]               WGM2[1:0]
 TCCR2A ? = ????;// OC2B  PWM mod = 7
 // 7 6 5 4  3      2   1   0
 //          WGM02  CS0[2:0]
 TCCR2B ?= ????;// fosc/??

 // nastavenie frekvencie opakovania na 2ms
 OCR2A ? = OCR2A_f_opak_TC2; 
 // Enable interrupts @ overflow TC2 MOD 7
 TIMSK2 ? = ????;
 // sei(); pre všetky naraz

}

ISR(TIMER2_OVF_vect)                           
{ /// tato slucka sa vykona kazde 2,0ms
    OCR2A = OCR2A_f_opak_TC2;
//toggle_bit(PORTD,PIND2); //PD2 - change 
    poc_T_vypis--;
if (!poc_T_vypis) {
// prednastavim pocitadlo vypisov na 0,5s
poc_T_vypis = T__050;
flag_Vypisov = 1;// nastavim priznak vypisov
//toggle_bit(PORTD,PIND2); //PD2 - change 
 }

}

ISR(TIMER1_CAPT_vect){
	// globalne prerusenie je zakazane
// POCITADLO SA INKREMENTUJE KAZDU ?us
 if(TESTUJEM HRANU){// bola nábežna hrana
   ....; // tu prepnem na dobežnu hrana
   T1_st_vz = T1_no_vz; 
   T1_no_vz = ICR1; // odpamätám nový “čas“
   T_opak = ... ;

   pl_PWM_pocitane_Percent = f(T_log_1,T_opak);
   T_M = f( (T_log_1 ,T_opak);
 }  else {// bola dobežna hrana
    ....; // tu prepnem na nábežnu hrana
    
    T_log_1 = ICR1 - T1_no_vz;  
    T_log_1_us =f(.....).
 }

}

Literatúra



Návrat na zoznam cvičení...