# Συζήτηση Κυκλωμάτων > Ψηφιακά Κυκλώματα > Μικροελεγκτές >  >  LCD σε μικροελεγκτή AVR

## ALAMAN

Καλησπέρα.
Χρειάζομε μία βοήθεια σε μία σύνδεση οθόνης LCD σε μικροελεγκτή AVR.
Θέλω να την χρσησιμοποιήσω για απεικόνηση θερμοκρασίας ενός αισθητηρίου LM35. Έχω κάνει την ενίσχυση του αισθητηρίου σε αθροιστή με μία σταθερή τάση 200mV και την μετατροπή σε 8bit με το ADC0804.
Τώρα Θέλω να οδηγήσω τα 8bit σε μία θύρα που θα ορίσω ώς είσοδο στον μικροελεγκτή και στη συνέχεια με κάποια άλλη θύρα εξόδου να οδηγήσω την οθόνη. Παράδειγμα, για τιμή 00011011 να δείχνει την θερμοκρασία 25 C κλπ...
Κατασκευαστικά όμως δεν ξέρω πως λειτουργεί η οθόνη και χρειάζομαι βοήθεια στην "αποκωδικοποίηση" των 8bit για να απεικονιστούν στην οθόνη.
Έχω μία απλή LCD 2x16 πιστεύω να μου κάνει.
Και απο μικροελεγκτή σκεύτομαι να χρησιμοποιήσω τον ATMega8515.

----------


## saq

ριξε μια ματια εδω
http://www.hlektronika.gr/forum/showthread.php?t=46164

ειχα δωσει και εναν κωδικα που εκανε μια απλη απεικονιση στην ldc... :Smile:

----------


## ALAMAN

Προσπαθώ να βρώ την λειτουργία της στο multisim.
Όμως δεν έχω καταλάβει τί ακριβώς κάνουν τα pin CV, E, RS, RW
Το RD νομίζω είναι το read/write οπου εκεί συνδέουμε μία γεννήτρια τετραγωνικών παλμών...

----------


## ALAMAN

> ριξε μια ματια εδω
> 
> #include<lcd.h>
> #include<stdio.h>
> #include<delay.h>
> char lcd_buffer[33];
> void main(void)
>  { 
> 
> ...



Αυτό νομίζω είναι σε γλώσσα C. Στο AVR Studio μπορώ να γράψω C ?

----------


## saq

το προγραμμα που σου εδωσα ειναι γραμμενο σε c και στο codevision το οποιο σου παρεχει μια βιβλιοθηκη την lcd.h η οποια εχει ετοιμες μεσα εντολες-συναρτησεις για χρηση της οθονης.
το avr studio να σου πω  την αληθεια δεν το εχω χρησιμοποιησει καθολου αλλα νομιζω οτι μπορεις να γραψεις σε c,την βιβλιοθηκη αυτη ομως δεν την εχει...αν τσεκαρεις στα link που εχει δωσει o mousakias υπαρχουν παρα πολλα manual και απ'οτι ειδα εχουν μεσα και για assemply παραδειγματα....

----------


## stom

Το avr studio δεν υποστηριζει C compiler συνεργαζεται ομως με διαφορους.
Ψαξε για winavr

----------


## ALAMAN

> το προγραμμα που σου εδωσα ειναι γραμμενο σε c και στο codevision το οποιο σου παρεχει μια βιβλιοθηκη την lcd.h η οποια εχει ετοιμες μεσα εντολες-συναρτησεις για χρηση της οθονης.
> το avr studio να σου πω  την αληθεια δεν το εχω χρησιμοποιησει καθολου αλλα νομιζω οτι μπορεις να γραψεις σε c,την βιβλιοθηκη αυτη ομως δεν την εχει...αν τσεκαρεις στα link που εχει δωσει o mousakias υπαρχουν παρα πολλα manual και απ'οτι ειδα εχουν μεσα και για assemply παραδειγματα....



Στο codevision πώς ακριβώς μπορώ να γράψω τον κώδικα γιατί είναι λίγο περίπλοκο...

----------


## ALAMAN

Στην οθόνη LCD 2x16 για να γράψουμε δεδομένα πρέπει στο RS να υπάρχουν παλμοί ή να είναι μονίμως στο 1 ?

----------


## stom

```
/* 
  LCD Demo
  
  CodeVisionAVR C Compiler
  (C) 2000-2007 HP InfoTech S.R.L.
  www.hpinfotech.ro
  
  Chip: ATmega8515
  Memory Model: SMALL
  Data Stack Size: 128 bytes

  Use an 2x16 alphanumeric LCD connected
  to the STK500 PORTC header as follows:

  [LCD]   [STK500 PORTC HEADER]
   1 GND- 9  GND
   2 +5V- 10 VCC  
   3 VLC- LCD contrast control voltage 0..1V
   4 RS - 1  PC0
   5 RD - 2  PC1
   6 EN - 3  PC2
  11 D4 - 5  PC4
  12 D5 - 6  PC5
  13 D6 - 7  PC6
  14 D7 - 8  PC7
*/

// the LCD is connected to PORTC outputs
// see the file lcd.h in the ..\inc directory
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm

// include the LCD driver routines
#include <lcd.h>

void main(void)
{
// initialize the LCD for
// 2 lines & 16 columns
lcd_init(16);

// go on the second LCD line
lcd_gotoxy(0,1);

// display the message
lcd_putsf("Hello world");

// stop here
while (1);
}
```

----------


## saq

οπως εγραψε και ο stom μεσα στο  codevision σου δινει τα init που χρειαζεσαι για να δουλεψει η οθονη σε ρωταει στο wizzard (αν το χρησιμοποιησεις) ποια πορτα θες να συνδεσεις στην οθονη και μετα σου δινει το σεταρισμα των πινς και μπορεις να χρησιμοποιησεις και την βιβλιοθηκη lcd.h και εισαι ετοιμος... :Smile:

----------


## ALAMAN

Ενοείς στο παρακάτω παράθυρο?
Πατάω File -> New ->  (στο file type) επιλέγω project -> ok -> βγάζει ένα παράθυρο για το wizard, επιλέγω ναι -> και εμφανίζεται το παρακάτω παράθυρο
Στο πλαίσιο δεξιά γράφουμε τον κώδικα?

Το Wizard τί ακριβώς είναι ?

----------


## robotakias

> Ενοείς στο παρακάτω παράθυρο?
> Πατάω File -> New -> (στο file type) επιλέγω project -> ok -> βγάζει ένα παράθυρο για το wizard, επιλέγω ναι -> και εμφανίζεται το παρακάτω παράθυρο
> Στο πλαίσιο δεξιά γράφουμε τον κώδικα?
> 
> Το Wizard τί ακριβώς είναι ?



Θα πάς εκεί που έχει την LCD και θα διαλέξεις την πόρτα που θες να είναι και το είδος της LCD (2x16 κτλ).
Μετά θα κάνεις File -> Save, Genarate and Exit θα ονομάσεις το project σου και το αρχείο σου. 
Μην παιδεύεσαι με το AVRStudio , το codevision όπως είπαν και οι προηγούμενοι έχει έτοιμες τις βιβλιοθήκες.
 :Smile:  :Wink:

----------


## ALAMAN

Μπορώ να γράψω και ελληνικούς χαρακτήρες στην οθόνη?

----------


## ALAMAN

Και ποιό αρχείο φορτώνω ?


Στην καρτέλα ports εκεί που ορίζουμε την θύρα ώς είσοδο απο δεξιά η στήλη pullup / Output Value τί ακριβώς είναι ? Έχει δύο επιλογές P και Τ

----------


## stom

Pullup και tristate...Ελληνικα για να γραψεις πρεπει να υπαρχουν στη γεννητρια χαρακτηρων του HD44xx controller.
Οι pullup αντιστασεις συχνα χρησιμοποιουνται σε εισοδους που ειναι στον αερα.

----------


## ALAMAN

> Pullup και tristate...Ελληνικα για να γραψεις πρεπει να υπαρχουν στη γεννητρια χαρακτηρων του HD44xx controller.
> Οι pullup αντιστασεις συχνα χρησιμοποιουνται σε εισοδους που ειναι στον αερα.



Δηλαδή να το αφήσω σε pullup ?
Και για τους χαρακτήρες ενοείς στον τύπο (κωδικό) της οθόνης ?

----------


## stom

Για συνδεση σε LCD μαλλον δεν χρειαζεσαι pull-up.. Ειδικοτερα αν ολα δουλευουν σε 5 volt. Για διαφορετικες τασεις επεξεργαστη-lcd πρεπει να γινεις πιο συγκεκριμενος.
Για user defined χαρακτηρες σε lcd display δες καταρχας το datasheet του LCD.
Απο οτι θυμαμαι δεν υποστηριζεται απο τις βιβλιοθηκες του codevision.

----------


## ALAMAN

Επειδή ο υπολογιστής μου δεν έχει σειριακή μπορώ να κάνω καμια μετατροπή απο σειριακή σε USB για να συνδέσω τον προγραμματιστή??

----------


## stom

Ποιον απο ολους?
Γενικα ναι, εκτος αν ειναι απαιτητικος στα 12 volt που θελει, οποτε μπορει και να μη δουλεψει...

----------


## ALAMAN

Έχω τον SKT500 ο οποίος νομίζω οτι δουλεύει απο 10-15V, δεν είμαι σίγουρος...

----------


## edgar

> Επειδή ο υπολογιστής μου δεν έχει σειριακή μπορώ να κάνω καμια μετατροπή απο σειριακή σε USB για να συνδέσω τον προγραμματιστή??



μπορει να κανω λαθος , αλλα δεν θα χρειαστει καποιο ειδος ftdi chip γι αυτην την δουλεια?

----------


## stom

Το stk500 δουλευει μια χαρα με usb2serial adaptor.
Το stk500 διαθετει σειριακη πορτα, το ftdi chip θα μπορουσε να χρησιμοποιηθει για την κατασκευη του usb2serial adapter αλλα οταν αυτα τα πραγματα ειναι ετοιμα και με κοστος 2-3 ευρω προφανως δεν αξιζει να ασχοληθει κανεις.
Αν θελαμε η κατασκευη μας να μιλαει μεσω usb σε pc τοτε ισως ναι, αλλα τοτε θα μιλουσαμε για αλλο project...

----------


## ALAMAN

> Το stk500 δουλευει μια χαρα με usb2serial adaptor.
> Το stk500 διαθετει σειριακη πορτα, το ftdi chip θα μπορουσε να χρησιμοποιηθει για την κατασκευη του usb2serial adapter αλλα οταν αυτα τα πραγματα ειναι ετοιμα και με κοστος 2-3 ευρω προφανως δεν αξιζει να ασχοληθει κανεις.
> Αν θελαμε η κατασκευη μας να μιλαει μεσω usb σε pc τοτε ισως ναι, αλλα τοτε θα μιλουσαμε για αλλο project...



Ναί όντως δουλεύει μια χαρά και το καλώδιο μετατροπής δεν έχει 2-3 ευρώ... 20 ευρώ το πήρα !!!  :Sad:

----------


## ALAMAN

Παιδιά μια μιρκή βοήθεια...
Πήρα ένα παράδειγμα απο mikrobasic και έβγαλα το hex.
Προσπαθώ να το φορτώσω με το AVRstudio αλλα μου βγάζει το παρακάτω μύνημα...

----------


## ALAMAN

Στο Codevision το αρχείο HEX πώς βγάινει?

----------


## saq

οταν φτιαξεις project στο codevision στον φακελλο του project σου μεσα εχει 4 αλλους φακελλους αν θυμαμαι καλα και εκει μεσα εχει εναν ποθ λεγεται exe.τα αρχεια εκει μεσα ειναι hex.

----------


## ALAMAN

Πήρα οθόνη LCD 2x16.
Αύριο θα κάνω μια δοκιμή με τον ATmega8515.
Μπορείται να με πείτε λίγο τον κώδικα της C πού ακριβώς τον γράφουμε?
Όταν βγαίνει ο wizard στην καρτέλα LCD βάζω την θύρα που θέλω, απο κάτω μου βγάζει τα πινς και τις συνδέσεις. Ο κυρίως κώδικας πού γράφεται?
Δεξιά υπάρχει ένα λευκό πλαίσιο κειμένου που γράφει "program preview" εκεί γράφω τον κώδικα?

----------


## stom

Οταν πατησεις οκ θα σου τα μεταφερει ολα στο κυριως παραθυρο.
Ο κωδικας μπαινει εκει που λεει, put your code here..
(and put the kot down επισης)  :Very Happy:

----------


## ALAMAN

> Οταν πατησεις οκ θα σου τα μεταφερει ολα στο κυριως παραθυρο.
> Ο κωδικας μπαινει εκει που λεει, put your code here..
> (and put the kot down επισης)



Όταν πατάω File -> New -> τσεκάρω την επιλογή project -> πατάω οκ -> και με ρωτάει αν χρησιμοποιήσω wizard -> πατάω ναι -> και μου βγάζει το ακόλουθο παράθυρο...


Μετά αφού κάνω τις ρυθμίσεις για την θύρα που θέλω να συνδέσω την LCD κλπ πατάω generate program, save file and exit. Κλείνει ο wizard και με βγάζει αυτό το παράθυρο...


Δεν γράφει πουθενά "put your code here.."

----------


## stom

Στα notes σιγουρα οχι..
Αν πας στο .c αρχειο ομως?

Πιο συγκεκριμενα, βαζει ενα μονιμο loop , καθοτι τα embedded προγραμματα δεν κανουν terminate ποτε..
while (1)
      {
      // Place your code here

      };
}

