[bascom]Pomoc w napisaniu(dokończeniu) programu

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Tomasz Olech
-
Posty: 1
Rejestracja: 23 mar 2008, 1:56
Lokalizacja: Gliwice
Kontakt:

[bascom]Pomoc w napisaniu(dokończeniu) programu

Post autor: Tomasz Olech » 23 mar 2008, 5:33

Witam. Jestem nowo zarejestrowany, lecz od dawna czytam forum.

Dostałem od taty za zadanie zbudować sterownik świateł(230V). 8 kanałowy, z ściemnianiem. Mam o tyle łatwiej że mamy już jeden kupiony, choć to mało ważne.

Warunki:
-min. 2,5kW/ kanał
-musi być ściemnianie/zapalanie (welcome PWM)
-sterownik ma być do końca marca
Tata osobiście nie wierzy we mnie, więc to sprawa honoru aby to wykonać :)

Wybrałem sobie atmegę8, porty D jako wyjściowe.
i teraz zaczynam pytania, jako że jestem prawie zielony jeśli chodzi o elektronikę.
Stabilizator to lm7805, atmega zasilana ma być napięciem od 4,5 do 5,5V. Polecili mi w elektronicznym trafo o wtórnym 9V. Czy to nie za dużo dla atmegi? W sklepie mi powiedzieli, że tak się robi, że wszyscy tak kupują, ale hmm... zawsze mogę dać na końcu rezystor...
Dalej: z portów D idzie (poprzez rezystor) na LED'a, potem optotriak moc3021, i BT139. To już załatwione, sprawdzone i działa. Zaczerpnąłem to z tego kupnego sterownika (tyle że tam pracuje uC mikrochipa PICxxxx).

Co do bascom: przeczytałem książkę M. Wiązani "prog. mikrokontrolerów w języku bascom", ale i tak kilka rzeczy nie rozumiem :)
Film pokazujący jak ma to działać (ten był kupiony)
Do rzeczy:
1.Czytam, że sygnał PWM jest generowany na wyjściach OC1A i OC1b, a ja to chcę na porty D. Da się to zrobić z poziomu programu? A jeśli tak, to jak?
2. Jak zrobić, aby gasiły się wszystkie kanały, po czym zapalały (patrz film z linku)? Trzeba jakoś zaznaczyć kolejne sekwencje w tabelach?(patrz program)
3. Jak zrobić aby w momencie gaszenia kanałów 1,3,5,7 kanały 2,4,6,8 się zapalały(naprzemian 1 kanał zapala, w tym czasie 2 gaśnie itd)?
4. Jak zrobić, aby za pomocą potencjometru dało się regulować szybkość gaszenia/ zapalania?(nie szybkość całego programu a tylko szybkość przebiegów PWM)
5. Jak widać na początku programu wpisałem przycisk, który ma powodować przejście do następnej sekwencji. Nie wiem jak to dalej wpisać, gdzie. Zaznaczam że program ma sam lecieć od początku do końca, ale gdy się naciśnie przycisk, to przechodzi do następnej sekwencji/tabeli.

I na koniec proszę o przejrzenie całego programu w poszukiwaniu potencjalnych błędów. Bascom-avr kilka pokazał, usunąłem, ale wolę aby ktoś fachowym okiem na to spojrzał.

Kod: Zaznacz cały

$regfile = "m8def.dat"
$crystal = 8000000

Config Portd = Output                                       'Wszystkie linie portu D jako wyjściowe
Config Pinb.0 = Input                                       'pinb.0 jako wejscie
Przycisk Alias Pinb.0
Dim Opoznienie As Word                                      'opóźnienie między przełączeniami, liczba do 65535
Dim Efekt As Byte                                           'numer efektu
Dim X As Byte                                               'indeks
Dim Port As Byte                                            'liczba którą wpiszemy do portu
Dim Kierunek As Bit
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Enable Interrupts
On Int0 Przerwanie                                          'włączamy przerwania
Enable Int0


Do
'tutaj główna część
Gosub Potencjometr
If Efekt = 0 Then Gosub Wprawo                              'jeśli włączony efekt nr1, to idź do podprogramu WPRAWO
Gosub Potencjometr
If Efekt = 1 Then Gosub Dosrodka                            'itp
Gosub Potencjometr
If Efekt = 2 Then Gosub Lancuch
Gosub Potencjometr
If Efekt = 3 Then Gosub Lancuch2
Gosub Potencjometr
If Efekt = 4 Then Gosub Sekwencja1
Gosub Potencjometr
If Efekt = 5 Then Gosub Sekwencja2
Gosub Potencjometr
If Efekt = 6 Then Gosub Sekwencja3
Gosub Potencjometr
If Efekt = 7 Then Gosub Sekwencja4
Gosub Potencjometr
If Efekt = 8 Then Gosub Sekwencja5
Gosub Potencjometr
If Efekt = 9 Then Gosub Sekwencja6
Gosub Potencjometr
If Efekt = 10 Then Gosub Sekwencja7
Gosub Potencjometr
If Efekt = 11 Then Gosub Sekwencja8
Gosub Potencjometr
If Efekt = 12 Then Gosub Sekwencja9
Gosub Potencjometr
If Efekt = 13 Then Gosub Sekwencja10
Gosub Potencjometr
If Efekt = 14 Then Gosub Sekwencja11
Gosub Potencjometr
If Efekt = 15 Then Gosub Sekwencja12
Gosub Potencjometr
If Efekt = 16 Then Gosub Sekwencja13
Gosub Potencjometr
'itd...
Loop
End

