Menysystem i en mikroprocessor...

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Menysystem i en mikroprocessor...

Inlägg av Jeppsson »

Hej!

Jag försöker att få till ett bra menysystem i en PIC men får inte det att fungera till hundra procent.

Hårdvara
Jag har en vanlig HD44780 Display kopplad på PORTB på en PIC16F648A och har för tillfället två knappar kopplare till PORTA med pulldown motstånd.

Mjukvara
Jag sitter och kodar i MikroC och kör med InternOSC.
Menyträdet har i nuvarande konfiguration 4 styck menyer som skriver ut info på displayn. Målet så här långt är bara att kunna stega i menyn med knapparna plus och minus.

Jag har bland annat problem med att minus knappen inte fungerar som den skall, nollar direkt vid tryck och reagerar inte på fler tryck.

Här kommer min kod

Kod: Markera allt

unsigned char Key_Old_State;
unsigned char Key_New_State;

//==============================================================================
// LCD START UP
//==============================================================================

void Lcd_Startup()
     {
     Lcd_Init(&PORTB);         // Initialize LCD connected to PORTB
     Lcd_Cmd(Lcd_CURSOR_OFF);  // Turn cursor off
     Lcd_Cmd(Lcd_CLEAR);
     Lcd_Out(1, 1, "Test Meny");      // Print text to LCD, 2nd row, 1st column
     Lcd_Out(2, 1, "Ver: 1.1");
     }


//==============================================================================
// Meny Tree
//==============================================================================

void Meny_Tree_Case()
   {
   switch(Key_New_State)
      {
      case 0:
      Lcd_Out(2, 1, "Meny Case 0!");
      break;

      case 1:
      Lcd_Out(2, 1, "Meny Case 1!");
      break;
      
      case 2:
      Lcd_Out(2, 1, "Meny Case 2!");
      break;
      
      case 3:
      Lcd_Out(2, 1, "Meny Case 3!");
      break;
      
      
      }
   }


//==============================================================================
// KEYBOARD SENS
//==============================================================================

void Key_Sens()
     {
     do {
        Key_Old_State = Key_New_State;
        if (Button(&PORTA, 1, 7, 1)) Key_New_State++;  //Meny Plus
        if (Button(&PORTA, 0, 7, 1)) Key_New_State--;   //Meny Minus
        if (Key_New_State >= 4) Key_New_State = 0;     //Bara fyra steg om mer så slårunt till början igen
//        if (Key_New_State < 0) Key_New_State = 3;
        if (Key_New_State != Key_Old_State) Meny_Tree_Case(); //Om Key_New_State inte är samma som Key_Old_State gå till Meny_Tree_Case
        }
      while(1);
      }


//==============================================================================
// PIC Inställningar
//==============================================================================

void Initialize()
  {
  CMCON = 0x07;        // No comparator-thingy
  // Dont Allow interrupts
  INTCON = 0x00;         // Disables all interrupts

  // Set port directions
  TRISA = 0;         // All out but -MCLR
  TRISB = 0;      // All out
  // Set port values
  PORTA = 0;         // Start value
  PORTB = 0;         // Start value
  }


//==============================================================================
// Main startup
//==============================================================================

void main()
  {
  Initialize();       //Setup PIC
  Lcd_Startup();
  Meny_Tree_Case();
  Key_Sens();
  }
Tar tacksamt mot förslag på förbättringar och förslag på hur man kan bygga upp ett menysystem på något annat bra sätt!

/ Jeppsson
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

Ta en titt hur
http://www.siwawi.arubi.uni-kl.de/avr_p ... 70517b.zip
har löst menysystemet.

Hur hanterar du kontaktstuds t.ex. ?
Gimbal
Inlägg: 8689
Blev medlem: 20 april 2005, 15:43:53

Inlägg av Gimbal »

Såg ett par saker.

För det första kör du med unsigned char för key_new_state och sedan kollar du om den är mindre än 0. ologiskt.

Sen måste du nog se till så att du bara stegar ett steg i taget, gissningsvis racear du till ändlägena så fort du nuddar plus eller minus knappen.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

I MikroC rutiner så har dom en funktion som heter Button som tar hand om kontaktstuts...

Kod: Markera allt

if (Button(&PORTB, 0, 1, 1)) oldstate = 1;
Description Function eliminates the influence of contact flickering upon pressing a button (debouncing).

Parameter port specifies the location of the button; parameter pin is the pin number on designated port and goes from 0..7; parameter time is a debounce period in milliseconds; parameter active_state can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.


Skall kolla länken :)

Edit: Förklarar funtkionen button
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Har fått det att fungera lite bättre om jag drar upp Debounce tiden till 100 ms samt att jag ändrar key_new_state och key_old_state till signed char och kontrollerar att key_new_state håller sig mellan 0 och 3.

Den filen som du länkade till Micke_s var lite över min nivå och svår att tyda då den hoppar mellan flera olika c filer.