----------


## ALAMAN

> Στα notes σιγουρα οχι..
> Αν πας στο .c αρχειο ομως?
> 
> Πιο συγκεκριμενα, βαζει ενα μονιμο loop , καθοτι τα embedded προγραμματα δεν κανουν terminate ποτε..
> while (1)
>       {
>       // Place your code here
> 
>       };
> }



Σωστά... τώρα το είδα!
Σε αυτήν την ρουτίνα είναι ο κυρίως κώδικας? δηλαδή μέσα απο αυτήν θα μπορώ να ελέγξω και τις εισόδους του μικροελεγκτή για να απεικονίζει ένα αντίστοιχο μύνημα στην οθόνη?

----------


## stom

Για αρχη κανε ενα led να αναβοσβησει....
Εντος του main loop μπαινουν τα παντα εκτος απο τις interrupt service ρουτινες...
(που δεν χρειαζονται για να γραψεις κατι στην οθονη ενος led)

----------


## ALAMAN

> Για αρχη κανε ενα led να αναβοσβησει....
> Εντος του main loop μπαινουν τα παντα εκτος απο τις interrupt service ρουτινες...
> (που δεν χρειαζονται για να γραψεις κατι στην οθονη ενος led)



Δεν έχω ιδέα πως γίνεται... ακόμα και αυτό  :Confused1:  :Blushing: 
Είναι η πρώτη φορά που ασχολούμε με C.
Μόνο κάτι ρουτίνες ξέρω τύπου if κλπ...
Δηλαδή πώς ενεργοποιούμε μία θύρα σαν byte ή σαν bit ξεχωριστά ένα-ένα..?

----------


## Thansavv

Εγώ θα σου πρότεινα να ασχοληθείς καλύτερα με προγραμματισμό σε assembly. Πιστεύω ότι έτσι θα κατανοήσεις ευκολότερα την έννοια των εισόδων - εξόδων, καταχωρητών και γενικά του τρόπου λειτουργίας του AVR...Και βέβαια να διαβάσεις το datasheet και τις εντολές (instructions)...
Θέλει υπομονή και επιμονή...

----------


## stom

Δες τα παραδειγματα που εχει η codevision. π.χ υπαρχει η portA.3 που αναφερεται στο 3ο bit....
Χρειαζεσαι και ενα καλο βιβλιο για C. πχ
http://www.smileymicros.com/index.ph...age&PAGE_id=26
Εχει διαφορα ωραια αυτος...

----------


## ALAMAN

> Εγώ θα σου πρότεινα να ασχοληθείς καλύτερα με προγραμματισμό σε assembly. Πιστεύω ότι έτσι θα κατανοήσεις ευκολότερα την έννοια των εισόδων - εξόδων, καταχωρητών και γενικά του τρόπου λειτουργίας του AVR...Και βέβαια να διαβάσεις το datasheet και τις εντολές (instructions)...
> Θέλει υπομονή και επιμονή...



Είναι πολύ δύσκολη γλώσσα.
Προς το παρόν θέλω να μάθω λίγο την C και ίσως αργότερα όταν μάθω κάποια πράγματα να πάω και στην assembly.

----------


## Thansavv

> Είναι πολύ δύσκολη γλώσσα.
> Προς το παρόν θέλω να μάθω λίγο την C και ίσως αργότερα όταν μάθω κάποια πράγματα να πάω και στην assembly.




Δεν είναι δύσκολη για μικρά πραγματάκια να κάνεις... Με 4-5 γραμμές κώδικα / εντολές αρχίζεις και μπαίνεις στο νόημα της... 
Διαφορετικά πρέπει να μάθεις να δουλεύεις σε C (σαν γλώσσα προγραμματισμού) , και μετά να εφαρμόσεις αυτά που έμαθες σε mcu... 
Αυτή είναι η γνώμη μου..Δεν ξέρω ποιά γνώμη έχουν άλλοι φίλοι εδώ στο Hlektronika.gr :Smile:

----------


## stom

Αν αυτο που θες να κανεις ειναι σχετικα συνθετο, με την assembly πρεπει να γινεσαι πολυ αναλυτικος και δεν ειναι ιδιαιτερα παραγωγικο.
Και μιας και η ταση σημερα ειναι ποσο γρηγορα μπορεις να κανεις κατι πολυπλοκο, η γνωση μιας high level γλωσσας ειναι απαραιτητη, χωρις να σημαινει οτι και η assembly δεν εχει τις χαρες της...
Προσωπικα αν και στο παρελθον ειχα ασχοληθει με assembly 6502, Ζ80, 80x86 δεν χρειαστηκε να ασχοληθω με την assembly του avr μιας και με τη c καθαριζεις πολυ γρηγορα.

----------


## ALAMAN

Παιδιά, μια βοήθεια...
Την ώρα που ανοίγω νέο project και επιλέγω στον wizard συχνότητα 1MHz, τον τύπο του μικροελεγκτή (ATmega8515) και την θύρα της LCD (PORTB), στη συνέχεια πατάω generate program, save and exit. Τέλος εκεί που λέει place your code here βάζω τον παρακάτω κώδικα αλλα όταν πατάω build project μου βγάζει αυτό το error



```
Error: C:\AVR\giorgos.c(157): must declare first in block
```


Χρησιμοποίησα τον κώδικα που έδωσε ο stom στην πρώτη σελίδα.



```
/* 
  LCD Demo
  
  CodeVisionAVR C Compiler
  (C) 2000-2007 HP InfoTech S.R.L.
  www.hpinfotech.ro
  
  Chip: ATmega8515
  Memory Model: SMALL
  Data Stack Size: 128 bytes

  Use an 2x16 alphanumeric LCD connected
  to the STK500 PORTC header as follows:

  [LCD]   [STK500 PORTC HEADER]
   1 GND- 9  GND
   2 +5V- 10 VCC  
   3 VLC- LCD contrast control voltage 0..1V
   4 RS - 1  PC0
   5 RD - 2  PC1
   6 EN - 3  PC2
  11 D4 - 5  PC4
  12 D5 - 6  PC5
  13 D6 - 7  PC6
  14 D7 - 8  PC7
*/

// the LCD is connected to PORTC outputs
// see the file lcd.h in the ..\inc directory
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm

// include the LCD driver routines
#include <lcd.h>

void main(void)
{
// initialize the LCD for
// 2 lines & 16 columns
lcd_init(16);

// go on the second LCD line
lcd_gotoxy(0,1);

// display the message
lcd_putsf("Hello world");

// stop here
while (1);
}
```


Πατώντας διπλό κλίκ στο error μου βγάζει σφάλμα στην γραμμή "*void main(void)"*

----------


## stom

Ο κωδικας που σου εδωσα ειναι απο τα exampes του codevision και δεν τον βαζεις αυτουσιο στο put your code here!!!
Προφανως εχεις ορισει ΔΥΟ main, κατι που στη C δεν προβλεπεται.

----------


## ALAMAN

Παιδιά help!!  :Sad: 
Έγγραψα τον παρακάτω κώδικα στο codevisionAVR και σύνδεσα τον μικροελεγκτή στην οθόνη.
Στην αρχή καταλάθος σύνδεσα το Pin1 της οθόνης με την τροφοδοσία +5V και το pin2 με την γείωση, το ρεύμα αυξήθηκε απότομα σαν βραχυκύκλωμα!
Δεν έβγαλε καπνούς ούτε φάνηκε να κάηκε κάτι.
Με σωστή πολικότητα (pin1-GND, pin2-Vcc) η οθόνη δεν δούλεψε!!
Υπάρχει περίπτωση να κάηκε? ή μήπως υπάρχει πρόβλημα με τον κώδικα?
Το πρόγραμμα είναι:



```
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.2c Evaluation
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 28/7/2009
Author  : Freeware, for evaluation and non-commercial use only
Company : 
Comments: 


Chip type               : ATmega8515
Program type            : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 128
*****************************************************/

#include <mega8515.h>


#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include <stdio.h>
#include <delay.h>
char lcd_buffer[33];

void main(void)
{
 
PORTA=0xFF;
DDRA=0x00;


PORTB=0x00;
DDRB=0x00;

 
PORTC=0x00;
DDRC=0x00;


PORTD=0x00;
DDRD=0x00;

 
PORTE=0x00;
DDRE=0x00;


TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;


TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

MCUCR=0x00;
EMCUCR=0x00;


TIMSK=0x00;

ACSR=0x80;

// LCD module initialization
lcd_init(16);

while (1)
      {
      lcd_init(16);

lcd_clear();
sprintf(lcd_buffer,"hello]");
lcd_puts(lcd_buffer);
delay_ms(1000);
lcd_clear();

      };
}
```


Η θύρα που χρησιμοποίησα είναι η PORTB την οποία επέλεξα απο το wizard.
Όταν επιλέγω θύρα για την οθόνη απο το wizard πρέπει να την επιλέγω και ώς έξοδο απο την αντίστοιχη καρτέλα στο wizard? εγώ την επέλεξα μόνο απο την καρτέλα LCD.
To πρόγραμμα δεν έβγαλε σφάλμα και φορτώθηκε με επιτυχία στην flash του ATMega8515.
Η οθόνη ήταν δοκιμασμένη σε άλλη κατασκευή και λειτουργούσε (πριν καιρό).

Δοκίμασα να ανάψω σκέτη την οθόνη (μόνο τα leds) και δεν λειτουργούσε. Τόσο εύκολα καίγεται?

----------


## stom

Τωρα να σου πει καποιος με σιγουρια οτι δεν την εκαψες, οπως καταλαβαινεις ειναι κομματακι δυσκολο.
Ομως, εχεις βαλει ποτενσιομετρο για το contrast? Μηπως φταιει αυτό?

