cumi
14.04.2006, 13:47
Hallo Zusammen
Ich versuche schon seit längerem einen 12Bit AD Wandler an einem AVR anzuschliessen und natürlich auszulesen.
Es handelt sich um den ADS7818 von BURR BROWN.
Ich habe mit eine Lochrasterplatine nach dem Schema (siehe Anhang A) gelötet. Diese habe ich über ein Flachbandkabel ans RN-Control gehängt. Ist das ev. ein Problem, das da etwa 20cm Kabel dazwischen sind? Denn die Frequenzen sind ja ziemlich hoch.
Dann habe ich folgende Software geschrieben und mit dem avr-gcc compiliert. b_setH(a,n); setzt das nte bit (das niderwerdigste ist 0) vom Byte a auf HIGH.
mit sendPc_hex16(); kann ich mir eine Zahl auf den Computer übertragen, sodass sie dann angezeigt wird.
Im Anhang B sieht ihr das Timing aus dem Datenblatt, welches ich implementiert habe.
Das ganze Datenblatt habe ich auch noch angehängt.
Hier der Code:
#include "bit_func.h"
#include "avr_types.h" //meine benötigten Typen
#include <avr/io.h>
#include <avr/interrupt.h> //wird für die Übertragung benötigt
#include "prot.h" //für die Übertragung auf den PC
#include "ad.h" //eigenes Haeder-File einbiden
// local definitions -----------------------------------------------------------
#define F_CPU 16000000
#define AD_PORT PORTD
#define AD_DDR DDRD
#define AD_PIN PIND
#define AD_CONV 4
#define AD_CLK 3
#define AD_DATA 2
// global variables ------------------------------------------------------------
// local variables -------------------------------------------------------------
int8 data[12];
// local function declarations -------------------------------------------------
void adInit(void);
void adRead(void);
// global function implementation ----------------------------------------------
int main(void){
DDRC =0xFF;
PORTC=0xFF;
adInit();
protInit(); //initialisiert ein Übertragungsprotokoll auf den PC
sei(); //Interrupts für die Übertragung auf den PC aktivieren
sendPc_str("***START***"); //der Contorller läuft...
while(1){ //loop
adRead(); //lesen
}
return 0;
}
// interrupt routines ----------------------------------------------------------
// local function implementation -----------------------------------------------
void adInit(void){
b_setH(AD_DDR ,AD_CONV);
b_setH(AD_PORT,AD_CONV);//default: hight
b_setH(AD_DDR ,AD_CLK);
b_setH(AD_PORT,AD_CLK); //default: hight
b_setL(AD_DDR ,AD_DATA);//Input
b_setL(AD_PORT,AD_DATA);//Pull-Up disable
}
void adRead(void){
int8 i;
byte dataH=0,dataL=0;
for(i=0;i<2;i++){
b_setL(AD_PORT,AD_CLK); //1,3
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //2,4
}
b_setL(AD_PORT,AD_CONV); //4-
asm volatile ("nop");
b_setL(AD_PORT,AD_CLK); //5
b_setH(AD_PORT,AD_CLK); //6
for(i=3;i>=0;i--){ //read HIGH Byte
b_setL(AD_PORT,AD_CLK); //7,...
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //8,...
if(b_ifset(AD_PIN,AD_DATA))
b_setH(dataH,i);
}
for(i=7;i>=1;i--){ //read LOW Byte 7-1
b_setL(AD_PORT,AD_CLK); //7,...
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //8,...
if(b_ifset(AD_PIN,AD_DATA))
b_setH(dataL,i);
}
b_setH(AD_PORT,AD_CONV);
if(b_ifset(AD_PIN,AD_DATA)) //read last bit
b_setH(dataL,0);
b_setL(AD_PORT,AD_CLK);
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK);
sendPc_hex16((dataH<<8)|dataL); //sendet mir die erhaltenen Daten zum PC.
}
// EOF -------------------------------------------------------------------------
Die Ausgabe ist immer:
hex16 : 0xffff
Das heisst der Pegel am Daten-Pin ändert sich überhaupt nie!
An was könnte das liegen? Habe ich eine Software-Fehler? Wenn ja, dann würde ich doch zumindest irgendetwas lesen, auch wenns falsch ist, und nicht einfach nichts, oder?
An was könnte es elektronisch liegen? Habe ich mich mit den Zeiten verrechnet (siehe Datenblatt). Oder ist einfach der AD kaputt und ich muss einen neuen kaufen (hab leider keine auf Vorrat, kosten ja immerhin 14CHF).
Vielen Dank für eure Hilfe!
Grüsse cumi
Ich versuche schon seit längerem einen 12Bit AD Wandler an einem AVR anzuschliessen und natürlich auszulesen.
Es handelt sich um den ADS7818 von BURR BROWN.
Ich habe mit eine Lochrasterplatine nach dem Schema (siehe Anhang A) gelötet. Diese habe ich über ein Flachbandkabel ans RN-Control gehängt. Ist das ev. ein Problem, das da etwa 20cm Kabel dazwischen sind? Denn die Frequenzen sind ja ziemlich hoch.
Dann habe ich folgende Software geschrieben und mit dem avr-gcc compiliert. b_setH(a,n); setzt das nte bit (das niderwerdigste ist 0) vom Byte a auf HIGH.
mit sendPc_hex16(); kann ich mir eine Zahl auf den Computer übertragen, sodass sie dann angezeigt wird.
Im Anhang B sieht ihr das Timing aus dem Datenblatt, welches ich implementiert habe.
Das ganze Datenblatt habe ich auch noch angehängt.
Hier der Code:
#include "bit_func.h"
#include "avr_types.h" //meine benötigten Typen
#include <avr/io.h>
#include <avr/interrupt.h> //wird für die Übertragung benötigt
#include "prot.h" //für die Übertragung auf den PC
#include "ad.h" //eigenes Haeder-File einbiden
// local definitions -----------------------------------------------------------
#define F_CPU 16000000
#define AD_PORT PORTD
#define AD_DDR DDRD
#define AD_PIN PIND
#define AD_CONV 4
#define AD_CLK 3
#define AD_DATA 2
// global variables ------------------------------------------------------------
// local variables -------------------------------------------------------------
int8 data[12];
// local function declarations -------------------------------------------------
void adInit(void);
void adRead(void);
// global function implementation ----------------------------------------------
int main(void){
DDRC =0xFF;
PORTC=0xFF;
adInit();
protInit(); //initialisiert ein Übertragungsprotokoll auf den PC
sei(); //Interrupts für die Übertragung auf den PC aktivieren
sendPc_str("***START***"); //der Contorller läuft...
while(1){ //loop
adRead(); //lesen
}
return 0;
}
// interrupt routines ----------------------------------------------------------
// local function implementation -----------------------------------------------
void adInit(void){
b_setH(AD_DDR ,AD_CONV);
b_setH(AD_PORT,AD_CONV);//default: hight
b_setH(AD_DDR ,AD_CLK);
b_setH(AD_PORT,AD_CLK); //default: hight
b_setL(AD_DDR ,AD_DATA);//Input
b_setL(AD_PORT,AD_DATA);//Pull-Up disable
}
void adRead(void){
int8 i;
byte dataH=0,dataL=0;
for(i=0;i<2;i++){
b_setL(AD_PORT,AD_CLK); //1,3
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //2,4
}
b_setL(AD_PORT,AD_CONV); //4-
asm volatile ("nop");
b_setL(AD_PORT,AD_CLK); //5
b_setH(AD_PORT,AD_CLK); //6
for(i=3;i>=0;i--){ //read HIGH Byte
b_setL(AD_PORT,AD_CLK); //7,...
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //8,...
if(b_ifset(AD_PIN,AD_DATA))
b_setH(dataH,i);
}
for(i=7;i>=1;i--){ //read LOW Byte 7-1
b_setL(AD_PORT,AD_CLK); //7,...
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK); //8,...
if(b_ifset(AD_PIN,AD_DATA))
b_setH(dataL,i);
}
b_setH(AD_PORT,AD_CONV);
if(b_ifset(AD_PIN,AD_DATA)) //read last bit
b_setH(dataL,0);
b_setL(AD_PORT,AD_CLK);
asm volatile ("nop");
b_setH(AD_PORT,AD_CLK);
sendPc_hex16((dataH<<8)|dataL); //sendet mir die erhaltenen Daten zum PC.
}
// EOF -------------------------------------------------------------------------
Die Ausgabe ist immer:
hex16 : 0xffff
Das heisst der Pegel am Daten-Pin ändert sich überhaupt nie!
An was könnte das liegen? Habe ich eine Software-Fehler? Wenn ja, dann würde ich doch zumindest irgendetwas lesen, auch wenns falsch ist, und nicht einfach nichts, oder?
An was könnte es elektronisch liegen? Habe ich mich mit den Zeiten verrechnet (siehe Datenblatt). Oder ist einfach der AD kaputt und ich muss einen neuen kaufen (hab leider keine auf Vorrat, kosten ja immerhin 14CHF).
Vielen Dank für eure Hilfe!
Grüsse cumi