'-------------------------
Potencjometr:                                               'podprogram sprawdzania wartości z potencjometru
Start Adc
Opoznienie = Getadc(0)                                      'w tym przypadku pinC.0
Stop Adc
Opoznienie = Opoznienie * 2                                 'mnożymy gdyby było za mało
Return

Przerwanie:
Disable Int0
Incr Efekt                                                  'zmieniamy efekt
If Efekt > 9 Then Efekt = 0                                'jeśli mamy tylko 10 efektów
Waitms 50                                                   'lekkie opóźnienie żeby nie zwiększyć kilkukrotnie za jednym przyciśnięciem
Enable Int0
Return

'--------------------------
Wprawo:
Port = 255
For X = 0 To 7                                              'powtarzane 8 razy
Shift Port , Right                                          'przesuwam o jeden w prawo
Portd = Port                                                'wpisuje wartość do portu
Waitms Opoznienie                                           'opóźniam
Next X
Return

Dosrodka:
For X = 0 To 7                                              'powtarzane 8 razy
Port = Lookup(x , Tab_dosrodka)                             'sekwencje odczytuje z tabeli
Portd = Port
Waitms Opoznienie
Next X
Return

Lancuch:
For X = 0 To 7                                              'powtarzane 8 razy
Port = Lookup(x , Tab_lancuch)
Portd = Port
Waitms Opoznienie
Next X
Return

Lancuch2:
For X = 0 To 7
Port = Lookup(x , Tab_lancuch2)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja1:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja1)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja2:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja2)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja3:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja3)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja4:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja4)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja5:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja5)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja6:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja6)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja7:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja7)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja8:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja8)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja9:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja9)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja10:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja10)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja11:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja11)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja12:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja12)
Portd = Port
Waitms Opoznienie
Next X
Return

Sekwencja13:
For X = 0 To 7
Port = Lookup(x , Tab_sekwencja13)
Portd = Port
Waitms Opoznienie
Next X
Return

'a niżej tabele z sekwencjami:
Tab_dosrodka:
Data &B11111111 , &B01111110 , &B00111100 , &B00011000 , &B00000000
Tab_lancuch:
Data &B10101010 , &B01010101 , &B10101010 , &B01010101 , &B10101010
Tab_lancuch2:
Data &B01010101 , &B10101010 , &B01010101 , &B10101010 , &B01010101
Tab_sekwencja1:
Data &B10000000 , &B11000000 , &B11100000 , &B11110000 , &B11111000 , &B11111100 , &B11111110 , &B11111111 , &B01111111 , &B00111111 , &B00011111 , &B00001111 , &B00000111 , &B00000011 , &B00000001 , &B00000000

Tab_sekwencja2:
Data &B10000000 , &B01000000 , &B00100000 , &B00010000 , &B00001000 , &B00000100 , &B00000010 , &B00000001 , &B10000001 , &B01000001 , &B00100001 , &B00010001 , &B00001001 , &B00000101 , &B00000011 , &B10000011 , &B01000011 , &B00100011 , &B00010011 , &B00001011 , &B00000111 , &B10000111 , &B01000111 , &B00100111 , &B00010111 , &B00001111 , &B10001111 , &B01001111 , &B00101111 , &B00011111 , &B10011111 , &B01011111 , &B00111111 , &B10111111 , &B01111111 , &B11111111

Tab_sekwencja3:
Data &B10000001 , &B11000011 , &B11100111 , &B11111111 , &B11100111 , &B11000011 , &B10000001

Tab_sekwencja4:
Data &B11111111 , &B00000000 , &B11111111 , &B00000000 , &B11111111 , &B00000000 , &B11111111

Tab_sekwencja5:
Data &B11111111 , &B01111111 , &B10111111 , &B11011111 , &B11101111 , &B11110111 , &B11111011 , &B11111101 , &B11111110

Tab_sekwencja6:
Data &B10000000 , &B11000000 , &B01100000 , &B00110000 , &B00011000 , &B00001100 , &B00000110 , &B00000011 , &B00000110 , &B00001100 , &B00011000 , &B00110000 , &B01100000 , &B11000000

Tab_sekwencja7:
Data &B11100111 , &B00011000 , &B11000011 , &B00111100 , &B10000001 , &B01111110 , &B10010010 , &B01001001 , &B00100100 , &B10010010 , &B01001001 , &B00100100 ,

Tab_sekwencja8:
Data &B11000000 , &B01100000 , &B00110000 , &B00011000 , &B00001100 , &B00000110 , &B00000011 , &B00000110 , &B00001100 , &B00011000 , &B00110000 , &B01100000 , &B11000000