----------


## ALAMAN

> Τωρα να σου πει καποιος με σιγουρια οτι δεν την εκαψες, οπως καταλαβαινεις ειναι κομματακι δυσκολο.
> Ομως, εχεις βαλει ποτενσιομετρο για το contrast? Μηπως φταιει αυτό?



Γειώσα και το contrast (pin3).
Θα το δοκιμάσω αύριο με ποτενσιόμετρο και άν πάλι δεν ανάβει να πάρω άλλη.

----------


## tasosmos

Φτιαξε το ανταπτορακι που εχει στις κατασκευες για συνδεση με υπολογιστη μεσω παραλληλης και δοκιμασε την οθονη να εισαι βεβαιος αν δουλευει.

----------


## ALAMAN

> Φτιαξε το ανταπτορακι που εχει στις κατασκευες για συνδεση με υπολογιστη μεσω παραλληλης και δοκιμασε την οθονη να εισαι βεβαιος αν δουλευει.



Αυτήν την κατασκευή είχα κάνει παλιά και δούλευε!!
Αλλά δεν έπρεπε μόνο με μία τάση +5V να ανάβει η οθόνη? χωρίς τίποτα παραπάνω...

----------


## ALAMAN

Την εντολή if πώς μπορούμε να την χρησιμοποιήσουμε για κωδικοποίηση?
παράδειγμα...
Για τιμή της εισόδου PORTB, 00110111... η θύρα PORTD να δώσει 11100111 κλπ...
Προσπάθησα να γράψω (τυχαία νούμερα)
if (portb=128 ) then
portd=255
end if;
αλλα μου βγάζει σφάλμα για έλειψη ερωτιματικού ";"  :Confused1: 
ενώ δεν υπάρχει έλειμο ερωτιματικό...

----------


## ALAMAN

Το κυρίως πρόγραμμα είναι αυτό...



```
while (1)
      {
      int i;
      if (PORTA=128) {
      PORTB = 255 };
      };
}
```


 :Confused1:   :Confused1:   :Confused1: 

Και μια φωτο του σφάλματος...


Δεν μπορώ να καταλάβω που το βλέπει το έλειμο ερωτιματικό!

----------


## kopla

```
while (1)
{
     int i;
     if ( PORTA==128 )
     {
         PORTB = 255;
     }
}

```


*Δεν ξέρω αν θα δουλέψει αλλά δοκίμασέ το αν θες.*
- Το ερωτηματικό είναι στο 255 και όχι μετά το }
- Στο if εβαλα == αντί για =
- Το ερωτηματικό στο } του while το έβγαλα.

*edit*
Στη C ό,τι είναι μεταξύ { } είναι software block. Ο τετματισμός των εντολών γίνεται με ; άρα λογικά πάντα, αν αφήσεις τα ερωτηματικά στα κλεισίματα των while και if δεν θα πρέπει να υπάρχει πρόβλημα.

----------


## ALAMAN

ΟΚ δούλεψε αλλα υπάρχει ένα μικρό πρόβλημα.

Ο κώδικας είναι: 




```
while (1)
      {
      int i;
      if (PORTA=128) {PORTB=128;
    }
else  {PORTB=32;    
    };

      };
}
```


Σύμφωνα με το παραπάνω πρόγραμμα όταν η θύρα Α είναι 10000000 (δηλαδή ενεργοποιείται το πιν 7) η θύρα Β ενεργοποιεί στην προκειμένη περιπτωση το αντίστοιχο πιν, το 7.
Διαφορετικά!
Η θύρα Β θα παρει την τιμη 00100000, δηλαδή ενεργοποιείται το πιν 5.
Οταν το προγραμμα τρέχει πάνω στον STK500 χωρίς να πατηθεί κάποιο πλήκτρο για τη θύρα Α, η έξοδος θύρα Β δίνει τον κωδικό 01111111 (αντίθετη λογική!) που σημαίνει οτι αυτό έπρεπε να το βγάζει *μόνο!* όταν πατηθεί το πλήκτρο πιν7 το οποίο δεν είναι πατημένο.... !

----------


## ALAMAN

Δοκίμασα να αλλάξω λίγο τις τιμές των θυρών.
Και νομίζω πως υπάρχει πρόβλημα στην παρακάτω γραμμή...



```
while (1)
{
if (PORTA=128) {
PORTB=64;}
else
{PORTB=32;}
}
}
```

----------


## kopla

Έχεις ενα παραπανω } το τελευταίο δηλαδή.
Θεωρώ λάθος το =  στο if. Θέλει == όταν κανεις ελεγχο ισότητας. Αλλιώς κανει ανάθεση. Το μηδέν είναι false και όλα τα άλλα true. Τσέκαρέ το.

Ο κώδικας είναι C αλλά δεν ξέρω αν έχει κληρονομίσει τα πάντα από τη C. Για παράδειγμα, για μία μόνο εντολή σε if/else/for/while μπορείς να παραλέιψεις τα *{*_εντολή_;*}*. Μήπως το ενοχλούν τα {} στη μία εντολή?

Καλό θα είναι και κάποιο σχηματικό. ΠΧ τα buttons, πως είναι συνδεδεμένα? Όταν δεν είναι πατημένο καποιο, το αντίστοιχο pin τι διαβάζει? "1" ή "0"

----------


## Mihos

