Sari la conținut
ELFORUM - Forumul electronistilor

ATMega16


Vizitator eyes_wide_open

Postări Recomandate

Vizitator eyes_wide_open

Salut, nu sunt cunoscatoare, scriu si eu din ce am prins, deci imi cer scuze in fata ofensatilor.La ultimele laboratoare ale unei discipline s-a lucrat cu ATMega16, un JTAG, AVR Studio, IAR Embedded Workbench si diferite instrumente Hameg.Ok, marturisesc ca la laborator nu am lucrat decat foarte putin deoarece profu` ne-a lasat in voia sortii si nici eu n-am prea aratat interes (da, stiu, astea-s scuze )si doresc ca in 2 nopti si o zi sa inteleg cat sa mi puna profu` un 5 vineri la colocviu. Din cate am inteles, astazi a fost printre subiecte ceva de genul : -> implementati un periodmetru ( durata de impuls 1 ) in gama 10-1000 msec. Numarul trebuie formatat si trimis pe seriala inb formatul xxxxms.Nici macar nu stiu cu ce sa incep ca sa invat. Am gasit pe net noaptea trecuta cateva exemple, destul de putine totusi.Help me please, somebody.. :jytuiyu

Link spre comentariu
  • Răspunsuri 12
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Laci

    4

  • mitescu

    3

  • ratza

    1

Top autori în acest subiect

Daca semnalul este dreptunghiular , ttl , si este conectat la pinul INT0 a lui ATmega16

Iar la USART ai legat un PC pe care ruleaza Hyperteminalul, la o comanda 'g', MC-ul va intoarce perioada masurata a semnalului.

#include <mega16.h>#define true 0#define false 1char      flag_int;char      flag_ms;unsigned int       perioada;unsigned int        temp;// External Interrupt 0 service routineinterrupt [EXT_INT0] void ext_int0_isr(void){ if(flag_ms==true)    {    flag_int=true;    temp=0;    } else     {    flag_int=false;    flag_ms=false;    perioada=temp;    }}// Standard Input/Output functions#include <stdio.h>// Timer 0 overflow interrupt service routineinterrupt [TIM0_OVF] void timer0_ovf_isr(void){// Reinitialize Timer 0 valueTCNT0=0x83;     if (flag_int==true){temp=temp+1;}}void main(void){char byte;// Port DPORTD=0x04;DDRD=0x00;// Timer/Counter 0 // Clock source: System Clock// Clock value: 125.000 kHz// Mode: Normal top=FFh// OC0 output: DisconnectedTCCR0=0x03;TCNT0=0x83;OCR0=0x00;// External Interrupt(s) initialization// INT0: On// INT0 Mode: Rising EdgeGICR|=0x40;MCUCR=0x03;MCUCSR=0x00;GIFR=0x40;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x01;// USART initialization// Communication Parameters: 8 Data, 1 Stop, No Parity// USART Receiver: On// USART Transmitter: On// USART Mode: Asynchronous// USART Baud Rate: 9600UCSRA=0x00;UCSRB=0x18;UCSRC=0x86;UBRRH=0x00;UBRRL=0x33;flag_int=false;flag_ms=false;perioada=0;// Global enable interrupts#asm("sei")while (1)      {      byte=getchar();      if(byte=='g')        {         flag_ms=true;         wait_flag:                    if(flag_ms==true){goto wait_flag;}           printf("Perioada=%ims\r",perioada);                 }      };}
Sunt 4 variabile:

flag_ms - da startul masurarii

flag_int - da startul incrementarii la fiecare ms a unei teporar temp

la terminarea masurarii , cand flag_int =false, continutul lui temp este transferat in variabila "perioada"

Succes

Link spre comentariu

partea asta:"char flag_int;char flag_ms;unsigned int perioada;unsigned int temp;// External Interrupt 0 service routineinterrupt [EXT_INT0] void ext_int0_isr(void){if(flag_ms==true) { flag_int=true; temp=0; }else { flag_int=false; flag_ms=false; perioada=temp; }}"eu asi inlocui cu asta: "volatile char flag_int;volatile char flag_ms;volatile unsigned int perioada;volatile unsigned int temp;// External Interrupt 0 service routineinterrupt [EXT_INT0] void ext_int0_isr(void){if(flag_int==true) { flag_int=false; flag_ms=false; perioada=temp; } if(flag_ms==true) { flag_int=true; temp=0; } }"altfel o sa stea in bucla infinita(vezi goto wait_flag)

Link spre comentariu

Asta asa daca nu are semnal la INT0, daca are semnal continuu , dupa o perioada a semnalului flagul se reseteaza. Codul nu este perfect, este luat dintr-un program mai amplu in care , printre altele masuram niste timpi, dar sigur merge.

Link spre comentariu

