Sida 2 av 4

Postat: 7 december 2005, 09:11:00
av JimmyAndersson
>En OR är en bitmässig OR och kommer alltså enbart att göra 2 st 8-bitars ord till 1 st gemensamt 8-bitars ord.

Icecap: Oj, ja.. tur att du är vaken. :) Det jag var ute efter var att slå ihop två byte till ett word. Ska använda sodjans exempel istället.

(Jag har precis bytt dygnsrythm, så då är man lite trött i början. Det verkar synas i koden. Hm, Kaffe!!) :)

Nu ska jag jobba vidare med koden.


edit: Ajdå, det gick inte att använda multiplikation i interrupt-proceduren. Hm, får fixa på annat sätt.

Postat: 7 december 2005, 10:01:10
av sodjan
Notera att en mult med 256 är det samma som en enkel bit shift 8 positioner till vänster, om nu det blir lättare...

Eller om det finns något sätt att assigna den höga delen av "knapp_nr" direkt ?
Kolla manualen sid 32. Man kan definiera en int (tcå bytes) och sedan definera en ny variabel (byte) som delar minnesadress med den höga delen av int'en. Sedan kan man assigna den höga delen direkt utan mult eller shift...

Postat: 7 december 2005, 13:15:33
av JimmyAndersson
Har gjort lite ändringar i koden:


Först delen av init som har hand om AD'n och interrupt:

Kod: Markera allt

    'A/D
    ADCON1 = %00001110 ' Analoga IN på AN0
    ClearBit(ADCON0, CHS3)
    ClearBit(ADCON0, CHS2)
    ClearBit(ADCON0, CHS1)
    ClearBit(ADCON0, CHS0)
    SetBit(ADCON0, ADON) ' A/D-omvandlare enable (On)
    SetBit(ADCON0, GO/DONE) ' A/D-omvandling

    'Interrupt...
    Setbit(PIE1, ADIE) ' A/D-converter Interrupt enable bit
    Setbit(INTCON, GIE) ' Global Interrupt enable bit
    Clearbit(PIR1, ADIF) ' A/D-converter Interrupt -Clearas.

Så här ser interrupt-proceduren ut i sin helhet:

Kod: Markera allt

sub procedure interrupt
  if TestBit(PIR1, ADIF) = 1 then
     knapp_nr_lo = ADRESL ' Läser av ADC's låga byte
     knapp_nr_hi = ADRESH ' Läser av ADC's höga byte
     knapp_nr = (word(knapp_nr_hi << 8)) + knapp_nr_lo ' Slår i hop.

  end if

     'RUN
      if (knapp_nr >= 507) and (knapp_nr <= 517) then run = 1
      end if

      'STOP
      if (knapp_nr >= 465) and (knapp_nr <= 475) then  run = 0
      end if

     ClearBit(PIR1, ADIF)
     SetBit(ADCON0, ADON) ' A/D-omvandlare enable (On)
     SetBit(ADCON0, GO/DONE) ' A/D-omvandling
end sub
Något som ser galet ut?

Postat: 7 december 2005, 13:29:00
av sodjan
Hur så ? :-)
Fungerar det inte ?
Varför kolla om allt fungerar som det ska...

Postat: 7 december 2005, 14:26:04
av JimmyAndersson
Sant, varför laga något som inte är trasigt. :)

-Jag kanske borde skrivit att det inte fungerar.

Med andra ord: Lysdioden är släckt hela tiden, oavsett knapptryckningar eller inte. Ett annat test med enbart koden för DAC'en ger en toning av lysdioden och jag använder samma kod i detta projekt. En test med enbart koden för knapparna (som visar text på displayen) fungerar. Använder samma kod här, men med ändringar för interrupt-koden. Så det är något med interrupt-kodningen som jag har gjort fel.
-Därav frågan. :)

Postat: 7 december 2005, 15:06:42
av sodjan
Om du tittar på schemat över interruptlogiken i databladet (figur 9-1 på sidan 76 i min kopia, rev B), så ser du att vissa interrupt (igentligen alla *utom* de som kommer från timers och PORTB pinnarna) har en extra enable-bit, INTCON.PEIE.

Prova med :

Kod: Markera allt

    'Interrupt...
    Setbit(PIE1, ADIE) ' A/D-converter Interrupt enable bit
    Setbit(INTCON, GIE) ' Global Interrupt enable bit
    Setbit(INTCON, PEIE) ' Peripherial Interrupt enable bit  '  <<<===
    Clearbit(PIR1, ADIF) ' A/D-converter Interrupt -Clearas. 