> Δοκίμασα να αλλάξω λίγο τις τιμές των θυρών.
> Και νομίζω πως υπάρχει πρόβλημα στην παρακάτω γραμμή...
> 
> 
> 
> ```
> while (1)
> {
> if (PORTA=128) {
> ...



 
Αρχικά πρέπει να αλλάξεις το *PORTA=128* με *PINA* == 128. Στη C όταν γράφεις PORTA = 128 τότε αυτό που γίνεται στη πραγματικότητα είναι να κατάχωρείται στη PORTA η τιμή 128. Δεν γίνεται σύγκριση αλλά καταχώρηση (ακόμα και αν το γράφεις εντός των παρενθέσεων της if). Τώρα όλη η παράσταση PORTA = 128 έχει μία τιμή η οποία είναι το 128. Όταν εντός των παρενθέσεων της if βάζεις κάτι που είναι διάφορο του 0 τότε αυτό παίζει το ρόλο του TRUE. Επομένως στον κώδικά σου το σκέλος που θα εκτελείται πάντα είναι το PORTB = 64. 

Επίσης επειδή προσπαθείς να διαβάσεις από την PORTA θα πρέπει πρώτα να έχεις βάλει την εντολή DDRA = 0; Έτσι δηλώνεις ότι η πόρτα A θα χρησιμοποιείται ως είσοδος. Τώρα τον έλεγχο της τον κάνεις μέσω του PINA αφού το PORTA παίζει πλέον τον ρόλο των pull up αντιστάσεων. 
Αντίθετα, η πόρτα Β που παίζει τον ρόλο εξόδου θα πρέπει να έχει αρχικοποιηθεί με την εντολή DDRB = 0xFF;.

Αν τώρα χρησιμοποιείς κάποιο Board όπως το STK500 έχε υπόψη σου ότι τα LEDS έχουν αρνητική λογική. Δηλαδή το 01111111 που λες ότι βλέπεις είναι στη πραγματικότητα 1000000 δηλαδή το 64. Το ίδιο ισχύει και με τα Buttons. Αν δεν πατάς κανένα, είναι σα να τα θέτεις όλα στο 1. Αν πατήσεις κάποιο το θέτεις στο 0. Ένας πιο κομψός και σωστός τρόπος να γράψεις τον κώδικα σου είναι ο παρακάτω:




```
while (1) {
    if (PINA == 128)
        PORTB = 64;
    else
        PORTB = 32;
}
```


Και πάλι όμως το τεστάρισμα θα είναι δύσκολο αφού θα πρέπει να πατήσεις με τα δάκτυλα σου και τα 7 λιγότερο σημαντικά buttons για να εξασφαλίσεις ότι όντως η τιμή τους θα είναι x0000000 (η αρνητική λογική που λέγαμε...). Καλύτερα είναι να κάνεις το παρακάτω:




```
while (1) {
    if (PINA && 128)
        PORTB = 64;
    else
        PORTB = 32;
}
```


Έτσι ελέγχεις μόνο το 8o bit χωρίς να σε ενοχλεί οι κατάσταση των άλλων bit. (Ο τελεστής && είναι ο τελεστής AND σε επίπεδο bit).

Αν κάτι από όσα λέω είναι δυσνόητο ρώτα μέ :Smile:

----------


## ALAMAN

Σας ευχαριστώ πολύ όλους για τις απαντήσεις!  :Biggrin: 
Φίλτατε Mihos, πρίν την εντολή while στην αρχηκικοποίηση των θυρών υπάρχει η εντολή PORTA=0x00; και απο κάτω, DDRA=0x00; και για την θύρα Β υπάρχει το PORTB=0x00; και το DDRB=0xFF;
Τό μόνο όμως που δεν μπορώ να καταλάβω είναι γιατί πρέπει να χρησιμοποιήσουμε τον όρο PINA και όχι PORTA.
Επίσης τί σημασία έχουν οι 3 όροι, PINA, PORTA, και DDRA ??  :Unsure: 

Όντως έχεις απόλυτο δίκιο για τον συμβολισμό "=", νόμιζα οτι μέσα στην if δεν θα παίξει τον ρόλο της καταχώρησης.

Όσον αφορά αυτό με την αρνητική λογική, στο wizard του codevision παρατηρώ στην καρτέλα PORTS οτι στις εισόδους έχει κάποια επιλογή
P και T (pullup και toggle).
Τί σημασία θα παίξουν αυτά στο πρόγραμμα?
Εγώ θέλω η είσοδος να ενεργοποιείται (λογικό 1) όταν σε κάποιο πιν υπάρχει τάση, 5V, δηλαδή 1.


Ομοίως στις εξόδους δεξιά (στην θέση των P, T) υπάρχει μια στήλη με 0 και 1.
Τί ρόλο παίζουν και αυτά εδώ?
Μήπως είναι αρχικικοποίηση της θύρας? να τα θέσει σε κάποια στάθμη? 0 ή 1?

Όταν έβγαλα τον μικροελεγκτή (ATMega8515) και το έβαλα σε ράστερ παρατήρησα πάλι αντίθετη λογική.
Δηλαδή το 128 το είχε ως 01111111.

Το τελευταίο με τον τελεστή AND δεν θα με βοηθήσει στο τελικό πρόγραμμα γιατί εγώ θέλω να κάνω μια μικρή κωδικοποίηση/αποκωδικοποίηση με τις if.
Δηλαδή για τιμή 11100010 η θύρα Β να δώσει 00110010 κλπ κλπ...
Και όλο αυτό με 250 if ! για 250 διαφορετικούς συνδυασμούς!

----------


## Mihos

Οι όροι DDRx (όπου x μπορεί να είναι A,B,C...) είναι οι καταχωρητές στους οποίους ορίζουμε αν μία πόρτα θέλουμε να χρησιμοποιηθεί ως έξοδος ή ως είσοδος. Πχ DDRA = 0b11110000; σημαίνει ότι τα 4 περισσότερο σημαντικά bit της πόρτας θα χρησιμοποιηθούν ως έξοδοι και τα 4 λιγότερο σημαντικά ως είσοδοι. (0: είσοδος, 1:έξοδος). Το 0xFF είναι ο συμβολισμός του 11111111 στο δεκαεξαδικό (συνήθως χρησιμοποιούμε το 16δικό για λακωνικότητα). Έτσι η εντολή DDRB = 0xFF; σημαίνει ότι όλα τα bits της πόρτας θα χρησιμοποιηθούν ως έξοδοι.

Οι όροι PORTx έχουν διπλή σημασία. 
*Αν το αντίστοιχο bit κάποιας πόρτας έχει ορισθεί ως έξοδος (μέσω της DDRx) τότε η τιμή της PORTx (στο συγκεκριμένο bit) είναι αυτή που καθορίζει την τάση του αντίστοιχου pin στον μικροελεγκτη (1 = 5V, 0 = 0V).  
*Αν το bit έχει ορισθεί ως είσοδος, τότε το PORTx ορίζει αν θα συνδέσουμε pull up αντίσταση στην είσοδο του κάθε pin ή όχι (1 = Συνδεδεμένη pull up, 0 = Χωρίς pull up). Οι AVR διαθέτουν εσωτερικά προεραιτικές αντιστάσεις pull up. Επομένως δε έχει άμεση σχέση με τη τάση που εφαρμόζουμε στα pin κάποιας πόρτας.

Οι όροι PINx είναι όροι ανάγνωσης μόνο. Δεν μπορούμε να τους δώσουμε κάποια τιμή ή αν τους δώσουμε θα έχουμε απρόβλεπτα αποτελέσματα. Μπορούμε μόνο να τους διαβάσουμε.

*Αν η αντίστοιχη πόρτα έχει ορισθεί σαν έξοδος, τότε η τιμή του PINx ταυτίζεται συνήθως με τη τιμή του PORTx (για την ακρίβεια έπαιται με καθυστέρηση ενός κύκλου).
*Αν η πόρτα έχει ορισθεί ως έίσοδος* η τιμή του PINx αντικατοπτρίζει τη τάση που έχουμε εφαρμόσει στο pin* του μικροελεγκτή (1=5V, 0=0V).

Τώρα όσον αφορά τον wizard που χρησιμοποιείς δεν μπορώ να σου πώ κάτι με σιγουριά καθώς δεν έχω χρησιμοποιήσει το συγκεκριμένο πρόγραμμα ποτέ μου. Υποθέτω όμως ότι ανάλογα με της επιλογές σου στα checkboxes παράγει αυτόματα για εσένα τις εντολές DDRx = κάτι και PORTx = κάτι. Δεν νομίζω ότι κάνει κάτι πιο εξειδικευμένο...

Το ότι σου έβγαλε αρνητική λογική και στο breadboard μου φαίνεται πολύ περίεργο.

Τέλος, αν θέλεις να φτιάξεις έναν "αποκωδικοποιητή" για τόσο πολές τιμές είναι πιο βολικό να χρησιμοποιήσεις τη δομή switch της C παρά πολλά διαδοχικά if ... else ... Η switch παράγει και πιο αποδοτικό τελικό κώδικα. 
Αυτά :Rolleyes:

----------


## ALAMAN

Τί διαφορά θα παίξει η switch απο την if σε ένα τέτοιο πρόγραμμα?
Για την αντίθετη λογική η οποία δεν με απασχολεί ιδιαίτερα μπορεί να χρησιμοποιήσω κάποιο ολοκληρωμένο με πύλες NOT !  :Wink: 

Επίσης στο πρόγραμμα θέλω να ενσωματώσω και κάποιες ρουτίνες.
Το πρόγραμμα θα το χρησιμοποιήσω σε μέτρηση θερμοκρασίας για απεικόνηση σε LCD. Θα ήθελα όμως πρώτα να καταλάβω τί γίνεται με τις εισόδους/εξόδους στην C++.
Απο εκεί και πέρα διάφορες ρουτίνες που θα διαβάζουν την είσοδο θα εκτελούντε ανάλογα πάντα με την τιμή που θα υπάρξει στην είσοδο.
Αυτό ίσως να μπορούσε να γίνει με switch.
Για παράδειγμα θα μπορούσαμε να ενεγοποιήσουμε μία άλλη έξοδο πχ την θύρα C, όταν η τιμή του byte γίνει μεγαλύτερη ή ίση με 192 δηλαδή 11000000.

----------


## Mihos

> Τί διαφορά θα παίξει η switch απο την if σε ένα τέτοιο πρόγραμμα?



Μάλλον δε κατάλαβα καλά εγώ...
Αν θέλεις να κάνεις ελέγχους του στυλ PINA > x ή με άλλους σχεσιακούς πέραν της απλής ισότητας (πχ >=, !!, &&) τότε τα if είναι μονόδρομος. Αν όμως θέλεις να ελέγχεις την ισότητα με διάφορες τιμές:





> ...εγώ θέλω να κάνω μια μικρή κωδικοποίηση/αποκωδικοποίηση με τις if.
> Δηλαδή για τιμή 11100010 η θύρα Β να δώσει 00110010 κλπ κλπ...
> Και όλο αυτό με 250 if ! για 250 διαφορετικούς συνδυασμούς!



τότε η switch είναι πιο βολική καθώς αυτό:




```
switch (PINA) {
    case 1: κάνε κάτι
    case 2: κάνε κάτι άλλο
    case 3: ...
}
```


είναι πολύ πιο σύντομο από αυτό:




```
if (PINA == 1) {
    κάνε κάτι
}
else if (PINA == 2) {
    κάνε κάτι άλλο
}
else if ...
```


Και εκτός από το ότι είναι πιο σύντομο παράγει και μικρότερο κώδικα. Σου εξοικονομεί χώρο στη flash. :Wink: 





> ...Για την αντίθετη λογική η οποία δεν με απασχολεί ιδιαίτερα μπορεί να χρησιμοποιήσω κάποιο ολοκληρωμένο με πύλες NOT !



Δεν υπάρχει λόγος :Smile: . Μπορείς απλά αντί να γράφεις PORTB = x να γράφεις PORTB = ~x (~: Τελεστής αντιστροφής bit). Αυτό εξάλου είναι το νόημα των μικροελεγκτών. Να μας κάνουν τη ζωή εύκολη :Wink: .

Αν και νομίζω ότι για να σου βγάζει αντίστροφες τιμές το AVR κάτι δε πάει κάλα... Ψάξτο καλού κακού...

----------


## ALAMAN

ΟΚ κατάλαβα!!!  :Smile: 
Θα πειραματιστώ λίγο ακόμα με τις θύρες.
Μετά όλες αυτές τις if μπορούμε να τις χρησιμοποιήσουμε μαζί με την βιβλιοθήκη lcd.h για να απεικονίζουμε την τιμή (δεκαδικός αριθμός) στην οθόνη?

----------


## Mihos

Προφανώς. Μέσα στα if μπορείς να βάλεις κλίσεις των συναρτήσεων που παρέχει το lcd.h .

----------


## ALAMAN

> Προφανώς. Μέσα στα if μπορείς να βάλεις κλίσεις των συναρτήσεων που παρέχει το lcd.h .



ΟΚ θα χρειαστώ βοήθεια όμως γιατί πρώτη φορά ασχολούμε με C++.
Ευχαριστώ πολύ!  :Rolleyes:

----------


## stom

Που την ειδες την C++?

----------


## ALAMAN

> Που την ειδες την C++?



Γιατί τί γλώσσα είναι?

----------


## Mihos

Η γλώσσα βασικά είναι C. Σκέτο.
Αν και νομίζω υπάρχει compiler C++ για AVR.

----------


## ALAMAN

> Η γλώσσα βασικά είναι C. Σκέτο.
> Αν και νομίζω υπάρχει compiler C++ για AVR.



Ναί αλλα στην C++ δεν περιέχονται και εντολές της C ?

----------


## Mihos

Κάπως έτσι είναι :Biggrin: ...

http://en.wikipedia.org/wiki/Compati..._C_and_C%2B%2B

Παρ' όλα αυτά η γλώσσα που χρησιμοποιείς είναι η C.

----------


## ALAMAN

Στον compiler CodeVisionAVR εντολές της C++ δεν τις τρέχει?

----------


## stom

Οχι.
Η C++ ειναι object oriented και ειναι μαλλον για αλλες δουλειες.
Υποτιθεται οτι στα embedded συστηματα ειναι θεμιτο να ειμαστε σχετικα "κοντα" στη μηχανη και να ξερουμε τι γινεται ακριβως. (αυτο επιτυγχανεται πληρως με την assembly)ομως για πολυπλοκα πραγματα μια γλωσσα "υψηλης ραπτικης"  :Very Happy:  οπως η C μας κανει πολυ πιο παραγωγικους.
H c++ μαλλον θα εστελνε την μπαλα στα μνυματα.
Ισως σε ενα 32bit atmel περιβαλλον, με υπαρξη real time operating system μια C++ να εχει αρκετο νοημα.
Παντως χωρις παρεξηγηση αγαπητε alaman, ενα βιβλιαρακι για C το χρειαζεσαι....

----------


## ALAMAN

> Παντως χωρις παρεξηγηση αγαπητε alaman, ενα βιβλιαρακι για C το χρειαζεσαι....



βιβλίο για C και βέβαια χρειάζομαι, αλλα δεν ξέρω ποιό...
Έχετε να προτείνεται κάτι? Σε ελληνικά βέβαια

----------


## ALAMAN

> Οχι.
> Η C++ ειναι object oriented και ειναι μαλλον για αλλες δουλειες.
> Υποτιθεται οτι στα embedded συστηματα ειναι θεμιτο να ειμαστε σχετικα "κοντα" στη μηχανη και να ξερουμε τι γινεται ακριβως. (αυτο επιτυγχανεται πληρως με την assembly)ομως για πολυπλοκα πραγματα μια γλωσσα "υψηλης ραπτικης"  οπως η C μας κανει πολυ πιο παραγωγικους.
> H c++ μαλλον θα εστελνε την μπαλα στα μνυματα.
> Ισως σε ενα 32bit atmel περιβαλλον, με υπαρξη real time operating system μια C++ να εχει αρκετο νοημα.



Θέλεις να πείς οτι η γλώσσα C προσεγγίζει περισσότερο την γλώσσα μηχανής απ' ότι η C++ ??

----------


## stom

Για ελληνικα δεβ ξερω τι κυκλοφορει, σιγορυα οχι πολλα παντως.
Θα υπαρχει το κλασσικο The C Programming Language  by Brian Kernighan and Dennis Ritchie αλλα απο κει και περα....

Οσο για τη C++ θα ελεγα οτι ΔΕΝ προσεγγιζει καν το κλασσικο τροπο ππρογραμματισμου και στηριζεται σε πολυ μεγαλο βαθμο σε ετοιμα πραγματα που απλως τα καλεις.... Ιδανικό για μεγαλα και πολυπλοκα πραγματα, καταστροφικο μαλλον για πολυ μικρες μηχανες οπως οι mc.

----------


## ALAMAN

Στο παπασωτηρίου βρήκα αρκετά καλά και σχετικά φθηνά βιβλία αλλα δεν ξέρω τους συγγραφείς για να επιλέξω κάποιο καλό.  :Unsure:

----------


## tasosmos

Καλο βιβλιο imo ειναι το "Πληρες εγχειριδιο της C" εκδοσεις Γκιουρδας, δεν θυμαμαι τωρα συγγραφεα.

----------


## ALAMAN

Μάλλον ενοείς αυτό: http://www.papasotiriou.gr/product.g...=803432&deid=0 φαίνετε αρκετά καλό.
Τις γνώσεις που παίρνει κάποιος απο αυτά τα βιβλία θα μπορεί να τις χρησιμοποιήσει πάνω σε μικροελεγκτές?

Τί λέτε και γιαυτά τα 2?
http://www.papasotiriou.gr/product.g...d=17082&deid=0
http://www.papasotiriou.gr/product.g...=253730&deid=0

----------


## ALAMAN

Διόρθωσα το πρόγραμμα:




```
while (1)
      {

      if (PORTA == 247) {
      PORTB = 128;}
      else {
      PORTB = 32;}

      };
}
```


Τώρα, όταν το bit3 της θύρας Α γίνει 0 (11110111) η έξοδος θα δώσει 10000000. Διαφορετικά η έξοδος θα δώσει 00100000.
Δυστηχώς όμως κάνει πάλι το ίδιο είναι σαν να αγνοεί την είσοδο θέτοντας απλα μια κατάσταση στην έξοδο.
Το δοκίμασα και στο ράστερ με αντιστάσεις Pull up (10kΩ).
Η μόνη εντολή που φαίνετε να εκτελείται είναι η else. με έξοδο 00100000 (με αντίθετη λογική!)

Ορίστε και το κύκλωμα της εισόδου.

----------


## Mihos

Δεν είπαμε ότι χρησιμοποιούμε για είσοδο το *PINA* και όχι το *PORTA*???

----------


## ALAMAN

> Δεν είπαμε ότι χρησιμοποιούμε για είσοδο το *PINA* και όχι το *PORTA*???



Σωστά! Αυτο το είχα ξεχάσει.  :Bored: 
Τώρα δουλεύει!!!  :W00t: 
Σ' ευχαριστώ πολύ για την παρατήρηση!  :Rolleyes:

----------


## ALAMAN

Το δεκαεξαδικό και το δεκαδικό πιάνουν τον ίδιο χώρο στην flash ή μου φαίνετε?

----------


## Mihos

Στη Flash δεν υπάρχει δεκαδικό και δεκαεξαδικό... Στη Flash όλα είναι 0 και 1 δηλαδή διαδικό... Το δεκαδικό και το δεκαεξαδικό είναι διαφορετικοί τρόποι για να συμβολίσουμε εμείς οι άνθρωποι τους αριθμούς. 

Αυτό 0x13, αυτό 0b00010011 και αυτό 19 είναι ακριβώς το ίδιο.

----------


## ALAMAN

Δηλαδή στην συγγραφή του προγράμματος ότι και να γράψω αυτό θα μετατραπεί σε δυαδικό ??

----------


## Mihos

Όλος ο κώδικας μετατρέπεται σε γλώσσα μηχανής. Η γλώσσα μηχανής δεν είναι τίποτα άλλο παρά αριθμοί που αποθηκεύονται στη Flash και όπως όλα τα ψησφιακά συστήματα του κόσμου η Flash κρατά δεδομένα σε διαδική μορφή... 

Δηλαδή ναι... Τα πάντα μετατρέπονται σε 0 και 1. Αυτή είναι η δουλειά του μεταγλωττιστή (Για την ακρίβεια πρώτα δημιουργείται κώδικας Assemply μετά μετατρέπεται σε ένα αρχείο *.hex και τέλος ο προγραμματιστής του AVR το φορτώνει στη Flash σε διαδική μορφή).

edit: Νομίζω ότι έχουμε ξεφύγει τελείως από το θέμα όμως. 100% offtopic. Π τίτλος θα έπρεπε να είναι "Τα βασικά για τους μΕ..." :Rolleyes:  :Rolleyes:  :Unsure:

----------


## stom

Φυσικά... Και για να κανεις τη ζωη σου λιγακι ευκολοτερη, χρησιμοποιησε εντολες του τυπου if pinA.3 ==1 (το 3ο bit -αρα και το αντιστοιχο φυσικο pin) 
και για τις εξοδους portΒ.7 = 1 (το 7ο bit της πορτας Β..)

Οσο για βιβλιο, το τελευταιο που προτινες σιγουρα οχι, το μεσαιο δεν υπαρχει και το πρωτο ειναι μαλλον ακριβό.
Το μονο που χρειαζεσαι ειναι να καταλαβεις λιγακι τις βασικες δομες της C.

Απο κει και περα λιγα εχουν να πουν τα γενικα βιβλια για το κοσμο της codevision και των atmel.

Σιγουρα αγγλικα ΔΕΝ?

ΥΓ Θα συμφωνησω για το offtopic, αλλά πρωτου τρεξεις, πρεπει να περπατησεις, και εδω μπουσουλαμε.

----------


## ALAMAN

> Φυσικά... Και για να κανεις τη ζωη σου λιγακι ευκολοτερη, χρησιμοποιησε εντολες του τυπου if pinA.3 ==1 (το 3ο bit -αρα και το αντιστοιχο φυσικο pin) 
> και για τις εξοδους portΒ.7 = 1 (το 7ο bit της πορτας Β..)
> 
> Οσο για βιβλιο, το τελευταιο που προτινες σιγουρα οχι, το μεσαιο δεν υπαρχει και το πρωτο ειναι μαλλον ακριβό.
> Το μονο που χρειαζεσαι ειναι να καταλαβεις λιγακι τις βασικες δομες της C.
> 
> Απο κει και περα λιγα εχουν να πουν τα γενικα βιβλια για το κοσμο της codevision και των atmel.
> 
> Σιγουρα αγγλικα ΔΕΝ?
> ...



Αυτός ο τρόπος συγγραφής θα μου βγάλει αρκετές σειρές κώδικα  :Bored: 
Καλύτερα να τα γράφω σε δεκαδικό ή δεκαεξαδικό.

Όχι αγγλικά βιβλία.

----------


## Mihos

stom είσαι σίγουρος ότι μπορείς να γράψεις κάτι τέτοιο στη C (για τη τελεία μιλάω)? Ειληκρινά το βλέπω πρώτη φορά :Blink: . Εγώ θα έγραφα αντίσοιχα if (PINA && 1<<3) και PORTB = PORTB || (1<<7).

----------


## stom

Σε winavr και γω ετσι θα το γραφα.. Ειναι codevision "feature"
Ενα παραδειγμα εδω, που βρηκα προχειρο.. 



```
int ledflash(int duty)
    {
      switch (duty)
      {
      case 1:  { if (msec>lastflash+999) {lastflash=msec; PORTB.1=0;}
                  if (msec>lastflash+100) { PORTB.1=1; };
               }
               break;
      case 2:   { if (msec>lastflash+999) {lastflash=msec; PORTB.1=1;}
                  if (msec>lastflash+100) { PORTB.1=0; };
               }
               break; 
      case 3:   { if (msec>lastflash+999) {lastflash=msec; PORTB.1=1;}
                  if (msec>lastflash+500) { PORTB.1=0; };
               }
               break;  
      case 4:   { if (msec>lastflash+999) {lastflash=msec; PORTB.1=1;}
                  if (msec>lastflash+10) { PORTB.1=0; };
                  if (msec>lastflash+490 && msec <(lastflash+500)) { PORTB.1=1;}
                  if (msec>lastflash+10 && msec <(lastflash+490))  { PORTB.1=0; };
               }
               break;                    
       }               
 return 0; }