flagul respectiv nu se reseteaza nicaieri :) uitate pe cod:)dar nu am postat ca sa fiu carcotas, era un gest generos sa postezi asa rapid un cod, eu numai am corectat-o, userul respectiv a cerut si o solutie pentru masurare factor de umplere, uite aici este:

/*Frecventa MCU este considerat 8MHz!*/#include #include #include #define true 0#define false 1volatile char flag_int;volatile char flag_ms;volatile unsigned int perioada;volatile unsigned int temp;//printf setup for avr-gccstatic int uart_putchar(char c, FILE *stream);static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);static int uart_putchar(char c, FILE *stream){ if (c == '\n') uart_putchar('\r', stream); loop_until_bit_is_set(UCSRA, UDRE); UDR = c; return 0;}//static int uart_putchar(char c, FILE *stream)// External Interrupt 0 service routineISR(INT0_vect){/*Modificare pentru masurare factor de umplere: modificare intrerupere, sa apara pe front negativ */ if(flag_int==true) { flag_int=false; flag_ms=false; perioada=temp; //Pentru varianta factor de umplere MCUCR=0x03; // Reconfigurat pentru front pozitiv(stare initiala) } if(flag_ms==true) { flag_int=true; temp=0; //Pentru varianta factor de umplere MCUCR=0x02; // Urmatoarea intrerupere o sa apara pe frontul negativ } }//ISR(INT0_vect)// Timer 0 overflow interrupt service routineISR(TIMER0_OVF_vect){// Reinitialize Timer 0 valueTCNT0=0x83; if (flag_int==true) temp=temp+1;}//ISR(TIMER0_OVF_vect)int main(void){//printf setupstdout = &mystdout;// Timer/Counter 0// Clock source: System Clock(8MHz)// Clock value: 125.000 kHz (prescaller 64)// Mode: Normal top=FFh// OC0 output: DisconnectedTCCR0=0x03;TCNT0=0x83;OCR0=0x00;// External Interrupt(s) initialization// INT0: OnGICR|=0x40;MCUCR=0x03; // INT0 Mode: Rising EdgeMCUCSR=0x00;GIFR=0x40;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x01;// USART initialization// Communication Parameters: 8 Data, 1 Stop, No Parity// USART Receiver: On// USART Transmitter: On// USART Mode: Asynchronous// USART Baud Rate: 9600UCSRA=0x00;UCSRB=0x18;UCSRC=0x86;UBRRH=0x00;UBRRL=0x33;flag_int=false;flag_ms=false;perioada=0;// Global enable interrupts//#asm("sei")sei();while (1){ while ( !(UCSRA & (1<

Codul am modificat putin pentru avr-gcc, dar in mare parte a ramas, respect pentru userul mitescu, ca de la el vine codul initial :aplauze
Link spre comentariu

Ai dreptate (sunt venit de pe drumuri si sunt obosit), cand am copiat nu am copiat ce trebuie, era ceva de genul:

interrupt [EXT_INT0] void ext_int0_isr(void){ if(flag_ms==true)    {    flag_int=true;    temp=0;    } else     {    flag_int=false;    //flag_ms=false;    perioada=temp;    }    flag_ms=flag_int;}
Scuze... Oricum , daca ai dat tu o solutie mai buna, este foarte bine. Inca o data scuze.
Link spre comentariu
Vizitator xela

Deci:in primul rand pt IAR codul se scrie putin diferit.Durata unui impuls se poate masura prin 2 metode:1. daca se doreste utilizarea intreruperilor se activeaza un automat (1 buc. semafor) cu 2 stari pentru palier 1 sau palier 0. Functie de stare se starteaza timerul astfel incit sa se poata masura intervalul dorit.2. daca masuram 10 - 1000 ms (100 Hz - 1 Hz) atunci merge si un simplu test pentru 1 si 0. Se poate masura cu o precizie de pina la 100 us ( 400 instructiuni la 4MHz). Problema este de test de lab si se face in 10 min maxim. :ras: :nebun:

Link spre comentariu

@xela, nu stiu de ce te bagi in discutie... ca nu dai nici o informatie utila...

Dupa cum ai postat vad ca esti cam paralel

daca se doreste utilizarea intreruperilor se activeaza un automat (1 buc. semafor) cu 2 stari
:nebun: si sigur nu faci nici in 100 de minute treaba, numai daca folosesti ceva soft gen flowcad.

 

Faptul ca pentru IAR se scrie diferit codul..., pai asta stim toti inteligentule :)

 

Functie de stare se starteaza timerul astfel incit sa se poata masura intervalul dorit.
, parca faci politilogie, ca asta poate sa spuna oricine :) propozitia nu contine nici o informatie utila.

 

Dar ca sa nu mori chiar prost

merge si un simplu test pentru 1 si 0
metoda se numeste polling si defapt sunt 3 solutii: 1.) polling, 2.)cu intrerupere, 3.) cu input capture(cel mai precis si cu cel mai mic overhead)
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări