PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Int Variable auf LCD ausgeben



Jan.HH
10.11.2005, 22:06
Hallo,

ich programmiere einen ATMEGA8 mit Codevision AVR. An den atmega hab ich ein LCD gehängt, ich kann auch Strings mit dem Befehl
lcd_putsf("Hello world"); ausgeben. Nur habe ich keine Ahnung mit welchem Befehl ich einen Int-Wert ausgeben kann?


bei putsf bekomm ich eine Fehlermeldung: function parameter incompatible with its declaration

Hier mein Code:


#include <mega8.h>

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int x;
int y;



// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x87;

// LCD module initialization
lcd_init(16);



while (1)
{

x= read_adc(PINC.0);
y= read_adc(PINC.1);

lcd_gotoxy(0,0);
lcd_putsf('x');


lcd_gotoxy(5,0);
lcd_putsf(y);


delay_ms(500);

};
}



vielen Dank für eure Hilfe.

Jan


Edit: lcd_putchar(x) geht auch nicht, da wird jedem int Wert ein Buchstabe zugeordnet ;)

Andun
11.11.2005, 08:05
Du musst die Integer mit itoa() in einen Char umwandeln. Diesen kannst du dann ohne Probleme am LCD oder übers Hyperterminal anzeigen lassen.

SprinterSB
11.11.2005, 09:06
Fraglich, ob das bei Codevision dabei ist, weil itoa() kein ISO-C ist.

#include <stdlib.h>
This file declares some basic C macros and functions as defined by the ISO standard, plus some AVR-specific extensions.

Non-standard (i.e. non-ISO C) functions:

• char* itoa (int val, char *s, int radix)
• char* ltoa (long int val, char *s, int radix)
• char* utoa (unsigned int val, char *s, int radix)
• char* ultoa (unsigned long int val, char *s, int radix)



char* itoa (int val, char *s, int radix)
Convert an integer to a string. The function itoa() converts the integer value from val into an ASCII representation that will be stored under s. The caller is responsible for providing sufficient storage in s.

Note:
The minimal size of the buffer s depends on the choice of radix. For example, if the radix is 2 (binary), you need to supply a buffer with a minimal length of 8*sizeof (int) + 1 characters, i.e. one character for each bit plus one for the string terminator. Using a larger radix will require a smaller minimal buffer size.

Warning:
If the buffer is too small, you risk a buffer overflow.

Conversion is done using the radix as base, which may be a number between 2 (binary conversion) and up to 36. If radix is greater than 10, the next digit after ’9’ will be the letter ’a’. If radix is 10 and val is negative, a minus sign will be prepended.

The itoa() function returns the pointer passed as s.

skillii
11.11.2005, 11:24
ja itoa gibt es im CodevisionAVR ...
der Prototyp ist allerdings ein wenig anders:
void itoa(int n, char *str)
// converts the integer n to characters in string str.

BGMF
11.11.2005, 12:02
Hm.
Ich hab ja keine Ahnung, wie komplex die iota-Funktion ist, aber selbst mit meinen mitunter recht schwachem Mathe, könnte ich das relativ schnell, wenn auch wahrscheinlich nicht sonderlich effizient, selbst basteln...
Wozu gibts sonst Modulo und Dividieren?

BGMF

P.S. Wobei ich zugeben muss, dass Iota mal einfach mächtiger scheint...
P.P.S Aber vieleicht ist das ja auch mit Kanonen auf Spatzen schiessen...

SprinterSB
11.11.2005, 12:19
Ich hab ja keine Ahnung, wie komplex die iota-Funktion ist, aber selbst mit meinen mitunter recht schwachem Mathe, könnte ich das relativ schnell, wenn auch wahrscheinlich nicht sonderlich effizient, selbst basteln...
Wozu gibts sonst Modulo und Dividieren?

itoa() ist low level und isst etwa 150 Bytes deines wertvollen Flashs auf. Dabei sind die durch itoa() nachgezogenen Divisionsroutinen etc. schon mit eingerechnet. Falls man an anderer Stelle eh dividieren muss, ist es natürlich weniger, es verbleiben dann rund 110 Bytes.

Jan.HH
14.11.2005, 21:38
hey,

itoa funktioniert, vielen Dank für den Tipp

Jan.HH
16.11.2005, 19:36
hallo,

ich habe ein weiteres Problem, passt zwar nicht richtig in diesen Thread aber ich poste dass hier trotzdem mal.

Also, ich möchte mit dem ADC vom Atmega8 einen Wert einlesen. Nach langen Testen hab ich jetzt heraus gefunden dass mein Programm grundsätzlich die Spannung von PinC.1 ausliesst. Es ist total egal welchen Pin ich auslesen möchte er nimmt immer Pin.1.

Hier mein Code:


#include <mega8.h>

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
#include <stdlib.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int x;

char s[3];


// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x87;

// LCD module initialization
lcd_init(8);



while (1)
{
lcd_clear();
x= read_adc(PINC.0);

itoa(x,s);
lcd_gotoxy(0,1);
lcd_puts(s);


delay_ms(500);

};
}

und er liesst nicht die Spg. von PINC.0 ](*,)


wäre nett wenn ihr mir wieder so schnell helfen könntet.

Vielen Dank
Jan

kater
16.11.2005, 20:05
Was hast du dir denn bei dieser Zeile gedacht?

ADMUX=adc_input|ADC_VREF_TYPE;

linux_80
16.11.2005, 20:14
Hi kater,
das würde schon passen, wenn man die funktion richtig aufruft,

@Jan.HH
man gibt hier nicht das Pin direkt an an welchem man gerne messen würde, sondern nur die nummer von 0 bis 6.
Dazu gibts im Datenblatt irgendwo eine Liste in der steht welche Nr welches Pin ist, aber normalerweise Pin ADC0 mit Nr 0 auswählen.

Mit ADC_VREF_TYPE gibst Du an wie deine Referenzspannung aussieht, das muss dann aber zu dem passen wie Du das angeschlossen hat, ebenfalls siehe Datenblatt.

Jan.HH
16.11.2005, 20:44
Soweit ich es verstanden habe sollte es doch aber möglich sein den ADC Channel zu wechseln, also den Pin an den man auslesen möchte zu wechseln.

Der ADC Prozess funktioniert auch, also sollte dafür die Syntax richtig sein.

Ich versteh halt nur nicht was ich bei der Auswahl des Channels falsch mache.

linux_80
16.11.2005, 21:11
natürlich geht das,
wenns keine Fehlrmeldung gibt, muss es nicht heissen das es richtig ist, es passiert nur nicht das was gewünscht ist !

Da eins weiter oben hätte ich geschrieben wie's geht !

Jan.HH
16.11.2005, 21:21
@linux80

sry die letzte Antwort war etwas unbedacht...



soweit ich das Datenblatt verstanden habe heissen die Pins ADC0 bis ADC7, wenn ich dies aber im Code so eingebe, also "x= read_adc(ADC0);" bekomm ich die Fehlermeldung undefined symbol ADC0. Und mit "x= read_adc(PINC.0);" gabs keine Fehlermeldung, dehalb dachte ich dass der Code so vielleicht richtig ist, was ja aber nicht zutrifft.

linux_80
16.11.2005, 21:33
schreib einfach nur eine Zahl in die klammer:

read_adc( 0 )

für ADC0.

Jan.HH
16.11.2005, 21:44
vielen vielen Dank jetzt geht es ;)