```


Ασε το optimization για (πολυ) αργοτερα, εαν και εφοσον σου χρειαστει.
Οπως και να το γραψεις ο compiler κανει απο μονος του μπολικο optimization..

----------


## ALAMAN

Για κάθε ένα συνδυασμό της εισόδου χρειάζομαι 6 γραμμές κώδικα για κωδικοποίηση (για να ανάψουν 3 display με έναν αριθμό πχ. 15,5!).



```
if (PINA = ...) {
PORTB = ....
delay
PORTB = ......
delay 
PORTB = ........ }
```


Δηλαδή για 230 τιμές περίπου θα χρειαστεί να γράψουμε 1380 γραμμές κώδικα !!!  :Blink:  :Bored: 

Θα χωρέσει ένα τέτοιο πρόγραμμα μέσα στην flash του ATMEGA8515 ??  :Confused1:

----------


## stom

Υποψιαζομαι πως ναι.
Περαν αυτου, αυτο που περιγραφεις, μαλλον δεν πρεπει να το κανεις οπως το σκεφτεσαι..
Μια πιθανη προσεγγιση ειναι ενα array με τις απαιτουμενες τιμες εξοδου, και την εισοδο σαν index.
Το γεμισμα της array θα ειναι μεγαλο πριν το compliation, μετα ομως θα ειναι πολυ λιγο.

----------


## ALAMAN

Τον Σεπτέμβριο θα πάω να πάρω άλλη LCD και θα κάνω δοκιμές με αυτήν, θα βγεί πολύ μικρότερος κώδικας!

Αυτό το array που λές δεν το καταλαβαίνω...
Τί ακριβώς είναι?

----------


## ALAMAN

Τί λέτε για τον ATmega32A ???
Έχει 32kB μνήμη flash, απ' ότι λέει η atmel... http://www.atmel.com/dyn/resources/p...ents/8155S.pdf

Κάτι άλλο που δεν καταλαβαίνω είναι ο 10bit ADC. Γιατί είναι 10bit αφού οι καταχωρητές του μικροελεγκτή είναι 8bit ??
Ακόμα και αν χρειαστούμε να πάρουμε την δυαδική τιμή ψηφιακά απο τις εξόδους με 8bit διάδρομο θα την πάρουμε.

----------


## kopla

Το αποτελεσμα θα είναι σε 2 καταχωρητές.

----------


## ALAMAN

Άν όμως θέλουμε η τιμή να βγεί σε κάποια θύρα... πχ PORTB θα χαθούν bits !!  :Huh:

----------


## kopla

Γιατί να χαθεί?
8 bits δεν εχουν και οι πόρτες στους AVR ?

Θα πρεπει τα αλλα 2 bit να τα γραψεις σε αλλη πορτα

----------


## ALAMAN

Ναί αλλα η πληροφορία απο την μετατροπή του ADC είναι 10bit.
τα υπόλοιπα 2??

EDIT:




> Γιατί να χαθεί?
> 8 bits δεν εχουν και οι πόρτες στους AVR ?
> 
> Θα πρεπει τα αλλα 2 bit να τα γραψεις σε αλλη πορτα



Ίσως για την δουλεία που το θέλω να με χρησιμεύσει ο ADC.
Τώρα που το ξανασκέυτομαι δε νομίζω να χρειάζετα να βγούν και τα 10bit στην έξοδο της θύρας που θα συνδεθεί η LCD.
Στα display θα είχαμε πρόβλημα με μία θύρα (8bit) αλλα στην LCD δε νομίζω...

Πώς ενεργοποιήται ο ADC ??

----------


## kopla

Εκανα γρήγορο edit γιατί η ερώτηση μου ήταν ακυρη εντελώς.
*Θα πρεπει τα αλλα 2 bit να τα γραψεις σε αλλη πορτα*

Υπάρχουν 2 προσεγγίσεις.
1. 10bit αποτελεσμα οπότε θες 10 bits
2. Από το 10μπιτο αποτελεσμα να κρατήσεις τα 8 πιο σημαντικά bits (τα οποίο πολύ απλά τα δείχνεις σε μια ολόκληρη πόρτα). Τα 2 bits που θα παραλείψεις θα σου εισαγουν ενα σφάλμα 2^2=4 θέσεις.

ΠΧ

   reg1          reg0
xxxx.xx*00 0000.00*00  \
xxxx.xx*00 0000.00*01  \
xxxx.xx*00 0000.00*10  /
xxxx.xx*00 0000.00*11 /
xxxx.xx*00 0000.01*00


Οι reg1 και reg0 είναι οι καταχωρητές που θα εχουν το A2D αποτελεσμα. Δεν ξέρω πιο είναι το πραγματικό τους όνομα γιατι δεν ασχολούμαι με ATMEL.
Να το σφάλμα. Είτε διαβαστει το 0,1,2 ή το 3, εσύ θα πάρεις 0. Σου εχω σημειώσει με *bold* τα 8 πιο σημαντικά μπιτ.
Από το 4 και μετα (00000100) εχουμε αλλαγή που θα αντικατοπρισθεί στην εξοδο (καποια πορτα). Μιλάω για το *κοκκινο 1

edit
*Για να κανω πιο πλήρες το ποστ....
Αν φυσικά κρατήσεις τα 8 λιγότερο σημαντικά bit τοτε κερδίζεις σε ακρίβεια αλλά χανεις σε ευρος. (διά 4 δηλαδή)

----------


## kopla

Ti θες να κανεις με το AD και το display με μια LCD ?
Για να καταλάβω το προβλημα "_Στα display θα είχαμε πρόβλημα με μία θύρα (8bit) αλλα στην LCD δε νομίζω..._"

----------


## stom

Μας εχεις μπερδεψει σιγουρα.
Ενα A/d 10 bit δινει τιμες απο 0 μεχρι 1023. (σε 2 καταχωρητες, 8bits +2)
Το lcd display απεικονιζει χαρακτηρες που συνηθως τις διαβαζουν ανθρωποι, οποτε μαλλον με 4 ψηφια μπορεις να δειξεις ολες τις τιμες του 10bit adc. στο δεκαδικο συστημα..

----------


## ALAMAN

> Ti θες να κανεις με το AD και το display με μια LCD ?
> Για να καταλάβω το προβλημα "_Στα display θα είχαμε πρόβλημα με μία θύρα (8bit) αλλα στην LCD δε νομίζω..._"



Απεικόνηση θερμοκρασίας.
Επειδή δεν γνωρίζω απο μικροελεγκτές χρησιμοποίησα έναν ξεχωριστό ADC με έξοδο 8bit. Αναγκαστικά επέλεξα θερμοκρασία με εύρος -20 εως 90 βαθμοί με βήμα 0,5. Δηλαδή περίπου 220 τιμές.
Μια λέξη όμως με μήκος 10bit, όπως ο ενσωματομένος ADC του AVR θα με βοηθούσε ακόμα παραπάνω ώστε να μπορώ να έχω ένα εύρος απο -15 εως 90 βαθμούς αλλα με βήμα 0,1 ! που σημαίνει τεράστια ακρίβεια.
Και το σημαντικότερο είναι οτι θα μου μείνουν διαθέσιμα πινς για άλλες εργασίες! 

Επίσης με την LCD μπορείς να κάνεις πολύ περισσότερα πράγματα απ' ότι στα display.

----------


## Mihos

ALAMAN το καλύτερο που μπορείς να κάνεις για να καταλάβεις πως λειτουργούν γενικώς οι AVR και τα διάφορα περιφεριακά τους είναι να κατεβάσεις το Datasheet του μοντέλου που σε ενδιαφέρει και να το μελετήσεις προσεκτικά. Έκεί θα βρείς όλες τις πληροφορίες που θέλεις και συνήθως και παραδείγματα κώδικα. Και αν το Datasheet σου φανεί πολύ δύσκολο στην ανάγνωση, τότε πάρε ένα εισαγωγικό βιβλίο :Wink: .

Όπως καταλαβαίνεις μέσα από το forum είναι δύσκολο να καταλάβεις τι παίζει μόνο και μόνο από τα postings των συναδέλφων...

Σου έυχομαι πάντως καλή αρχή με τους μE. Θα νιώσεις μεγάλη δημιουργηκότητα αν ασχοληθείς τελικά :Rolleyes: ! Αξίζει.

----------


## ALAMAN

> ALAMAN το καλύτερο που μπορείς να κάνεις για να καταλάβεις πως λειτουργούν γενικώς οι AVR και τα διάφορα περιφεριακά τους είναι να κατεβάσεις το Datasheet του μοντέλου που σε ενδιαφέρει και να το μελετήσεις προσεκτικά. Έκεί θα βρείς όλες τις πληροφορίες που θέλεις και συνήθως και παραδείγματα κώδικα. Και αν το Datasheet σου φανεί πολύ δύσκολο στην ανάγνωση, τότε πάρε ένα εισαγωγικό βιβλίο.
> 
> Όπως καταλαβαίνεις μέσα από το forum είναι δύσκολο να καταλάβεις τι παίζει μόνο και μόνο από τα postings των συναδέλφων...
> 
> Σου έυχομαι πάντως καλή αρχή με τους μE. Θα νιώσεις μεγάλη δημιουργηκότητα αν ασχοληθείς τελικά! Αξίζει.



Ευχαριστώ! Έχω καταλάβει κάποια πράγματα για τους μικροελεγκτές και την γλώσσα αν και νομίζω πως ακόμα δεν έχω φτάσει ούτε στην αρχή!  :Tongue2: 

Προς το παρόν θα συνεχίσω να φτιάχνω αυτό που άρχισα και μόλις τελειώσω θα προχωρίσω πιο βαθιά, θα βρώ και κάποιο καλό βιβλίο για τη C.

----------


## stom

Εγω θα ελεγα να ξεχασεις τον 8515 και να παιξεις με εναν atmega32 που εχει μεσα του 8 αναλογικες πορτες των 10 bit. Και ευκολοτερο ειναι και καλυτερα θα δουλεψει.
Οσο για τις τιμες, προφανως και δεν θα τις κανεις με if...
Η ταση που μετρας δινεται απο τυπο adc=(vin-1024)/Vref
Οποτε με λιγες αριθμητικες πραξεις εχεις τη θερμοκρασια ετοιμη και τη στελνεις στο display.
Με το ζορι 1 σελιδα κωδικας ολο μαζι.

----------


## ALAMAN

Παιδιά μια ακόμα βοήθεια....
Έχω φτιάξει ένα πρόγραμμα όμοιο με το προηγούμενο (αποκωδικοποιητής)
Στην αρχή όμως του προγράμματος έχω προσθέσει έναν μετρητή ο οποίος μετράει και αποθηκεύει την τρέχουσα τιμή σε μία μεταβλητή x.
Το πρόβλημα τώρα είναι οτι απο κάτω υπάρχει μια if για την ανάγνωση της εισόδου η οποία δεν εκτελείται ποτέ!
Ο μετρητής αυξάνει μηδενίζει και αρχίζει ξανά... Το πρόγραμμα απορίπτει εντελώς τις επόμενες γραμμές του κώδικα!  :Bored: 
Με ποιόν τρόπο θα μπορούσε μέσα στην main να τρέχουν 2 ή περισσότερες ρουτίνες ανεξάρτητα?

----------


## tigris76

καλημερα να ρωτησω κατι μπορω να συνδεσω δυο υπολογιστες με ενα στικακι τις κοσμοτε ον τηε γκοου

----------


## stom

Αμα εχει avr μεσα σιγουρα....

----------


## stom

> Παιδιά μια ακόμα βοήθεια....
> Έχω φτιάξει ένα πρόγραμμα όμοιο με το προηγούμενο (αποκωδικοποιητής)
> Στην αρχή όμως του προγράμματος έχω προσθέσει έναν μετρητή ο οποίος μετράει και αποθηκεύει την τρέχουσα τιμή σε μία μεταβλητή x.
> Το πρόβλημα τώρα είναι οτι απο κάτω υπάρχει μια if για την ανάγνωση της εισόδου η οποία δεν εκτελείται ποτέ!
> Ο μετρητής αυξάνει μηδενίζει και αρχίζει ξανά... Το πρόγραμμα απορίπτει εντελώς τις επόμενες γραμμές του κώδικα! 
> Με ποιόν τρόπο θα μπορούσε μέσα στην main να τρέχουν 2 ή περισσότερες ρουτίνες ανεξάρτητα?



Μαλλον πρεπει να μας δειξεις τον κωδικα.

----------


## ALAMAN

```
while (1)
      {
      int x;
      for (x=1;x<=255;x++)
      {
      };
      if (PINA == 0x00) {
      PORTB = 0x5B;
      delay_ms(5);
      PORTB = 0xBF;
      delay_ms(5);
      PORTB = 0xBF;
      }
      else if (PINA == 0x01) {
      PORTB = 0x06;
      delay_ms(5);
      PORTB = 0xFE;
      delay_ms(5);
      PORTB = 0xDD; }
      else if (PINA == 0x02) {
      PORTB = 0x06;
      delay_ms(5);
      PORTB = 0xFE;
      delay_ms(5);
      PORTB = 0x37;
      };

      };
}
```


Το πρόγραμμα θα ξεκινήσει με την ρουτίνα for και θα παραμείνει εκεί απορίπτονας τις if.
Εγώ θα ήθελα οι ρουτίνες for και if να τρέχουν ταυτόχρονα και ανεξάρτητα μέσα στην main.

----------


## Mihos

If και while δεν είναι ρουτίνες :Wink: . Είναι απλά σύνθετες εντολές... Και αυτό που συμβαίνει είναι το εξής: 

Πρώτα εκτελείται η for (η οποία δε φένεται να κάνει κάτι χρήσιμο εκτός από τη καθυστέρηση) και μετά η if. Και όλο αυτό επαναλαμβάνεται επ'άπειρο (while(1)). Δε μπορείς να έχεις παράλληλη εκτέλεση δύο "νημάτων"... Αυτό είναι κάτι πολύ προχωρημένο για έναν απλό μικροελεγκτή... Βιβλίο της C πήραμε? :Wink:

----------


## ALAMAN

> If και while δεν είναι ρουτίνες. Είναι απλά σύνθετες εντολές... Και αυτό που συμβαίνει είναι το εξής: 
> 
> Πρώτα εκτελείται η for (η οποία δε φένεται να κάνει κάτι χρήσιμο εκτός από τη καθυστέρηση) και μετά η if. Και όλο αυτό επαναλαμβάνεται επ'άπειρο (while(1)). Δε μπορείς να έχεις παράλληλη εκτέλεση δύο "νημάτων"... Αυτό είναι κάτι πολύ προχωρημένο για έναν απλό μικροελεγκτή... Βιβλίο της C πήραμε?



Η εντολή for θα με χρησιμεύσει για αργότερα καθώς θα βάλω μέσα delay.
Αλλα θα ήταν πραγματικά χρήσιμο αμα εκτελούταν ανεξάρτητα, μόνη της μέσα στο πρόγραμμα. Άλλα όπως λες δεν γίνετε...

Τώρα, όσον αφορά για το βιβλίο στο παπασωτηρίου έχει πάρα πολλά αλλα δεν μπορώ να αποφασήσω σε κάποιο συγκεκριμένο καθώς έχω μεγάλο δίλημα!  :Unsure:  Άν έχεις να μου προτείνεις κάτι θα με βοηθούσες.  :Rolleyes: 

Επίσης απο χθές ψάχνω τις βιβλιοθήκες των μικροελεγκτών και διάφορες άλλες όπως, 8515.h, lcd.h κλπ για να μελετήσω τις εντολές καθώς ένα απλό βιβλίο της C δε νομίζω πως περιγράφει την γλώσσα με βάση της βιβλιοθήκες που χρησιμοποιούντε συνήθως στο CodeVisionAVR.

----------


## ALAMAN

Τελιά όσον αφορά με το βιβλίο βρίσκομαι ανάμεσα σ' αυτά τα 2:
http://www.papasotiriou.gr/product.g...313&deid=11003
http://www.papasotiriou.gr/product.g...=803432&deid=0

Άν και μάλλον θα καταλήξω στο πρώτο... "Η ΓΛΩΣΣΑ C ΣΕ ΒΑΘΟΣ"
Τί γνώμη έχετε γιαυτό?

----------


## stom

Στο βαθος κηπος.. Καλο δειχνει, αν διαβαζεται....
Για ποιο λογο να χρησιμοποιεις for loop οταν υπαρχει η delay?
Τελος παντων. Hello world στην στην LCD γραψαμε?

----------


## ALAMAN

> Στο βαθος κηπος.. Καλο δειχνει, αν διαβαζεται....
> Για ποιο λογο να χρησιμοποιεις for loop οταν υπαρχει η delay?
> Τελος παντων. Hello world στην στην LCD γραψαμε?



Δεν έχω LCD. Δηλαδή αυτή που έχω ούτε καν ανάβει!!!
Απο Σεπτέμβριο θα πάω να πάρω μία. Αυτό το διάστημα δεν είχαν τίποτα.

Αυτό με την for ήθελα να κάνω έναν μικρό προσομοιωτή ρολογιού που να μετράει κάποια δευτερόλεπτα, λεπτά και ώρες. Και μετά σε συγκεκριμένες στιγμές της ημέρας να κρατάει στατιστικά δεδομένα απο την θερμοκρασία που διαβάζει. Γιαυτό ήθελα να λειτουργούσε ανεξάρτητα απο το κύριο πρόγραμμα.
Η εντολή delay μέχρι πόση μεγάλη καθυστέρηση μπορεί να έχει ??

Επίσης μετά απο την αποθήκευση των τιμών των θερμοκρασιών που διαβάζονται απο την θύρα μπορούμε να δούμε ποιά ήταν η μέγιστη και ποιά η ελάχιστη! Αλλά για να γίνει αυτό (σε περίπτωση απεικόνησης σε display) το κύριο πρόγραμμα που εκτελεί όλες αυτές τις if θα πρέπει να κάνει μια πάυση ώστε να διαβάσει την μεταβλητή στην οποία είναι αποθηκευμένη η μέγιστη ή ελάχιστη θερμοκρασία και να την απεικονήσει στην οθόνη. Και αυτό, όταν εμείς το θελήσουμε!

Το πρόγραμμα όμως, όπως και στην παραπάνω περίπτωση, εκτελεί κατα σειρά όλες τις εντολές. Έτσι άμα έχουμε μία απλή εντολή if που βλέπει κάποιο πιν της θύρας D (η οποία θα χρησιμοποιείται για να μπορούμε να δούμε μια αποθηκευμένη τιμή) θα πρέπει να περιμένουμε να εκτελεστούν όλες οι εντολές μέχρι ο έλεγχος του προγράμματος να φτάσει στο σημείο:



```
/* Παράδειγμα */
if (PIND == 0x01) {
PORTB = k; }   /* k = μεταβλητή στην οποία αποθηκεύεται η θερμοκρασία */
```

----------


## stom

Πρωτα φτιαχνουμε κατι απλο και μετα παμε σε κατι πιο συνθετο.
Αφου επιμενεις με το εξωτερικο a/d εψαξες πως το ξυπνας?
Συνηθως οι a/d converters τους ξεκινας και σε ειδοποιουν καπως οτι ειναι ετοιμοι και εχουν ολοκληρωσει τη μετατροπη και ΜΕΤΑ πας και διαβαζεις την τιμή.
Αν πας και διαβασεις τιμες οποτε σε βολευει μαλλον θα διαβασεις τυχαια πραγματα.
Δες στα παραδειγματα του codevision. Εχει ετοιμο το κωδικα για τη μετατροπη a/d και μαλιστα interrupt driven.

Η τηρηση της ωρας ειναι λιγο πιο πολυπλοκη υποθεση και δεν γινεται με ενα for loop.
Ουτε με delay γινεται γιατι οσο εκτελειται η delay δεν γινεται τιποτε αλλο.

Επιμενω οτι εχεις πεσει στα βαθεια. Δοκιμασε κατι απλουστερο.
Παρε πχ ενα Led display με ενα ψηφιο και καντο να μετραει απο το 0 εως το 9 ανα 1 δευτερολεπτο. Μετα δοκιμασε να βαλεις 3-4 display και οδηγησε τα με πολυπλεξια.
Οταν θα το εχεις πετυχει αυτο, πας παρακατω.

----------


## ALAMAN

Τα εξωτερικά ADC δουλεύουν με τα πιν read / write.
Το έχω φτιάξει αυτό και δουλεύει πολύ καλά. Έχω υλοποιήσει όλο σχεδόν το σχέδιο εκτός το κομάτι του μικροελεγκτή.
Εγώ ήθελα να χρησιμοποιήσω τον εσωτερικό ADC γιατί έτσι το σχέδιο γίνετε πιο απλό και χρησιμοποιούντε λιγότερα πιν του μικροελεγκτή. Αυτό που ήθελα εξ' αρχής να κάνω το βρήκα αλλα θα προσπαθήσω να το απλοποιήσω λίγο μόλις πάρω και οθόνη LCD.

Επίσης η προσομοίωση ρολογίου δεν είναι κάτι τόσο δύσκολο. Με 3 for θα μπορούσε να γίνει. Άλλα δεν θα επιμείνω και θα συμφωνήσω μαζί σου, ας το αφήσουμε για αργότερα αυτό καθώς τώρα δεν χρειάζεται.

Τώρα, η οδήγηση 2 ή περισσότερων display δε νομίζω οτι είναι μια ιδιαίτερη φιλοσοφία. Το μόνο δύσκολο και χρονοβόρο είναι οτι πρέπει να κάτσουμε να γράψουμε ένα σχετικά τεράστιο πρόγραμμα.

----------


## ALAMAN

Τελικά πήρα το βιβλίο "Η γλώσσα C σε βάθος"!
Αρκετά καλογραμμένο και εύκολο.

Θα ήθελα να ρωτήσω όμως στο τεράστιο πρόγραμμα με τις if πώς μπορούμε να κρατήσουμε μέγιστη και ελάχιστη τιμή?
Σκεύτικα το παρακάτω αλλά νομίζω οτι το πρόγραμμα θα μπορούσε να μπερδευτεί έτσι όπως θα το έγγραφα...  :Unsure: 




```
if (PINA == 0x00) {
     x = PINA;
      PORTB = 0x5B;
      delay_ms(5);
      PORTB = 0xBF;
      delay_ms(5);
      PORTB = 0xBF;
      }
      else if (PINA == 0x01) {
     if (x < PINA)
      x = PINA;
      PORTB = 0x06;
      delay_ms(5);
      PORTB = 0xFE;
      delay_ms(5);
      PORTB = 0xDD; }
      else if (PINA == 0x02) {
     if (x < PINA)
      x = PINA;
      PORTB = 0x06;
      delay_ms(5);
      PORTB = 0xFE;
      delay_ms(5);
      PORTB = 0x37;
      };
