Hallo,
ich habe im Internet einen Quarztester mit LCD Display gefunden.
Nun wollte ich das ganze auf USB Umbauen. Doch leider kommt als
Freqenz immer 0 heraus. Das Ozi Zeigt aber an, dass an PD4 ein
Sauberer Takt anliegt.
Leider kenn ich mich mit Timer nicht wirklich aus. Und der Original Teil lief bei
14.7456Mhz mein AVR läuft bei 16 0000 Mhz.
Vielleicht findet ja von euch jemand den Fehler.
Leider ist das eine ganz schön harte Kobelaufgabe.
Vielen Dank schon mal für eure Antworten.
PS: Der ATMEGA32 läuft mit Quarz 16 Mhz + 2 27pf. Als FUSE ist high (D9) und low (EF) gesetzt. Der USB teil funktioniert, wenn ich in die freq Variable eine Wert schreibe bekomme ich ihn am PC auch richtig angezeigt.
Original Quelltext:
Code:
* ATmega8 */
/* Quarztest V4.02*/
/* Zählereingang ist T0, Teilerausgang des 74HC4060 /64 */
/* Ausgabetext auf dem Display wird nicht im RAM sondern im Flash gespeichert*/
/* Für LCD 2x16 Zeichen */
/* Es wird die Batt-Spannung und Version in der zweiten Zeile ausgegeben */
/* Korrekturfaktor für Spannungsabfall am Gleichrichter */
/* Für HW-Version V2.1, V3.1, V3.2 */
#include <avr/io.h>
#include "lcd_new.h"
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include "hubert.h"
#include <avr/pgmspace.h>
#ifndef F_CPU
#define F_CPU 14745600UL
#endif
#define Timer_1_wert ((F_CPU / 400)+3)
void LCD_Ausgabe (void);
volatile DWORD Timer_0z=0; /*Zählt die Überläufe von timer0 */
volatile WORD Timer_1z=0; /*Zählt die Überläufe von timer1 */
DWORD T0_wert=0; /* summenwert von timer_0_zähler + TCNT0 */
volatile WORD VMesswert;
char Programmname[]PROGMEM="Quarztest";
char Versionsnummer[]PROGMEM=" V4.02";
char Batterie[]PROGMEM="Batt";
/*Displaytexte werden Flash gespeichert, erste[] ist Anzahl der Werte, zweite [] max. Stellen +1*/
const char Wertdef[2][3]PROGMEM ={"Hz","V"};
const char fuellzeichen[4][2]PROGMEM ={"0",","," ","."};/* Texte für die LCD-Ausgabe im Flash*/
struct {
unsigned char LCD_Ausgabe :1; /* LCD-Ausgabe starten */
unsigned char ADC_Mess :1; /* ADC-Messung komplett */
unsigned char Versionan :1; /* Version wird angezeigt */
unsigned char VAn_time :2; /* Zeit für Version anzeigen */
}flag;
ISR(TIMER0_OVF_vect){ /*Überlauf timer 0*/
Timer_0z++;
}
ISR(TIMER1_COMPA_vect){ /*Takt 2500µ Sek*/
Timer_1z ++;
}
ISR(ADC_vect){ /* Interrupt auslösen wenn ADC-conversion komplett*/
VMesswert=ADCH; /*Register auslesen, */
flag.ADC_Mess=1;
}
void LCD_Ausgabe (void){ /* LCD_Ausgabe starten*/
lcd_clrscr(); /* LCD löschen */
lcd_gotoxy(1,0);
char FWert1[9];
char zlang;
ltoa(T0_wert,FWert1,10); /* Maximalwert Frequenz in ASCII-Wert umwandeln*/
zlang=(strlen(FWert1));
if(zlang==7){
lcd_puts_p(fuellzeichen[2]);
}
if(zlang==6){
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
}
if(zlang==5){
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
}
if (zlang <5 ){
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
lcd_puts_p(fuellzeichen[2]);
}
if (zlang ==8){
lcd_putc(FWert1[0]);
lcd_putc(FWert1[1]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[2]);
lcd_putc(FWert1[3]);
lcd_putc(FWert1[4]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[5]);
lcd_putc(FWert1[6]);
lcd_putc(FWert1[7]);
}
if (zlang ==7){
lcd_putc(FWert1[0]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[1]);
lcd_putc(FWert1[2]);
lcd_putc(FWert1[3]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[4]);
lcd_putc(FWert1[5]);
lcd_putc(FWert1[6]);
}
if (zlang==6){
lcd_putc(FWert1[0]);
lcd_putc(FWert1[1]);
lcd_putc(FWert1[2]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[3]);
lcd_putc(FWert1[4]);
lcd_putc(FWert1[5]);
}
if (zlang==5){
lcd_putc(FWert1[0]);
lcd_putc(FWert1[1]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(FWert1[2]);
lcd_putc(FWert1[3]);
lcd_putc(FWert1[4]);
}
lcd_gotoxy(12,0);
lcd_puts_p(Wertdef[0]); /* Bezeichnung Hz ausgeben */
lcd_gotoxy(0,1);
lcd_puts_p(Batterie);
char Vwert[4];
VMesswert=((VMesswert*8)+128);
itoa (VMesswert,Vwert,10);
lcd_gotoxy(5,1);
zlang=(strlen(Vwert));
if (zlang==4){
lcd_putc(Vwert[0]);
lcd_putc(Vwert[1]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(Vwert[2]);
}
if (zlang==3){
lcd_putc(Vwert[0]);
lcd_puts_p(fuellzeichen[3]);
lcd_putc(Vwert[1]);
}
lcd_puts_p(Wertdef[1]);
if(flag.Versionan){
flag.VAn_time +=1;
lcd_gotoxy(10,1);
lcd_puts_p(Versionsnummer);
if (flag.VAn_time >=3){
flag.Versionan = 0;
}
}
}
int main (void){
lcd_init(LCD_DISP_ON); /* LCD initialisieren */
flag.Versionan = 1;
flag.VAn_time = 0;
cli();
flag.LCD_Ausgabe=0;
TIMSK=(1<<OCIE1A)|(1<<TOIE0); /* timer0 für Messtart,timer1 für F-Messung aktiv */
OCR1A=Timer_1_wert;
TCCR1B=0;
TCNT0=0;
TCCR0=(1<<CS01)|(1<<CS02); /*Clock von T0 falling edge*/
TCCR1B=(1<<CS11)|(1<<WGM12);
flag.ADC_Mess=1;
MCUCR=(1<<SM0); /* ADC Noise Reduction Enabled */
ADMUX=(1<<MUX0)|(1<<MUX2)|(1<<REFS0)|(1<<ADLAR);/* ADC Kanal 5 initialisieren, Interne Referenz AVCC, Ausgabe linksbündig*/
ADCSRA=(1<<ADEN)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADSC); /* ADC initialisieren und starten */
sei();
for(;;){
if(Timer_1z>=50){ /*torzeit 1 Sekunde */
TCCR0=0;
TCCR1B=0;
Timer_1z=0;
T0_wert=((Timer_0z*256+TCNT0)*64);/* Anzahl der Überläufe * 256 > */
TCNT0=0; /* + Zählerstand * Teilerfaktor */
Timer_0z=0;
TCNT1=0;
ADCSRA|=(1<<ADSC);
flag.LCD_Ausgabe=1;
}
if ((flag.LCD_Ausgabe)&&(flag.ADC_Mess)){ /* Wenn LCD-Ausgabe vorbereitet Ausgabe starten*/
flag.LCD_Ausgabe=0;
flag.ADC_Mess=0;
TCCR0=(1<<CS01)|(1<<CS02); /* Timer 0 wieder starten */
TCCR1B=(1<<CS11)|(1<<WGM12); /* Timer 1 wieder starten */
LCD_Ausgabe();
}
}
}
Mein Quelltext
Code:
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <stdio.h>
#include <stdint.h>
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv.h"
#include "oddebug.h" /* This is also an example for using debug macros */
#include "requests.h" /* The custom request numbers we use */
//QT
#include <string.h>
#include <avr/io.h>
#include <stdlib.h>
#define NOT_IMPLEMENTED_REQUEST 0
#define Timer_1_wert ((F_CPU / 400)+3)
static uchar freq[11];
volatile unsigned long Timer_0z=0; /*Z ählt die Überläufe von timer0 */
volatile unsigned int Timer_1z=0; /* Zählt die Überläufe von timer1 */
unsigned long T0_wert=0; /* summenwert von timer_0_zähler + TCNT0 */
ISR(TIMER0_OVF_vect){ /*Überlauf timer 0*/
Timer_0z++;
}
ISR(TIMER1_COMPA_vect){ /*Takt 2500µ Sek*/
Timer_1z ++;
}
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8]){
usbRequest_t *rq = (void *)data;
static uchar dataBuffer[80]; /* buffer must stay valid when usbFunctionSetup returns */
if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
sprintf(dataBuffer, "Freq: %s Hz. ", freq);
usbMsgPtr = dataBuffer; /* tell the driver which data to return */
return 22; /* tell the driver to send 22 byte */
}
return NOT_IMPLEMENTED_REQUEST;
}
/* ------------------------------------------------------------------------- */
int __attribute__((noreturn)) main(void){
uchar i;
wdt_enable(WDTO_1S);
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET! */
/* RESET status: all port bits are inputs without pull-up.
* That's the way we need D+ and D-. Therefore we don't need any
* additional hardware initialization.
*/
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
// QT
// ===
cli();
TIMSK=(1<<OCIE1A)|(1<<TOIE0); // timer0 für Messtart,timer1 für F-Messung aktiv
OCR1A=Timer_1_wert;
TCCR1B=0;
TCNT0=0;
TCCR0=(1<<CS01)|(1<<CS02); //Clock von T0 falling edge
TCCR1B=(1<<CS11)|(1<<WGM12);
// =====
sei();
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
// QT
if(Timer_1z>=50){ //torzeit 1 Sekunde
TCCR0=0;
TCCR1B=0;
Timer_1z=0;
T0_wert=((Timer_0z*256+TCNT0)*64); // Anzahl der Überläufe * 256 >
TCNT0=0; // + Zählerstand * Teilerfaktor
Timer_0z=0;
TCNT1=0;
ADCSRA|=(1<<ADSC);
}
ltoa(T0_wert,freq,10); // Maximalwert Frequenz in ASCII-Wert umwandeln
TCCR0=(1<<CS01)|(1<<CS02); /* Timer 0 wieder starten */
TCCR1B=(1<<CS11)|(1<<WGM12); /* Timer 1 wieder starten */
}
}
/* ------------------------------------------------------------------------- */
Lesezeichen