Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Pomoc w lokalizacji błędu AVR Bascom

18 Oct 2005 13:47 2499 13
  • Level 20  
    Złożyłem układ z Atmega8515 i LCD. oraz klawiaturą matrycową. Kwarc 110592Hz.
    Tu kod:
    Code:

    Declare Sub Zklawiatury(byval Klaw As Byte)
    Declare Sub Post()
    Declare Sub Silxsensor()
    Declare Sub Silysensor()
    Declare Sub Silzsensor()
    Declare Sub Ruchsilx(byval Ilekrokow As Word)
    Declare Sub Ruchsily(byval Ilekrokow As Word)
    Declare Sub Ruchsilz(byval Ilekrokow As Word)
    'Funkcje
    Declare Function Petlaklaw() As Byte
    'Zmienne
    Dim Klaw As Byte
    Dim Opuznienie As Byte
    Dim Wcisniete As Byte
    Dim Ilekrokow As Word
    Dim Kier As Bit
    'Przypisanie aliasów
    'Silnik X przesówający się na boki
    Silclkx Alias Portc.7
    Sildirx Alias Portc.6
    Silenabx Alias Portc.5
    Czujniksilx Alias Portd.2
    'Silnik Y podnoszący i opuszczający płytkę
    Silclky Alias Portc.4
    Sildiry Alias Portc.3
    Silenaby Alias Portc.2
    Czujniksily Alias Portd.3
    'Silnik Z poruszający się do przodu i do tyłu
    Silclkz Alias Portc.1
    Sildirz Alias Portc.0
    Silenabz Alias Portd.7
    Czujniksilz Alias Portd.4
    Config Kbd = Porta
    'Config Lcdmode = Port
    'Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Portb.6 , Db5 = Portb.7 , Db6 = Portb.0 , Db7 = Portb.1 , E = Portb.5 , Rs = Portb.4
    Config Lcd = 20 * 4

    Initlcd
    Ddrc = &B11111111                                           'ustawiam
    Ddrd = &B10000000

    Reset Portb.2
    Wait 10
    Set Portb.2
    Reset Portb.3


    Print "henio"
    Cls
    Lcd "Automatyczne ciecie"
    Lowerline
    Lcd "    Czipow V 0.1    "
    Thirdline
    Lcd "Pomysl i wykonanie:"
    Fourthline
    Lcd "       Henio"
    Wait 2
    Cls
    Call Post
    'Głowna pętla programu
     Do
     Wcisniete = Petlaklaw()
     Cls
     If Wcisniete > 16 Then
     Wcisniete = Wcisniete - 8
     End If
      If Wcisniete = 0 Then
      Kier = 1
          Call Ruchsilx(50)
           End If
           Lcd "wcisnieto: " ; Wcisniete
           Waitms 10
     Loop


    Function Petlaklaw() As Byte
             Do
             Klaw = Getkbd()
             If Klaw <> 16 Then
             Petlaklaw = Klaw
             Waitms 10
             Exit Do
             End If
             Loop
    End Function



    Sub Zklawiatury(byval Klaw As Byte)
        If Klaw >= 0 And Klaw < 10 Then
        Cls
        Fourthline
        Lcd Klaw
        Waitms 10
        End If
    End Sub

    Sub Post()

    End Sub


    Sub Silxsensor()

    End Sub

    Sub Silysensor()

    End Sub

    Sub Silzsensor()

    End Sub

    Sub Ruchsilx(byval Ilekrokow As Word )
    Dim I As Word
    If Kier = 1 Then
    Set Sildirx
    Else
    Reset Sildirx
    End If
    Set Silenabx
    For I = 0 To Ilekrokow
    Set Silclkx
    Waitms Opuznienie
    Reset Silclkx
    Next I


    End Sub

    Sub Ruchsily(byval Ilekrokow As Word)
    Dim Ii As Word
    If Kier = 1 Then
    Set Sildiry
    Else
    Reset Sildiry
    End If
    Set Silenaby
    For Ii = 0 To Ilekrokow
    Set Silclky
    Waitms Opuznienie
    Reset Silclky
    Next Ii
    End Sub

    Sub Ruchsilz(byval Ilekrokow As Word)
    Dim Iii As Word
    If Kier = 1 Then
    Set Sildiry
    Else
    Reset Sildiry
    End If
    Set Silenaby
    For Ii = 0 To Ilekrokow
    Set Silclky
    Waitms Opuznienie
    Reset Silclky
    Next Iii

    End Sub

    Po włączeniu zasilania po kilkunastu sekundach wyświetlacz się inicjalizuje i potem wyświetla jakiś znaczek w lewym górnym rogu i nic się nie dzieje oraz jak wciskam klawiaturę to zero reakcji. Proszę tylko nie pisać że mam użyć asma albo innego C bo nie o to tu chodzi. Schematu nie załączam bo ustawienia (podłączenia, aliasy) kto programuje AVR wie pewnie o co chodzi. są w listingu. Nie wiem może trzeba poustawiać fusebity albo coś. Interesuje mnie żeby ten procek ruszył. Prubuję nawet na początku zaświecać diody podłączone przez tranzystor do portu B2 i pB3. Ale nie świecą. Dziwne wygląda tak jak by się zaraz na początku zawieszało. Acha może to ważne z kwarcem są kondensatory 33pF Może trzeba dać inne. Może jeszcze jakaś linia opuźniająca na początku. Czekam na cokolwiek co będzie mnie w stanie naprowadzić. Dokumentację Atmega przeczytałem całą. Ale po angielsku może czegoś nie pojołem.
  • Level 29  
    Dodaj na początku programu:

    Code:
    $crystal = 11059200
    
    $regfile = "m8515.dat"


    Jak nie ruszy - będziemy dalej myśleć...
  • Helpful post
    Level 26  
    widze że używasz trocze procedur i mam pytanie czy zmieniałeś wielkość stosów w bascomie ???
    to też może być przyczyną.
    niedopatrzałem się też konfiguracji UARTA.

    dodatkowo jak wstawiasz kod na forum to ujmuj go w znaki code to będzie bardziej czytelny
  • Level 39  
    To ja też dorzucę słówko :D
    Jeśli nie ruszałeś fusebitów , to procek nie korzysta z podłączonego kwarcu , tylko z wewnętrznego generatora RC , który to napewno nie pracuje z częstotliwością , z jaką wydaje Ci się że pracuje.Z jaką częstotliwością pracuje "dziewiczy" ATmega8515 , podano napewno w dokumentacji.

    Piotrek
  • Level 20  
    No dziewiczy to bodaj z 1Mhz. Fakt że nie ustawiałem fusebitów. Ale teraz niestety postanowiłem poeksperymentować z fusebitami od częstotliwości i narazier jest zablokowany (programowałem go używając sample elektroniks programer znaczy bezpośrednio podpinając pod lpt) Doczytałem w dokumentacji jak zaprogramować fusebytes dziś to zrobię. Tylko pytanie jak poustawiać poszczególne fusebits odpowiedzialne za oscylatory żeby potem była możliwość szeregowego przeprogramowania. W dokumentacji doczytałem że nawet programowanie równoległe wymaga odpowiedniego (domyślnego) poustawiania fusebits od oscylatora. Może ktoś ma doświadczenie z tymi atmegami i wie jak to ruszyć żeby potem była możliwość programowania (zmiany kodu).

    Jeszcze jedno wygrzebałem AT90S8515 ale w bascomie rozpoznaje go jako atmega. ale mam dostęp do wszystkich fusebits inie wiem czy nic się nie sknoci jak go będę używał jako atmegi
  • Helpful post
    Level 26  
    jeśli zle ustawiłeś fuse bity od zegara i nie chodzi to spróbuj podpiąć Xtal2 z tego działającego procka z Xtal1 tego niedziałającego i wtedy spróbuj ustawić na wewnętrzny. potem podłącz do niego kwarc i przestaw na zewnętrzny kwarc. z tego co pamiętam to w bascomie stawiasz ostatnią pozycje (1111) ale to jeszcze musisz sprawdzić.

    co do tego at90s8515 wykrywenym jako atmega8515 to dziwne.
    może atmel jak kończył sprzedawać zwykłe kostki 90 to zamiast nich sprzedawał atmegi z włączonym bitem kompatibilności w dól.
    o powiedz co dokłanie na nim pisze i czy program skompilowany na mege działa poprawnie na nim.
  • Level 20  
    Z tym bitem kompatybilności też tak myślałem ale jest ustawiony na atmegę. NIe wiem Oznaczenia to AT90S8515 niżej 8PC i na dole 0503C. Nie wiem czy działa program skomopilowany na Atmega bo na razie nic mi się nie udało uruchomić. Spróbuję jakiś prosty listing na początek (pomrugam diodą) i zobaczę czy coś się uruchamia. Bo na razie ten listing co zamieściłem to nie rusza ani skompilowany na Atmega ani na AT90. Pokombinuje z Fusebits. Zobaczymy. Jak coś ruszy to napiszę. Z tym podłączeniem to procesory tylko zasilić czy coś jeszcze popodłączać (kondzioł do reset itp.)

    Dodano po 27 [minuty]:

    Częściowy sukces. Ta AT90 skompilowany na atmegę miga diodami. Poustawiałem tak jak napisał hunterhouse Już mam jakiś punkt zaczepienia. Tamtą atmegę odblokuję jak będę musiał. Narazie eksperymentuję na tej.
  • Helpful post
    Level 26  
    jeśli chcesz odblokowac tamten chip to robisz tak:

    sprawny chip podłączasz z zewnętrznym kwarcem i 2 kondensatorami do masy.
    sygnał zegarowy z jego pinu XTAL2 (wyjście sygnału zagarowego)
    lączysz na XTAL1 (wejście sygnału zegarowego) zablokowanego chipa.
    oba procki muszą mieć wspólną mase i kabel polączeniowy od kwarcy musi być możliwie krótki.
    wtedy podlączasz programator do zablokowanego procka i zmieniasz fusebity.
  • Level 20  
    No i wszystko niby działa (znaczy mogę dowolnie programować itd) ale apetyt rośnie w miare jedzenia. Dokleiłem sobie procedurkę bootloadera bo chciałbym mieć możliwość programowania Atmegi w układzie. No i tu się schody zaczynaja. Bo po pierwsze to nic przez uarta nie mogę się skomunikować, po drugie nie działa bootloader.(co pewnie wynika z problemu number 1) Co zrobiłem nie tak że nawet na początku nie wysyla mi przez uart Powitania. Może ktoś już się bawił z bootloaderami.


    Code:
    '$sim
    
    $crystal = 11059200
    $baud = 9600
    $regfile = "m8515.dat"
    'Muszę pamiętać o odznaczeniu piszczenia oraz bootbloku!!!!!!!!!!!!!!!!!

    'do boot blocku
    Const Ramend_lo = $5f                   'RAM ending location to set up stack pointer
    Const Ramend_hi = $04

    Const Pagesize = 32                     'Flash Memory Page Size, in WORDS

    'Variable Definitions:
    !.def Tmp_reg = R16                     'Temporary register for calculations etc.
    !.def Hex_reg = R17                     'Hex calculation register
    !.def Ser_reg = R18                     'Serial character buffer register
    !.def SPM_reg = R19                     'Temporary register for SPM register settings
    !.def Rec_size = R20                    'Number of data bytes in this Hex file line
    !.def Chk_sum = R21
    '***********************


    Declare Sub Test()
    Declare Sub Zmipod()                    'Zmiana podświetlenia kolejno zielone jasneniebieskie i niebieskie
    Declare Sub Skankod()
    Declare Sub Pierwszyekran()             'to co po włączeniu maszyny, pozycja wyjściowa po skończonym cięciu itp
    'Procedura odpowiedzialna za cięcie-najdłuższa oraz najtrudniejsza
    Declare Sub Ciecie()
    'Odpowiedzialna za nastawy(po wciśnięciu Enter na pierwszym screen'ie
    Declare Sub Ustaw()


    Dim B As Byte                           'Przechowuje skan kod klawisza od 0 do 15. 16 oznacza brak wciśniętego klawisza
    Dim Kolor As Byte                       'Zmienna odpowiedzialna za kolor podświetlenia
    'Licznik przechowujący liczbę kroków, Powinien być wyzerowany gdy silniki osiągną pozycje domowe
    Dim Licznikx As Double
    Dim Liczniky As Double
    Dim Licznikz As Double
    Const K0 = 0
    Const K1 = 1
    Const K2 = 2
    Const K3 = 3
    Const K4 = 4
    Const K5 = 5
    Const K6 = 6
    Const K7 = 7
    Const K8 = 8
    Const K9 = 9
    Const Kstop = 10
    Const Kenter = 11
    Const Kstart = 12
    Const Kkropka = 13
    Const Klewo = 14
    Const Kprawo = 15
    'Podświetlanie
    Niebieskie Alias Portb.3
    Zielone Alias Portb.2
    'Układy wykonawcze
    Przekaznik1 Alias Portd.2
    Przekaznik2 Alias Portd.3
    Przekaznik3 Alias Portd.4
    Elektroniczne1 Alias Portd.5
    Elektroniczne2 Alias Portd.6
    'Silnik X
    Xkrok Alias Portc.7
    Xkierunek Alias Portc.6
    Xenabled Alias Portc.5
    'silnik y
    Ykrok Alias Portc.4
    Ykierunek Alias Portc.3
    Yenabled Alias Portc.2
    'silnik z
    Zkrok Alias Portc.1
    Zkierunek Alias Portc.0
    Zenabled Alias Portd.7
    'Sensory
    Sensorx Alias Porte.0
    Sensory Alias Porte.1
    Sensorz Alias Porte.2
    Glosnik Alias Portd.5
    'Ustawienie LCD
    Config Lcdpin = Pin , Db4 = Portb.6 , Db5 = Portb.7 , Db6 = Portb.0 , Db7 = Portb.1 , E = Portb.5 , Rs = Portb.4
    Config Lcd = 20 * 4
    Config Kbd = Porta , Delay = 100
    'Ustawienie portów do czego mają służyć
    Config Pinb.3 = Output
    Config Pinb.2 = Output
    Config Pind.3 = Output
    Config Pind.4 = Output
    Config Pind.5 = Output
    Config Pind.6 = Output
    Config Pind.7 = Output
    Config Portc = Output
    Config Porte = Input


    Cls
    Cursor Off Noblink
    Set Zielone
    Waitms 200
    Set Niebieskie
    Waitms 200
    Reset Zielone
    Waitms 200
    Reset Niebieskie
    Set Zielone

    Deflcdchar 0 , 32 , 32 , 14 , 1 , 15 , 17 , 15 , 1       'ą replace ? with number (0-7)
    Deflcdchar 1 , 32 , 32 , 14 , 17 , 31 , 16 , 14 , 1       'ę replace ? with number (0-7)
    Deflcdchar 2 , 2 , 4 , 15 , 16 , 16 , 17 , 14 , 32       'ć replace ? with number (0-7)
    Deflcdchar 3 , 12 , 4 , 6 , 12 , 4 , 4 , 14 , 32       'ł replace ? with number (0-7)
    Deflcdchar 4 , 4 , 32 , 31 , 2 , 4 , 8 , 31 , 32       'ż replace ? with number (0-7)
    Deflcdchar 5 , 2 , 4 , 14 , 17 , 17 , 17 , 14 , 32       'ó replace ? with number (0-7)
    Deflcdchar 6 , 2 , 4 , 22 , 25 , 17 , 17 , 17 , 32       'ń replace ? with number (0-7)
    Deflcdchar 7 , 2 , 4 , 14 , 16 , 14 , 1 , 30 , 32       'ś replace ? with number (0-7)
    'Powitanie
    Cls

    Lcd "Automatyczne ci" ; Chr(1) ; "cie"
    Lowerline
    Lcd "    Czip" ; Chr(5) ; "w V 0.7    "
    Thirdline
    Lcd "Pomys" ; Chr(3) ; " i wykonanie:"
    Fourthline
    Lcd "       Henio"

    Print "Powitanie-Test UART"
    Wait 3
    'tu najlepiej poustawiać wszystkie zmienne umieszczone w sramie żeby później było łatwo znaleźć domyślne wartości
    Kolor = 1
    Pierwszyekran
    End
    '*******************************************************************************
    Sub Pierwszyekran()
    'pierwszy screen
      Cls
        Lcd "Naci" ; Chr(7) ; "nij Start " ; Chr(4) ; "eby"
        Lowerline
        Lcd "rozpocz" ; Chr(0) ; Chr(2) ; " ci" ; Chr(1) ; "cie"
        Thirdline
        Lcd "Enter - wej" ; Chr(7) ; "cie do"
        Fourthline
        Lcd "ustawie" ; Chr(6)
    Do
      Skankod                               'wywołujemy obsługę klawiatury
        If B = K0 Then
        Zmipod
        End If
    '********************
        If B = K1 Then
        Dim I As Byte
        Cls
        For I = 1 To 80
        Lcd Chr(i)
        Next I
        End If
    '********************
        If B = K2 Then

        Dim Ii As Byte
         Cls
        For Ii = 81 To 160
        Lcd Chr(ii)
        Next Ii

        End If
    '********************
        If B = K3 Then

        Dim Iii As Byte
          Cls
        For Iii = 161 To 240
        Lcd Chr(iii)
       Next Iii
        End If
    '********************
        If B = K4 Then
        Dim Iiii As Byte
        Cls
        For Iiii = 240 To 255
        Lcd Chr(iiii)
        Next Iiii
        End If
    '********************
        If B = K5 Then

        End If
    '********************
        If B = K6 Then

        End If
    '********************
        If B = K7 Then

        End If
    '********************

    '********************
        If B = K8 Then

        End If
    '********************
        If B = K9 Then

        End If
    '********************
        If B = Kstop Then

        End If
    '********************
        If B = Kenter Then
        Ustaw
        End If
    '********************
        If B = Kstart Then

        End If
    '********************
        If B = Kkropka Then
          Cls
        Lcd "Startujemy"
        Lowerline
        Lcd "boot loadera..."
        jmp $f80

        End If
    '********************
        If B = Klewo Then

        End If
    '********************
        If B = Kprawo Then

        End If
    Loop
    End Sub
    '*******************************************************************************
    Sub Zmipod()
        If Kolor = 1 Then
           Reset Zielone
           Set Niebieskie
           Kolor = 2
           Exit Sub
        End If
        If Kolor = 2 Then
           Set Zielone
           Kolor = 3
           Exit Sub
        End If
        If Kolor = 3 Then
           Reset Niebieskie
           Kolor = 1
           Exit Sub
        End If
    End Sub

    ' "Po naciśnięciu klawisza"*****************************************************
    Sub Skankod()
    Do
    B = Getkbd()
    If B <> 16 Then
    Cls
    Lcd B
    Sound Glosnik , 5000 , 100
    Exit Sub
    End If
    Loop
    End Sub
    '*******************************************************************************
    Sub Ustaw()
    Cls
    '   "1234*1234*1234*1234*"
    Lcd "1-Ustaw szer. chipa"
    Lowerline
    Lcd "2-Ustaw szer. wafla"
    Thirdline
    Lcd "3-Ustaw grub. wafla"
    Fourthline
    Lcd "        Nast" ; Chr(1) ; "pny " ; Chr(126) ; Chr(126) ; Chr(126)
    Do
    Skankod
    If B = Kstop Then
    Pierwszyekran
    End If

    Loop
    End Sub

    'to jest na końcu i jest bootloaderem Cały kod musze umieścić przed tym
    $boot = $f7f                            'Set boot vector to F7F and add a NOP, for BASCOM Programmer
       nop

    Disable Interrupts                      'no interrupts allowed during bootloader programming

    '_chk_for_bootload:                                          'Check for bootload, this one uses hardware, Port D.5
    '   cbi   DDRD,5                                             'Clear the data direction bit for input
    '   sbi   PORTD,5                                            'Set the pull-up
    '   sbic  PIND,5                                             'Skip next instruction if pin is clear
     '  jmp   $0000                                              'Pin must be high, run normal code

    _bootloader_start:                      'Otherwise, run the bootloader
       ldi   tmp_reg,Ramend_Hi              'Load temp reg with the top of SRAM value
      !out   SPH,tmp_reg                    'Move out to stack pointer low byte
       ldi   tmp_reg,Ramend_Lo              'Load temp reg with the top of SRAM value
      !out   SPL,tmp_reg                    'Move out to stack pointer low byte
       ldi   tmp_reg,$00                    'Load the temp register with USART settings
      !out   UCSRA,tmp_reg                  'Set up the USART
       ldi   tmp_reg,$18                    'Load the temp register with USART settings
      !out   UCSRB,tmp_reg                  'Set up the USART
       ldi   tmp_reg,$86                    'Load the temp register with USART settings
      !out   UCSRC,tmp_reg                  'Set up the USART
       ldi   tmp_reg,$00                    'Load the temp register with USART baud rate high
      !out   UBRRH,tmp_reg                  'Set up the USART
       ldi   tmp_reg,25                     'Load the temp register with USART baud rate low
      !out   UBRRL,tmp_reg                  'Set up the USART
       clt                                  'Clear the T flag, used to indicate end of file

    _send_boot_msg:                         'Send a bootloader started message
       ldi   ser_reg, asc("B")              'Load "B" to show bootloader enabled
       rcall _send_ser                      'Call routine to send a character

    _read_lines:                            'Read in the lines from serial port to SRAM
       rcall _receive_hex_line              'Receive a single line from the UART into SRAM

    _parse_line:                            'Decode the current hex line
       ldi   XH,$01                         'Point to start of line, high byte, uses $0100
       ldi   XL,$00                         'Point to start of line, low byte
       clr   chk_sum                        'Clear the checksum register for this line

    _read_header:
       ld    tmp_reg,x+                     'Get first character, should be ":"
       cpi   tmp_reg, asc(":")              'Compare with ":" to send as error flag
       breq  _header_ok                     'Fine, read the next record
     _header_err:                           'Not ":", send error character
       ldi   ser_reg, asc("!")              'Header error
       rcall _send_ser                      'Call routine to send a character
     _header_ok:                            'Fine, read the next record

    _read_record_size:                      'Read the data byte count for this line
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       mov   rec_size,hex_reg               'Save number of bytes in this line
       tst   rec_size                       'Test if record size is zero for this line
       brne _read_address                   'Not the final line, continue
       !set                                 'Set the T flag indicating write last page
       rjmp _write_current_page             'Final line, write current page exit to main program

    _read_address:                          'Read the address high byte and low bytes into ZH/ZL
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       mov   ZH,hex_reg                     'Load ZH with page address high byte
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       mov   ZL,hex_reg                     'Load ZL with page address low byte

    _read_record_type:                      'Read the record type for this line
       rcall _char_to_byte                  'Call routine to convert two characters to byte

    _read_data_pairs:                       'Read the rest of the data bytes
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       mov   r0,hex_reg                     'Save in R0, LS Byte of page write buffer
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       mov   r1,hex_reg                     'Save in R1, MS Byte of page write buffer

    _store_word:                            'Store current R1/R0 Word in page buffer at proper address
       ldi   spm_reg,1                      'Load SPM Enable (SPMEN)
       rcall _exec_spm                      'Execute current SPM, return is in exec_spm

    _check_byte_count:                      'Check if this was the last word of the line
       subi  rec_size,2                     'Decrement the Record Size by two bytes
       breq _read_checksum                  'Done with this data, read checksum
       subi  ZL,$FE                         'Not done, increment the low address byte by two
       rjmp  _read_data_pairs               'Go back and read the next two characters

    _read_checksum:                         'Byte count = record size, next is checksum for this line
       rcall _char_to_byte                  'Call routine to convert two characters to byte
       breq  _checksum_ok                   'Must have added to zero, checksum is okay
      _checksum_err:                        'Checksum or other decoding error detected
       ldi   ser_reg, asc("!")              'Load "!" to send as error flag
       rcall _send_ser                      'Call routine to send a character
      _checksum_ok:

    'Done decoding and storing one complete input line, so check if this page is full

    _chk_page_full:                         'Check if this page is full
       mov   tmp_reg, ZL                    'Load the address low byte into the temp reg
       andi  tmp_reg,((Pagesize - 1 )*2)    'AND with page size for this device, mask bits
       cpi   tmp_reg,((Pagesize - 1 )*2)    'Compare with page size for this device

       brne  _read_lines                    'Page buffer is not full, read another line

    _write_current_page:                    'Write current page if the page buffer is full

     _erase_page:                           'Erase Page, page address is in Z12-Z6
       ldi   spm_reg,3                      'Load Page Erase (PGERS) and SPM Enable (SPMEN)
       rcall _exec_spm                      'Execute current SPM

     _write_page:                           'Page address range is Z12-Z6 for Mega8
       andi  ZL,$C0                         'Ensure that Z5 - Z0 are 0
       ldi   spm_reg,5                      'Load page write (PGWRT) and SPM Enable (SPMEN)
       rcall _exec_spm                      'Execute current SPM

     _enable_page:                          'Re-enable the Read-While-Write section
       rcall _wait_spm                      'Check if current write is complete
       ldi   spm_reg,11                     'Set RWWSRE and SPMEN only
       rcall _exec_spm                      'Execute current SPM

    _check_end_of_file:                     'Check if this is the end of the file
       brtc  _read_lines                    'Not the last page, continue to read in data lines

    _exit_bootloader:                       'Done, exit the bootloader code
       jmp $0000                            'Jump to main program reset vector

    '*******************************************************************************
    'Send a serial character
    _send_ser:                              'Send a serial characater
       sbis  UCSRA,UDRE                     'Check if USART data register is empty
       rjmp  _send_ser                      'Not ready yet, wait
      !out   UDR,ser_reg                    'Send serial register
     ret
    '*******************************************************************************
    'Get one line from the serial port and store at start of SRAM
    _receive_hex_line:
       ldi   XH,$01                         'Set pointers to SRAM location $0100
       ldi   XL,$00                         'Above all registers

       ldi   ser_reg, asc("?")              'No data now, so load "?" to request next character
       rcall _send_ser                      'Call routine to send a character

     _receive_hex_line_char:                'Get a character from UART and add to buffer
       sbis  UCSRA,RXC                      'Check UART for a serial character received
       rjmp  _receive_hex_line_char         'No, check again...
       in    tmp_reg,UDR                    'Store input character in temp register

    '   mov   ser_reg, tmp_reg               'Echo this character for troubleshooting
    '   rcall _send_ser                      'Call routine to send a character

       cpi   tmp_reg,13                     'Compare with <CR>, input line terminator
       breq  _receive_hex_line_end          'Yes, line is finished, branch to end
       st    x+,tmp_reg                     'Otherwise store value then increment buffer and
       rjmp  _receive_hex_line_char         'Go back and get next character

     _receive_hex_line_end:                 'This input line is finished, so
     ret                                    'Done with this line, so return
    '*******************************************************************************
    'Get two characters from buffer, add to checksum and return with result in hex_reg
    _char_to_byte:
       ld    hex_reg,x+                     'Load character into hex_reg, increment X
       subi  hex_reg,$41                    'ASCII Value minus $41, "A"
       brcc  _char_to_byte1                 'Branch if value was greater than $41
       subi  hex_reg,$F9                    'Not greater, subtract $F9
     _char_to_byte1:
       subi  hex_reg,$F6                    'Subtract $F6
       lsl   hex_reg                        'Shift this data
       lsl   hex_reg                        'Left for four bits
       lsl   hex_reg                        'To move it into the
       lsl   hex_reg                        'High nibble

       ld    tmp_reg,x+                     'Get next character,
       subi  tmp_reg,$41                    'ASCII Value minus $41, "A"
       brcc  _char_to_byte2                 'Branch if value was greater than $41
       subi  tmp_reg,$F9                    'Not greater, subtract $F9
     _char_to_byte2:
       subi  tmp_reg,$F6                    'Subtract $F6

       add   hex_reg,tmp_reg                'Add into hex register
       add   chk_sum,hex_reg                'Add it into the checksum for this line
      ret
    '*******************************************************************************
    _exec_spm:                              'Execute the current SPM instruction
      !out   spmcr,spm_reg                  'Send to SPM Control Register
       spm                                  'Do SPM instruction

     _wait_spm:                             'Check if current flash write is complete
       in    spm_reg,spmcr                  'Get the SPM control Register
       sbrc  spm_reg,spmen                  'Check if SPM Enable flag is clear
       rjmp  _wait_spm                      'No, go back and wait for SPMEN flag cleared
      ret                                   'Flag cleared, Return
    '*******************************************************************************
  • Level 20  
    Piotrek alias Zumek nie wiem czemu twój post został skasowany (czy może sam go skasowałeś) ale go doklejam tu(może wnosi coś na co nie zwróciłem ówagi):

    Jeśli myślisz , że użyta przez Ciebie instrukcja ...
    Kod:

    ...
    jmp $F80
    ...

    ... wykona skok do adresu $0F80 , to ... źle myślisz Very Happy
    Jeśli chcesz okiełznać AVR-y , to radzę zapoznać się dokładnie z instrukcjami assemblera dla poszczególnych procesorów , no i oczywiście z Bascomem.Czasami płata figle Wink

    Piotrek




    ;w każdym bądź razie po skompilowaniu chyba wszystko jest dobrze bo boot blok jest umieszczony dokładnie na końcu. Nie jestem tylko pewny czy ten skok działa ale w sym. z bascoma jest dobrze (teoretycznie) więc powinno działać problem jest raczej z komunikacją po stronie rs'a. Ja wiem (doczytałem) że adresowanie w AVR jest przez rozdziały i wordy a nie byte. Fakt że to mój pierwszy AVR wcześniej używałem wyłącznie AT89C2051 (4051) i wiem że są znaczne różnice. Fakt że AVR są miejscami dziwne ale mają ciekawe właściwości i są tanie więc najlepiej na nich się pouczyć. Zumek proszę rozwiń swoją myśl i wyjaśnij mi gdzie się mylę...
  • Level 26  
    niewiem czy koledze o to chodziło ale w nocie katalogowej uC nie ma instrukcji JMP. jest za to RJMP lub IJMP.
    ja by skok zrobił tak:
    Code:

    ......
    goto bootloader_start
    ......
    ......
    $boot = $f7f
    bootloader_start:
    ......
    ......


    możesz też dodać aby bootloader zapalał jakąć diodkę to będziesz miał pewność że się odpala.

    a tak wogóle to widze że ten bootloader to jakiś gotowiec.
    masz 100% pewności że on działa na M8515 ???
    i czy ustawiałeś prędkość UARTA ale w bootloaderze (trzeba to zrobić ustawiając odpowiednie rejestry. w twoim bootloaderze to jest ale czy zostało to wyliczone dla twojego kwarcu????)
  • Level 20  
    Dobra mam już pewność że się odpala. Komunikacja przez uart też działa (znaczy mam odzew w bascom monitorze). Masz rację hunterhouse pewnie chodzi o te prędkości i jeszcze żeby użyć odpowiedniego proga. Ten boot loader to gotowiec z sampli dołączonych do bascom AVR do Atmegi8. Ale adresowanie jest takie samo. tylko nie mam pewności czy i jak poustawiać rejestry (bo pewnie są innne w atmega 8 niż 8515). Najlepiej by było żebym napisał swój bootloader ale za cienki w uszach jestem dlatego chcę wykorzystać gotowca. Myślę że z pomocą w końcu zaczaję o co chodzi i zrobię to jak należy a potem bardzo dokładnie opiszę bo na całej elektrodzie nie znalazłem dokładnego wyjaśnienia jak się za bootloadery w AVR zabrać. Najczęściej są to zdawkowe "sprawdź w instrukcji" albo "ten procesor to ma a ten nie " itp. Żadko można jakieś konkrety wyłuskać. Znalazłem kilka rozwiązań że bootloader startuje po resecie sprawdza czy jest podpięty komp i wtedy program w komputerze testuje wszystkie możliwe transwery (odpada ustawianie z jaką prędkością jest uart ustawiony) No ale nie znalazłem źródeł tylko opis jak to mniejwięcej powinno działać. Chyba zaczaiłem że po wgraniu bootloadera przez programator (w moim przypadku wraz z kodem aplikacyjnym) trzeba to usunąć żeby został fragment tylko z częścią wykonywalną z procedurą wejścia do boot bloku. Bo bootloader się sam nie przeprogramowuje. Narazie tyle jak znajdę coś ciekawego to napiszę. To nie może być aż tak bardzo skomplikowane.
  • Level 39  
    Oineh wrote:
    Piotrek alias Zumek nie wiem czemu twój post został skasowany (czy może sam go skasowałeś) ale go doklejam tu(może wnosi coś na co nie zwróciłem ówagi):
    ...
    Zumek proszę rozwiń swoją myśl i wyjaśnij mi gdzie się mylę...

    Powiem z ręką na sercu :D , że sie zagalopowałem ;)
    Kiedy podejrzałem jak wygląda kod wynikowy(assembler) , to zamiast...
    Code:

    jmp $F80

    ... ujrzałem...
    Code:

    rjmp -0x02XX (skok "do tyłu")

    ... więc nieopatrznie potraktowałem to jako błąd , zapominając na chwile o tym , że RJMP operuje w obrębie jednej strony czyli 4096b (+2kB -2kB) wysmaliłem post.Jednak pomroczność jasna mi minęła i by nie wprowadzać Cię w błąd , post usunąłem :(

    Piotrek
  • Level 20  
    No ale dzięki temu spojrzałem na całą sprawę raz jeszcze i już dziś powinienem sobie poradzić z poustawianiem wszystkiego jak trzeba. Teraz mam tylko problem z dobrym skonfigurowaniem bootloadera ale jak juz pisałem skorzystam z jakiegoś gotowca.
pcbway logo