```


Το *PINA* (με το μπλέ) θεωρείτε η προηγούμενη τιμή της θύρας Α.
Το *PINA* (με το κόκκινο θεωρείτε η παρούσα τιμή της θύρας Α η οποία καταχωρείτε στη μεταβλητή x.
Πιστεύεται οτι είναι σωστός τρόπος αυτός ?  :Confused1:

----------


## tasosmos

Αν και δεν ξερω για ποιο λογο κανεις 2 φορες τον ιδιο ελεγχο σε σειρα αντι να χρησιμοποιησεις καποιο βροχο λογικα πρεπει να ειναι ενταξει.

----------


## ALAMAN

Και πώς θα γίνει με βρόγχο?
Μάλλον ενοείς με for...  :Huh: 

EDIT: το θέμα είναι οτι το πρόγραμμα θα πρέπει να εκτελέσει 250 περίπου if και μετά να κοιτάξει τον βρόγχο για να συγκρίνει και να αποθηκεύσει την τιμή.

----------


## stom

Φτιαξε ενα array, βαλε εκει τις τιμες που διαβαζεις, και στο τελος βρες τη μεγιστη τιμη ειτε κανοντας sort το array ειτε χρησιμοποιοντας καμμια ετοιμη function τυπου max..
(δεν θυμαμαι ακριβως τι κανει η codevision με αυτο το θεμα..)

Ομως.. βρε παιδι μου.. 255 if? καπου κατι το κανεις τελειως λαθος....σιγουρα υπαρχει αλλος καλυτερος τροπος. Τι adc χρησιμοποιεις?

----------


## ALAMAN

> Φτιαξε ενα array, βαλε εκει τις τιμες που διαβαζεις, και στο τελος βρες τη μεγιστη τιμη ειτε κανοντας sort το array ειτε χρησιμοποιοντας καμμια ετοιμη function τυπου max..
> (δεν θυμαμαι ακριβως τι κανει η codevision με αυτο το θεμα..)
> 
> Ομως.. βρε παιδι μου.. 255 if? καπου κατι το κανεις τελειως λαθος....σιγουρα υπαρχει αλλος καλυτερος τροπος. Τι adc χρησιμοποιεις?



Νομίζω πως η if είναι ο μοναδικός τρόπος...
Πώς θα γίνει αλλιώς?
Ένας απλός κωδικοποιητής-αποκωδικοποιητής είναι, διαβάζει μια τιμή x και δίνει μια τιμή z.

Αυτό που λές με τον array είναι σωστό, αλλα πώς θα γεμίζει με τις τιμές ???
Την ώρα που διαβάζει μια τιμή, σε ποιό σημείο θα πηγαίνει να την αποθηκεύσει στον πίνακα?

ADC δεν χρησιμοποιώ γιατί δεν ξέρω πως να τον ενεργοποιήσω και πως να τον ελεγξω απο το πρόγραμμα...  :Glare:

----------


## stom

Μαλλον κατι εχω χασει.. θερμοκρασια δεν ειπαμε μετρας?
Εξωτερικο adc δεν χρησιμοποιεις? 
Καθε φορα που θα αποθηκευεις τιμη θα κανεις increment και το index του array...

----------


## tasosmos

Διαβασε συναρτησεις, πινακες και βροχους, συνδυαζοντας αυτα τα 3 θα βγει πολυ πιο συντομο το προγραμμα σου.

----------


## ALAMAN

> Μαλλον κατι εχω χασει.. θερμοκρασια δεν ειπαμε μετρας?
> Εξωτερικο adc δεν χρησιμοποιεις? 
> Καθε φορα που θα αποθηκευεις τιμη θα κανεις increment και το index του array...



α νόμιζα έλεγες για τον ενσωματωμένο ADC...
Την τιμή όμως που διαβάζω απο την θύρα Α δεν την αποθηκεύω κάπου...





> Διαβασε συναρτησεις, πινακες και βροχους, συνδυαζοντας αυτα τα 3 θα βγει πολυ πιο συντομο το προγραμμα σου.



Η θύρα Α διαβάζετε μέσα απο τις if. άρα δεν θα αλλάξει κάτι νομίζω...
Γιαυτό σκέφτηκα να κάνω εκεί την αποθήκευση της τιμής.  :Bored:

----------


## stom

Αποτι ειδα χρησιμοποιεις τον adc0804 που ειναι 8bit.
Ξεχνωντας offset errors κλπ που πιθανοτατα δεν σε ενδιαφερουν σε αυτη τη φαση, η τιμη του ADC θα ειναι παντα adc=Vin*256 /Vref...
Οποτε Vin=adc*Vref/256...
Πανε τα 256 if.....

----------


## ALAMAN

> Αποτι ειδα χρησιμοποιεις τον adc0804 που ειναι 8bit.
> Ξεχνωντας offset errors κλπ που πιθανοτατα δεν σε ενδιαφερουν σε αυτη τη φαση, η τιμη του ADC θα ειναι παντα adc=Vin*256 /Vref...
> Οποτε Vin=adc*Vref/256...
> Πανε τα 256 if.....



Εδώ μιλάς για τον εσωτερικό adc....? ο οποίος είναι 10bit όμως και όχι 8.  :Bored: 
Έχω μπερδευτεί... τί είδους συνάρτηση είναι αυτή?
Ποιά είναι η τάση Vref ?
Εγώ στον adc0804 δεν χρησιμοποίησα Vref.

----------


## ALAMAN

Για δείτε εδώ ένα διαφορετικό πρόγραμμα....




```
int therm[4][4], x, y;  /* ο πίνακας θα αρχικικοποιείται με καταχωρημένες τιμές */