Skall jobba vidare på min egen lösning och se om jag får den att fungera bra! :?

Men tar gärna mot fler ideer.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag använder meny-system i många projekt och jag har alltid gjort så att en 100ms interrupt läser knapparna EN gång per interrupt, det tar hand om debounce, sedan dekodas dessa knappar och används i programmet. Beroende på hur många knappar kan man göra på olika sätt.

Jag använder oftast "n-key rollover" men i vissa fall kan det vara aktuellt med "2-key lockout".

Allt detta med inbyggda funktioner osv. har jag aldrig använd.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Har fått det att fungera lite bättre om jag drar upp Debounce tiden till 100 ms...

Vilken "debounce tid" ? Jag ser inte den i koden. Vad är det som du har
"dragit upp" ?

Generellt sätt skulle jag sätta upp en timer för att ge en "time base" på
säg 25-50 ms. Denna kan sedan användas till olika saker som
att t.ex kolla av knapparna (inkl debounce) ta tid för knapp-repetition m.m.
Alltså i princip samma sak som Icecap menar med ett "100ms interrupt"...
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Jo i MikroC finns där redan en "färdig" funktion som tar hand om knappar och debounce.

Utklipp från min kode

Kod: Markera allt

//==============================================================================
// KEYBOARD SENS
//==============================================================================

void Key_Sens()
     {
     do {
        Key_Old_State = Key_New_State;
        if (Button(&PORTA, 1, 100, 1)) Key_New_State++;  //Meny_Upp
        if (Button(&PORTA, 0, 100, 1)) Key_New_State--;  //Meny_Ner
//        if (Button(&PORTA, 7, 100, 1)) ;             //Enter
        if (Key_New_State >= 4) Key_New_State = 0;
        if (Key_New_State <= -1) Key_New_State = 3;
        if (Key_New_State != Key_Old_State) Meny_Tree_Case();
        }
      while(1);
      }
Funktionen heter Button och fungerar på förljande sätt.

if (Button(&PORTA, 1, 100, 1)) Key_New_State++;

Description Function eliminates the influence of contact flickering upon pressing a button (debouncing).

Parameter port specifies the location of the button; parameter pin is the pin number on designated port and goes from 0..7; parameter time is a debounce period in milliseconds; parameter active_state can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.


100 som jag har fetmarkerat är Debounce tiden.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Men asså, det här har ju inte med avstudsning att göra? Din kod kommer ju att tok-loopa igenom Key_Sens()-funktionen. Håller du in knappen 300ms så kommer ++ att köras tre gånger... trycker du på den andra knappen så gör den -- några gånger tills den når noll och varvet därefter slår runt till 255. Därefter blir den väl låst på något sätt...
Tänk igenom hur koden exekveras och tänkt på att allt går tok-fort!!
Du ska alltså byta ut "if (Key_New_State <= -1)" mot "if (Key_New_State == 0)" eftersom den variabel du deklarerat inte kan anta negativa värden.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Jag har skrivit i ett tidigare inlägg att jag ändra key_new_state till signed char.
Jeppsson skrev:Har fått det att fungera lite bättre om jag drar upp Debounce tiden till 100 ms samt att jag ändrar key_new_state och key_old_state till signed char och kontrollerar att key_new_state håller sig mellan 0 och 3.
Och svar ja håller jag inne knappen så stegar den automatiskt genom menyn. Men ett tryck så tar den ett steg i menyn.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Sorry, borde sova istället för att försöka klura på mjukvaruproblem =) Erkänner att jag nog läste tråden lite slarvigt. :roll:
Jeppsson skrev:Har fått det att fungera lite bättre om jag drar upp Debounce tiden till 100 ms samt att jag ändrar key_new_state och key_old_state till signed char och kontrollerar att key_new_state håller sig mellan 0 och 3.
Men.. vad betyder "lite bättre"? Vad fungerar bättre, och hur mycket bättre?
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Ibland så skriver den ut lite konstiga tecken på displayn.

Vet inte riktigt vad det beror på?!
Jag har avkopplings konding 100nF både till display och µP.
Börjar få lite ont om ben på µp så jag kör displayn på programmerings pinnarna till PICen.

De är kopplade på följande sätt:
På PIC benet tex RB7 som oxå är PGD har jag kopplat in programmeraren Wisp628s PGD där ifrån satt ett 4,7K ohm motstånd som går till displayns D7 ben.

Kan det vara det sist nämda som orsakar mitt problem?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Varför har du ett 4,7K där?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Om själva *programmeringen* går bra, så är det inget problem med
inkopplingen av Wisp628. Efter programmeringen kopplar Wisp628
själv bort alla pinnar (sätter dom i high-Z läge) så de ska inte störa
under programkörningen.

> Ibland så skriver den ut lite konstiga tecken på displayn.

Är det det som är det aktuella och enda problemet ?
Timing ? Avkoppling ?
Skriv svar