logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega32][c] Sprawdzenie programu - regulacja glosnosci

Taenia_Saginata 20 Lut 2009 20:53 1637 1
REKLAMA
  • #1 6180225
    Taenia_Saginata
    Poziom 31  
    Witam

    Napisalem sobie program do sterowania potencjometrem cyfrowym DS1802. Program dziala bardzo dobrze, ale to byl moj pierwszy program procz migania diodkami, wiec fajnie by bylo jakby ktos go przeczytal i skrytykowal za brzydkie wciecia, zle nazywanie zmiennych, uzywanie rzeczy ktorych sie powinno uzywac tylko w ostatecznosci i bardzo ostroznie itp.

    Uklad steruje sie trzema guzikami podpietymi do portu A, jeden podglasnia, drugi przycisza, trzeci calkiem wycisza. Podglosnienie albo przyciszenie wylacza automatycznie wyciszenie. Dluzsze przytrzymanie guzika plynnie zwieksza predkosc zmiany, zeby byla duza precyzja, a jednoczesnie mozliwosc szybkiego przelecenia przez caly zakres. Glosnosc wysylana do potencjometru to wartosc od 0 do 63 i jest to wytlumienie w dB.

    Te makra do zabaw z bitami powinny byc w osobnym pliku, i niedlugo je pewnie tam wyrzuce.


    #include <avr/io.h>
    #include <stdio.h>
    #include <util/delay.h>
    #include "lcd.h"
    
    #define bit_get(p,m) ((p) & (m)) 
    #define bit_set(p,m) ((p) |= (m)) 
    #define bit_clear(p,m) ((p) &= ~(m)) 
    #define bit_flip(p,m) ((p) ^= (m)) 
    #define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m)) 
    #define BIT(x) (0x01 << (x))
    char vol;		//wspolna glosnosc obu kanalow
    unsigned char flags;		//przerozne flagi ktore sie moga przydac
    unsigned char hold_length;		//Ilosc powtorzen podczas jednego przytrzymania guzika
    char wyswietlana[3];		//wyswietlana wartosc glosnosci
    unsigned char k;		//licznik do przeroznych petli
    
    void send_vol(unsigned char pot_0, unsigned char pot_1)
    //Wysyla po jednym bajcie dla kazdego potencjometru
    //C0 - reset, C1 - CLK, C7 - DATA
    {
    	bit_set(PORTC,BIT(0));
    	for (k=0;k<8;k++)
    	{
    		bit_write(bit_get(pot_0, BIT(k)), PORTC, BIT(7));
    		bit_set(PORTC, BIT(1));
    		_delay_us(1);
    		bit_clear(PORTC, BIT(1));
    		_delay_us(1);
    	}
    
    	for (k=0;k<8;k++)
    	{
    		bit_write(bit_get(pot_1, BIT(k)), PORTC, BIT(7));
    		bit_set(PORTC, BIT(1));
    		_delay_us(1);
    		bit_clear(PORTC, BIT(1));
    		_delay_us(1);
    	}
    	PORTC=0x00;
    }
    
    
    int main(void) 
    {
    
    	DDRA = 0x00;
    	PORTA = 0xFF;
    	DDRB = 0xFF; 
    	PORTB = 0xFF; 
    	DDRC = 0xFF;
    	PORTC = 0x00;
    	lcd_init();
    	_delay_ms(5); 
    	vol = 0x0A;		//Początkowa wartosc glosnosci, kiedys bedzie odczytywana z EEPROMA
    	flags = 0x00;
    	hold_length = 0x00;
    
    	for(k=0;k<8;k++)
    	{
    		write_command(0x40+k);
    		write_char(0x18);
    	}
    	for(k=0;k<8;k++)
    	{
    		write_command(0x48+k);
    		write_char(0x1C);
    	}
    	for(k=0;k<8;k++)
    	{
    		write_command(0x50+k);
    		write_char(0x1E);
    	}
    	//Wpisanie do RAMu wyswietlacza niepelnych prostokatow glosnosci
    
    	while(1)
    	{
    		if((!(PINA==0xFE))&(!(PINA==0xFD))) //Zerowanie licznika powtorzen
    		{
     			hold_length=0x00;
     		}
     		if(PINA==0xFE) //sciszanie
     		{
    			if(vol>0) vol--;
    			hold_length++;
    			if (hold_length<5) _delay_ms(110); //przyspieszanie po dluzszym przytrzymaniu
    			if (hold_length<13) _delay_ms(50);
    			_delay_ms(40);
    			bit_clear(flags, BIT(0));
     		} 
    
     		if(PINA==0xFD) //podglasnianie
     		{
    			if(vol<63)vol++;
    			hold_length++;
    			if (hold_length<5) _delay_ms(110);
    			if (hold_length<13) _delay_ms(50);
    			_delay_ms(40);
    			bit_clear(flags, BIT(0));
    
     		}
    
     		if((PINA==0xFB)&(!bit_get(flags, BIT(0)))) //Wlaczanie mute jesli jest wylaczone
     		{
     			bit_flip(flags, BIT(0));
    			write_command(0x8A);
     			write_text("  MUTE");
     			_delay_ms(300);
    		}
    
    		if((PINA==0xFB)&(bit_get(flags, BIT(0))))  //Wylaczanie mute jesli jest wlaczone
     		{
     			bit_flip(flags, BIT(0));
    			write_command(0x8B);
     			write_text(wyswietlana);
     			write_text("dB");
     			_delay_ms(300);
    		}
     		if(!bit_get(flags, BIT(0))) //Jesli mute wylaczone, wyswietlenie poziomu glosnosci
      		{
     			send_vol(vol,vol);
    			sprintf(wyswietlana,"%3.d",-vol);	
    			write_command(0x80);
    			write_text("Volume:    ");
     			write_text(wyswietlana);
    			write_text("dB");
    			write_command(0xC0);
    			for(k=0;k<(64-vol)/4;k++) //Pelne prostokaty paska glosnosci
     			write_char(255);
    			if (3-(vol%4)==0) write_char(0); //Niepelne prostokaty paska glosnosci
    			if (3-(vol%4)==1) write_char(1);
    			if (3-(vol%4)==2) write_char(2);
    			for(k=0;k<16;k++)
    			write_text(" ");
     		}
      		else send_vol(0x40,0x40); //Jesli mute wlaczone, wyciszenie potencjometra
     	}
    }
    


    Pytania dotyczące programowania mikrokontrolerów proszę zadawać w dziale Mikrokontrolery.
    Przeniosłem z Programowanie początkujący.
    [Dr.Vee]
  • REKLAMA
  • Pomocny post
    #2 6180869
    Dr.Vee
    VIP Zasłużony dla elektroda
    Fajnie, że Ci program działa. Kilka sugesti:

    1) nazwij jakoś te flagi. Możesz uzyć np:
    struct {
        unsigned mute:1;
        unsigned inna:1;
    } flags;
    
    /* dalej w kodzie */
    flags.mute = 1;


    2) używasz "magicznych stałych" w stylu 0xFD, 0x18, 63 itd. Wszystkie powinny być opisane i zdeklarowane na początku pliku za pomocą static const ... albo #define ... To samo z opóźnieniami, wymiarami LCD, bitami przycisków itp.

    3) Wszystkie funkcje i zmienne globalne wykorzystywane tylko w danym module powinny mieć kwalifikator static - było o tym nie raz na forum.

    4) write_text("tekst") zapewne umieszcza "tekst" jako stałą w pamięci RAM zamiast w pamięci programu. Poczytaj o avr/pgmspace.h i makrze PSTR().

    5) zamiast char, unsigned char itd warto używać int8_t, uint8_t itd - wtedy na 100% wiadomo że chodzi o typ 8 bitowy, a nie o znak. Definicje są w nagłówku stdint.h

    Pozdrawiam,
    Dr.Vee
REKLAMA