Operácie

Meranie dĺžky impulzu

Z SensorWiki

Ú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í...