for (x=1;x<=255;x++)  /* μετρητής για το x */
  {
      if (therm[x]==PINA)   /*σύγκριση, αν το x είναι ίσο με αυτό που έχει η θύρα Α */ 
                           /* τότε προχωράμε στην εγγραφή τιμής στην έξοδο Β */
     {
   
          for (y=1;y<=3;y++)  {  /*αφού έχουμε την τιμή του x (1 θέση για τον πίνακα) */
                                    /* αυξάνουμε το y διαδοχικά απο 1-3 για να πάρουμε και τις 3 τιμές με καθυστέρηση 5ms για απεικόνηση σε display. */

            PORTB = therm[x][y];  
            delay_ms(5);
                              }
      
     }
  }
```

----------


## stom

> Εδώ μιλάς για τον εσωτερικό adc....? ο οποίος είναι 10bit όμως και όχι 8. 
> Έχω μπερδευτεί... τί είδους συνάρτηση είναι αυτή?
> Ποιά είναι η τάση Vref ?
> Εγώ στον adc0804 δεν χρησιμοποίησα Vref.



Δεν υπαρχει adc χωρις vref και ο 0804 δεν ξεφευγει απο αυτο το κανονα..
Το Vref καπου το εχεις συνδεσει.
 Ο τυπος που σου εδωσα ισχυει για 8 bit ADC.
Αν ηταν 10bit το 256 γινεται 1024

----------


## ALAMAN

Θα ψάξω το κύκλωμα που είχα φτιάξει και θα σου πώ...

Ο παραπάνω κώδικας που έφτιαξα είναι οκ?
Πιστεύω πως υλοποιεί μια χαρά όλες τις if !

----------


## stom

PORTB = therm[x][y];  

Εδω τι προσπαθεις να κανεις ακριβως?
Η πορτΒ παιρνει ενα byte....

----------


## kopla

```
int therm[4][4], x, y;  /* ο πίνακας θα αρχικικοποιείται με καταχωρημένες τιμές */


