Archiv verlassen und diese Seite im Standarddesign anzeigen : A/D Wandler Problem
Hi @ all
Ich hab mich mal mit dem A/D Wandler beschäftigt. Leider fuktioniert das ganze nicht so wie ich mir das vorstelle. :(
Das ist einmal der Code:
#include <avr/io.h>
#include <stdlib.h>
#include "wintek2704.h"
void adc_init(void);
int get_adc (void);
void lcd_put_d(uint8_t dec);
int main (void)
{
DDRC &=~ _BV(PC0);
PINC &=~ _BV(PC0);
uint8_t ergebnis_display;
adc_init();
lcd_init(LCD_DISP_ON);
lcd_puts(" ADC -- Test\n");
while(1)
{
ergebnis_display = get_adc();
lcd_put_d(ergebnis_display);
}
return(0);
}
void lcd_put_d(uint8_t dec)
{
char buffer[6];
itoa(dec, buffer, 10);
lcd_puts(buffer);
}
void adc_init (void)
{
ADCSR = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS2); //Prescaler = 64 TF = 125 kHz
}
int get_adc (void)
{
uint8_t i;
uint16_t ergebnis_adc;
ADMUX = 0; // Vreff = Vcc
ADCSRA |= (1 << ADSC);
while (!(ADCSRA & (1 << ADIF)));
ergebnis_adc = 0;
for(i = 0; i < 5; i++)
{
ADCSRA |= (1 << ADSC);
while(!(ADCSRA & (1 << ADIF)))
ergebnis_adc += ADC;
}
ADCSRA &=~ (1 << ADEN);
ergebnis_adc = ergebnis_adc / 5;
return ergebnis_adc;
}
Am LCD bekomm ich nur Datdenmüll :(
Könnte mir da jaemand helfen???
Danke im Voraus
Gruß Robert
Hab gestern noch vergessen meine Harsware dazu posten.
CPU: ATMEGA 8
F_CPU = 8 MHz
Poti an PC0
Gruß Robert
SprinterSB
03.03.2006, 08:54
Hinter
while(!(ADCSRA & (1 << ADIF)))
fehlt ein ; bzw. {} ?
Kommt in letzter Zeit als Frage hier häufiger vor :)
Danke O:)
Jedoch verstehge ich eins nicht. Der ADC Wert wird nur nach einem Reset aktualisiert ausgegeben. Wenn ich danach das Poti verdrehe, ändert sich der Wert nicht.
Warum nicht?? Ich lese den A/D Kanal ja in einer Endlosschleife aus.
Könnte mir jemand das erklären?
Danke im Voraus
Gruß Robert
Du schaltest nach der ersten Wandlung den ADC ab:
ADCSRA &=~ (1 << ADEN);
Lass die Zeile in get_adc() mall weg. Dann sollte es klappen.
Arrg. Da hätt ich selber draufkommen können. Hab nämlich vorher die Init in der gleichen Funktionion gehabt.
Danke
Gruß Robert
Hallo an alle
Ich hab nun die A/D Routine fertig geschrieben .
#include <avr/io.h>
#include <stdlib.h>
#include "wintek2704.h"
void adc_init(void);
int get_adc (void);
void lcd_put_d(uint16_t dec);
int main (void)
{
DDRC &=~ _BV(PC0);
PINC &=~ _BV(PC0);
uint8_t balken3, balken_leer, i, j;
uint16_t ergebnis_display;
uint16_t ergebnis_neu;
adc_init();
lcd_init(LCD_DISP_ON);
lcd_puts(" ADC -- Test\n");
ergebnis_neu = 0;
while(1)
{
ergebnis_display = get_adc();
if (ergebnis_neu > ergebnis_display || ergebnis_neu < ergebnis_display)
{
lcd_gotoxy(0,1);
lcd_puts(" ");
ergebnis_neu = ergebnis_display;
}
lcd_gotoxy(0,1);
lcd_put_d(ergebnis_neu);
balken3 = ergebnis_neu / 37;
balken_leer = 27 - balken3;
lcd_gotoxy(0,2);
for(i = 0; i < balken3; i++)
lcd_puts("=");
for(j = 27; j > balken_leer; j--)
lcd_puts(" ");
}
return(0);
}
void lcd_put_d(uint16_t dec)
{
char buffer[6];
itoa(dec, buffer, 10);
lcd_puts(buffer);
}
void adc_init (void)
{
ADCSR = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS2); //Prescaler = 64 TF = 125 kHz
}
int get_adc (void)
{
uint8_t i;
uint16_t ergebnis_adc;
ADMUX = 0; // Vreff = Vcc
ADCSRA |= (1 << ADSC);
while (!(ADCSRA & (1 << ADIF)));
ergebnis_adc = 0;
for(i = 0; i < 5; i++)
{
ADCSRA |= (1 << ADSC);
while(!(ADCSRA & (1 << ADIF)));
ergebnis_adc += ADC;
}
ergebnis_adc = ergebnis_adc / 5;
return ergebnis_adc;
}
Jedoch überschreibe ich jetzt immer die Zahl vor der Aktualisierung mit 4 leerzeicnen (lcd_puts" "). Denn Wenn ich eine Zahl > 1000 anzeige, bleibt die letzte Stelle hängen wenn der Wert unter 1000 sinkt. Das gleiche bei 100. Deshalb die Überschreibung mit den Leerzeichen.
Gibt es in C ein Möglichkeit die Zahlen formatiert auszugeben zB 0125, 0058, 1024
In BASCOM gibt es ja die Funktion FUSING. Gibt es sowas auch in C
Danke im Voraus
Gruß Robert
SprinterSB
04.03.2006, 00:11
Du könntest sowas machen:
#include <string.h>
void lcd_put_d (uint8_t dec)
{
static char buffer[12];
char len, *str = buffer+6;
itoa (dec, str, 10);
for (len = 5-strlen (str); len > 0; len--)
*(--str) = '0';
lcd_puts (str);
}
Das füllt vorne mit Nullen auf.
Hallo Sprinter
Danke. Nur die Programmlogik verstehe ich noch nicht ganz. Der Zeiger zeigt auf die Adresse zeigt auf den String. Und an der Stelle des ZEigers wird eine 0 eingefügt. Der Zeiger wandert immere eins weiter.
Sehe ich das richtig??
Gruß Robert
SprinterSB
04.03.2006, 16:46
Den Puffer habe ich von 6 auf 12 Zeichen vergrößert. itoa schreibt sein Ergebnis aber nicht ab dem Abfang des Strings, sondern fängt erst ab Position 6 (dem 7.Zeichen) an.
Wenn itoa fertig ist, schaue ich nach, vieviele Nullen vorne dran müssen, bis die Stringlänge ganze 5 Zeichen ist. str wandert so lange zum Stringanfang und schreibt '0', bis er die 5 Zeichen hat. Dann wird der String ab str (und nicht von ganz Anfang, das wäre buffer) ausgegeben.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.