EDIT : Notera att (i alla fall i min kopia av databladet) så har man missat PEIE i den lilla listan 1-7 över vad som behöver göras för att få ett ADC interrupt. Så det är väll inte så konstigt att du också missade det... :-)

Postat: 7 december 2005, 18:23:33
av EagleSpirit
Vet du att du kommer in i interruptrutinen eller är det bara ett antagande att det är inuti interruptrutinen felet ligger?

Postat: 7 december 2005, 18:39:12
av sodjan
Som sagt, kolla PEIE...

Postat: 7 december 2005, 20:30:55
av EagleSpirit
jojo, men jag menar, han kan ju göra en liten debug precis i början av interruptrutinen, kanske skicka ett meddelande till LCD/PC eller bara sätta en utgång och koppla en lysdiod till den. Bara för att se så att han ens kommer in i interruptrutinen.

Postat: 7 december 2005, 21:06:21
av sodjan
Jojo, men det är mycket snabbare att bara sätta PEIE... :-)

Sen, när man *tror* att koden är OK, är det dags att börja debugga på allvar... :-)

Postat: 7 december 2005, 23:00:52
av JimmyAndersson
>Så det är väll inte så konstigt att du också missade det...

:) Precis. Däremot upptäckte jag fel i databladet: Det är fyra bitar som styr "Analog Channel Select bits", men de har skrivit att det är bit 5-3 (dvs 3 bitar) som har hand om det. :)

Har nu satt PEIE i init-delen. Tyvärr hjälpte det inte.
Jag är inte helt säker på att jag gjort rätt med interrupt och A/D-raderna. Ska prova med lysdioder så jag ser hur programmet körs.

Strax tillbaka. 8)

Postat: 7 december 2005, 23:55:45
av sodjan
> Har nu satt PEIE i init-delen. Tyvärr hjälpte det inte.

Nä, det var ju inte någon garanti att det var det enda felet... :-)
Däremot är jag ganska säker på att den måste vara satt till 1 för
att ADIF ska "gå igenom" och generera ett avbrott.

Postat: 8 december 2005, 00:06:40
av JimmyAndersson
Precis. Fel verkar vara ett "flockdjur"... :)

Jag plockade dit några Status-LED's:

Kod: Markera allt

sub procedure interrupt

    PORTA.2 = 1 ' *STATUS-LED 2*

  if TestBit(PIR1, ADIF) = 1 then
     knapp_nr_lo = ADRESL ' Läser av ADC's låga byte
     knapp_nr_hi = ADRESH ' Läser av ADC's höga byte
     knapp_nr = (word(knapp_nr_hi << 8)) + knapp_nr_lo ' Slår ihop.

    PORTA.3 = 1 ' *STATUS-LED 3*
  end if
Resultatet visade att programmet går in i interrupt-proceduren och att ADIF blev satt. Så långt är allt ok. Det genereras alltså ett interrupt.
(I init-proceduren lät jag dem blinka en gång för att se så de var "vakna".)

I klassisk debugger-stil ska jag nu lägga till fler Test-LED's för att se vilket fel som är trasigt.

Postat: 8 december 2005, 00:27:40
av sodjan
Det vore ju intressant att veta vilka värden som ADC ger.
Du kan inte sparka igång en USART lina och logga värderna till t.ex en PC ?

Postat: 10 december 2005, 00:06:37
av JimmyAndersson
Datorn som jag använder till Wisp-programmeraren har fått något problem som ger bluescreen hela tiden. Istället för att fixa det så ska jag lite snabbt plocka ihop en liten burk. (Datorn jag programmerar på står nämligen i ett annat rum.) Men i morgon ska jag logga ADC-värdena.

TXREG = knapp_nr_lo och TXREG = knapp_nr_hi kommer ju att skicka ASCII-tecken som motsvarar värdena, men som snabb-test lär det ju fungera. Hm, det finns förresten säkert någon inställning i terminalprogrammet som gör att jag kan ta emot ASCII-värdena.
MikroBasic's terminalprogram kan visserligen ta emot DEC/HEX/BIN-värden, men jag vet inte riktigt hur det programmet trivs på en liten 233MHz-burk med 64MB minne...

Nåja, nu ska jag bygga vidare på datorn. :)