for (x=0;x<=3;x++)  /* μετρητής για το x */
  {
      if (therm[x][0]==PINA)   /*σύγκριση, αν το x είναι ίσο με αυτό που έχει η θύρα Α */ 
                           /* τότε προχωράμε στην εγγραφή τιμής στην έξοδο Β */
     {
   
          for (y=1;y<=3;y++)  {  /*αφού έχουμε την τιμή του x (1 θέση για τον πίνακα) */
                                    /* αυξάνουμε το y διαδοχικά απο 1-3 για να πάρουμε και τις 3 τιμές με καθυστέρηση 5ms για απεικόνηση σε display. */

            PORTB = therm[x][y];  
            delay_ms(5);
                              }
      
     }
  }
```

----------


## ALAMAN

Μέσα στον πρώτο μετρητή του x, συγκρίνετε άν η θύρα Α (PINA==x) είναι ίση με την τιμή του x. 
Άν ΝΑΙ, προχωράμε στον δεύτερο μετρητή του y.
Που μετράει και εμφανίζει *διαδοχικά 3 αριθμούς των 8bit* που υπάρχουν αποθηκευμένοι.

Για παράδειγμα.
Στον πίνακα που επισύναψα όταν το x μέσα απο τον μετρητή πάρει την τιμή 2 και ταυτόχρονα η θύρα Α έχει τιμή 2 τότε η θύρα Β θα πάρει τις τιμές του πίνακα που αντιστοιχούν στις συντεταγμένες...
therm[2][1] ... delay ... therm[2][2] ... delay ... therm[2][3] ... delay

Δηλαδή θα έχουμε κάνει κωδικοποίηση, για τιμή 5, δίνουμε τιμές 14, 18, 30 πχ...
και κωδικοποιείται ανάλογα.... ώς 00000101 --> 00001110, 00010010, 00011110

----------


## ALAMAN

Σωστός ο kopla, το x πρέπει να αρχίζει απο 0.
Το x<=3 μην το δίνεται σημασία, είναι παράδειγμα του πίνακα 4x4

Στο  κανονικό πρόγραμμα ο πίνακας θα είναι μεγαλύτερος.
Απλά δεν μπορούσα να δώσω παράδειγμα με πίνακα 256x4  :Tongue2:

----------


## kopla

Είναι και αυτό: if (therm[x]*[0]*==PINA)

Με το [x] αλλάζεις γραμμές με το for/loop, αλλά οι αριθμοί που θες να τσεκάρεις είναι στην 1η στήλη. Γι αυτό και το [0] που ειναι η δεύτερη διάσταση του πίνακα.

----------


## ALAMAN

Ναί σωστά!
Θα κάνω μία μικρή δοκιμή στο Dev C++ να δώ αν το πρόγραμμα συμπεριφέρετε φυσιολογικά  και μετά θα το γράψω στο CodeVisionAVR

----------


## ALAMAN

Νομίζω πως υπάρχει ένα σοβαρό πρόβλημα...
Έγγραψα το παρακάτω πρόγαμμα στο Dev C++




```
#include <stdio.h>

main()
{
      int therm[4][4] = {{1,2,3,4}, {1,2,3,4}, {1,2,3,4}, {1,2,3,4}}, x, y, PINA;
      printf ("dose enan arithmo gia thura eisodou A\n");
      scanf ("%d", &PINA);
      for (x=0;x<=3;x++)
      {
          if (therm[x][0]==PINA)
          {
          for (y=0;y<=3;y++) 
          {
          printf ("%d", therm[x][y]);
          }
          }
          
  }
      system("pause");
}
```


Είναι ένας απλός αξομοιωτής απο την εργασία που θα εκτελεί ο μικροελεγκτής.
Την θύρα εισόδου PINA την καθορίζουμε εμείς απο το πληκτρολόγιο δινοντας μια τιμή απο 1-4
Στη συνέχεια το πρόγραμμα με μία for/loop αρχίζει και "ψάχνει" άν η τιμή της PINA (την οποία επιλέξαμε εμείς) είναι ίδια με την τιμή του πίνακα δηλαδή.. therm[0][0] η οποία είναι το 1.
Αυτό έχει ως αποτέλεσμα όταν εισάγω το 1 το πρόγραμμα να εμφανίζει διαδοχικά όλους τους αριθμούς του πίνακα...  οταν δίνω διαφορετικό αριθμό το πρόγαμμα απλώς τερματίζει!

----------


## ALAMAN

Άκυρο ... Δουλεύει !!!




```
#include <stdio.h>

main()
{
      int therm[4][4]={{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}}, x, y, PINA;
      for (x=0;x<=3;x++)
      {
          printf ("dose enan arithmo gia thura eisodou A\n");
          scanf ("%d", &PINA);
          if (PINA == therm[x][0])
      {
          printf ("\n");
          for (y=0;y<=3;y++)
          {
          printf ("%d  ", therm[x][y]);
          }         
      }
  }
      system("pause");
}
```


Επόμενο βήμα δοκιμή σε CodeVision !!  :Biggrin: 
Οι αποθηκευμένες τιμές της PINA μέσα στον πίνακα της πρώτης στήλης είναι 1,5,9,13

----------


## ALAMAN

Να ρωτήσω και μία λεπτομέρεια...
Η ρουτίνα for πόσο χρόνο θα χρειαστεί για να μετρήσει απο 0..εως..255, έτσι
ώστε να μπορεί να τσεκάρει τί τιμή θα έχει η θύρα Α ??

----------


## ALAMAN

Τον τελευταίο καιρό  ξανασχολούμε με τον προγραμματισμό μικροελεγκτών στη γλώσσα C.
Έφτιαξα και μια βοηθητική πλακέτα για να μπορώ να κάνω τις δοκιμές γρηγορότερα χωρίς να πεδεύομαι σε ράστερ!
Ξαναέψαξα προσεκτικά το θέμα και τελικά κατάφερα να ανάψω την οθόνη με διάφορους χαρακτήρες!
Πολύ εντυπωσιακό!
Θα ήθελα όμως αν ξέρει κανείς να με βοηθήσει να βρώ τις εντολές της βιβλιοθήκης lcd.h για να τις μελετήσω καλύτερα.
πχ. πώς μπορούμε να βάλουμε ολίσθηση σε ένα κείμενο, να ορίσουμε ταχύτητα ολίσθησης, να κάνουμε το κείμενο να αναβοσβήνει κλπ...
Υπάρχει κανένα άρθρο Ελληνικό ή Αγγλικό για διάφορες βιβλιοθήκες?

----------


## tasosmos

Απ'οτι ξερω δεν υπαρχει ετοιμη εντολη στην lcd.h για τπτ απο αυτα που αναφερεις, θα πρεπει να το κανεις εσυ με δομες επαναληψης.
πχ αν θες να αναβοσβηνει γραφεις το κειμενο που θες, καθυστερηση, καθαριζεις την οθονη, καθυστερηση.

Νομιζω οτι η ενσωματωμενη βοηθεια που εχουν οι compilers ειναι αρκετη για να καταλαβεις τι κανει η καθε εντολη, τουλαχιστον το codevision με καλυπτει σε αυτο το θεμα.

----------


## ALAMAN

Υπάρχει τρόπος να τυπώσω μια μεταβλητή σε οθόνη LCD?
Δηλαδή αν έχω μια μεταβλητή x και της δώσω μια τιμή, πώς μπορώ
να τυπώσω το x στην οθόνη χωρίς να μου το βγάζει σκέτο "x" ως γράμμα?

----------


## tasosmos

Χρησιμοποιεις τις συναρτησεις itoa ή ftoa αντιστοιχα αν ειναι ακεραιος ή float.

πχ 
int x=5;
char str[10];
itoa(x,str);
lcd_puts(str);

----------


## ALAMAN

> Χρησιμοποιεις τις συναρτησεις itoa ή ftoa αντιστοιχα αν ειναι ακεραιος ή float.
> 
> πχ 
> int x=5;
> *char str[10];
> itoa(x,str);*
> lcd_puts(str);



Οι συναρτήσεις char και itoa τί κάνουν ακριβώς?
η itoa νομίζω οτι μας λέει οτι το x είναι μεταβλητή με δεκαδική τιμή απ' ότι καταλαβαίνω...
Το char str[10]; σε τί χρησιμεύει?

----------


## tasosmos

Το char ειναι ο κλασικος τυπος μεταβλητης χαρακτηρα, απλα δηλωνεις εναν πινακα που να χωραει τα ψηφια που θες. (το 10 ειναι υπερβολη αφου οι unsigned int πανε μεχρι 32767, θα μπορουσες να βαλεις str[7] και θα επαιζε το ιδιο αλλα τεσπα)

Αφου εχεις ορισει int το x αυτο δεν μπορει να διατηρησει σε καμια περιπτωση δεκαδικα ψηφια.

Η itoa μετατρεπει εναν ακεραιο αριθμο στο ascii ισοδυναμο και το αποθηκευει στον πινακα str ωστε να μπορεις να το βγαλεις στην lcd.

Θα προτεινα να δεις την βοηθεια του codevision, εχει αρκετα συνοπτικα και κατανοητα ολα τα βασικα και απ'οτι καταλαβαινω εχεις προσπερασει καποια βασικα πραγματα οπως οι διαθεσιμοι τυποι μεταβλητων...

----------