Tab_sekwencja9:
Data &B10000000 , &B11000000 , &B11100000 , &B11110000 , &B11111000 , &B11111100 , &B11111110 , &B11111111 , &B10000000 , &B11000000 , &B11100000 , &B11110000 , &B11111000 , &B11111100 , &B11111110

Tab_sekwencja10:
Data &B11111111 , &B11111110 , &B11111100 , &B11111000 , &B11110000 , &B11100000 , &B11000000 , &B10000000 , &B11111111 , &B11111110 , &B11111100 , &B11111000 , &B11110000 , &B11100000 , &B11000000 , &B10000000

Tab_sekwencja11:
Data &B10000001 , &B11000011 , &B11100111 , &B01111110 , &B00111100 , &B00011000
Tab_sekwencja12:
Data &B00011000 , &B00111100 , &B01111110 , &B11111111 , &B00011000 , &B00111100 , &B01111110 , &B11111111

Tab_sekwencja13:
Data &B10101010 , &B01010101 , &B11001100 , &B00110011 , &B11100111 , &B00111001 , &B11111111
Pozdrawiam, Tomek.

ZbeeGin

Re: [bascom]Pomoc w napisaniu(dokończeniu) programu

Post autor: ZbeeGin » 23 mar 2008, 9:23

Tomasz Olech pisze:1.Czytam, że sygnał PWM jest generowany na wyjściach OC1A i OC1b, a ja to chcę na porty D. Da się to zrobić z poziomu programu? A jeśli tak, to jak?
Trzeba zrobić programowo-sprzętowy PWM z ośmioma kanałami. Cała idea jest podobna do tego:

Kod: Zaznacz cały

$regfile = "m8def.dat"
$crystal = 8000000

Config Pind.0 = Output                  'Konfiguracja 4 pinów wyjściowych PWM
Config Pind.1 = Output
Config Pind.2 = Output
Config Pind.3 = Output

Reset Portd.0
Reset Portd.1
Set Portd.2                             'ustawiamy druga pare jako zanegowana
Set Portd.3

Dim Wyp(4) As Byte                      'zmienne wypełnienia
Dim Licz As Byte                        'zmienna głównego licznika

Config Timer0 = Timer , Prescale = 8    'konfiguracja Timer0 jako timer
On Timer0 Przerwanie                    'wywołanie procedury liczącej przy przerwaniu
Enable Timer0                           'włączamy Timer0
Enable Interrupts                       'włączamy przerwania
'###########################################
Wyp(1) = 4                              ' przykładowe wartości początkowe wypełnień
Wyp(2) = 16
Wyp(3) = 50
Wyp(4) = 100

Do
  Rem tu obsługa przycisków i wyświetlacza LCD
Loop

End

Przerwanie:
 Timer0 = 224
 Incr Licz
 If Licz = Wyp(1) Then Toggle Portd.0
 If Licz = Wyp(2) Then Toggle Portd.1
 If Licz = Wyp(3) Then Toggle Portd.2
 If Licz = Wyp(4) Then Toggle Portd.3
 If Licz = 100 Then
   Licz = 0
   Portd.0 = 0                          ' zerowanie portów
   Portd.1 = 0
   Portd.2 = 1
   Portd.3 = 1
 End If
Return
Tomasz Olech pisze:2. Jak zrobić, aby gasiły się wszystkie kanały, po czym zapalały (patrz film z linku)? Trzeba jakoś zaznaczyć kolejne sekwencje w tabelach?(patrz program)
Korzystając z tabeli jeśli na danym bicie jest 1 to zwiększamy wypełnienie, jeśli zero to zmniejszamy. Trzeba tylko zdecydować w ilu krokach by miało to pewną płynność.
Tomasz Olech pisze:3. Jak zrobić aby w momencie gaszenia kanałów 1,3,5,7 kanały 2,4,6,8 się zapalały(naprzemian 1 kanał zapala, w tym czasie 2 gaśnie itd)?
U jednych zwiększać wypełnienie, u drugich zmiejszać i vice versa.
Tomasz Olech pisze:4. Jak zrobić, aby za pomocą potencjometru dało się regulować szybkość gaszenia/ zapalania?(nie szybkość całego programu a tylko szybkość przebiegów PWM)
Zmieniaj podstawę czasu licznika sprzętowego, tak aby taktowanie licznika programowego z "układu" PWM było zmienne.
Tomasz Olech pisze:5. Jak widać na początku programu wpisałem przycisk, który ma powodować przejście do następnej sekwencji. Nie wiem jak to dalej wpisać, gdzie. Zaznaczam że program ma sam lecieć od początku do końca, ale gdy się naciśnie przycisk, to przechodzi do następnej sekwencji/tabeli.
Po naciśnięciu przycisku wywołaj podprogram "Przerwanie" za pomocą GOSUB. Jest to bardzo nieeleganckie ale powinno działać. Skorzystaj oczywiście z polecenia DEBOUNCE by przycisk działał pewnie i jednorazowo.

ODPOWIEDZ