habe hier mal ein programm zusammengestellt aus auszügen für die gameboy-cam in winavr-c. die daten werden bei mir seriell mit 9600baud zum pc übertragen zum programm von tobi. ich habe ein AVR16 mit 8mhz intern und den adc-port-a0 benutzt.
adc.h :
gameboy-cam:Code:#define ADCchannel_init DDRA=0x00 // ADC Port als Eingang deklarieren #define ADCinit ADCSRA|=_BV(ADEN) // Teilt dem Board mit das der jeweilige Port für ADC verwendet wird #define ADCdisable ADCSRA &=~_BV(ADEN) // machs das vorherige wieder rückgänig #define ADCstart ADCSRA|=_BV(ADSC) // startet eine konvertierung auf dem gewünschten Kannal/Pin #define ADCfree ADCSRA|=_BV(ADATE) // schaltet den freilaufenden Modus ein #define ADCvintern ADMUX|=_BV(REFS0) // interne Spannungsversorgung #define ADCinterrupt_on ADCSRA|=_BV(ADIE) // ADC interrupt wird freigeschalten #define ADCprescaler_2 ADCSRA |=_BV(ADPS0) // gewünschter Teilungsfaktor/Prescaler #define ADCprescaler_4 ADCSRA|=_BV(ADPS1) #define ADCprescaler_8 ADCSRA=_BV(ADPS1) | _BV(ADPS0) #define ADCprescaler_16 ADCSRA|=_BV(ADPS2) #define ADCprescaler_32 ADCSRA=_BV(ADPS2) | _BV(ADPS0) #define ADCprescaler_64 ADCSRA=_BV(ADPS2) | _BV(ADPS1) #define ADCprescaler_128 ADCSRA=_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) #define ADCprescaler_reset ADCSRA = ~_BV(ADPS2) & ~_BV(ADPS1) & ~_BV(ADPS0) #define ADCchannel_1 //gewünschter Kannal z.B bei ATmega32 PINA0 - PINA7 #define ADCchannel_2 ADMUX|=_BV(MUX0) // bei nicht freilaufen muss ADCchannel_x vor #define ADCchannel_3 ADMUX|=_BV(MUX1) // ADCstart kommen dann kann man mit getadc() der #define ADCchannel_4 ADMUX= _BV(MUX1) | _BV(MUX0) // Adcwert des gewählten Kannals auslesen #define ADCchannel_5 ADMUX|=_BV(MUX2) #define ADCchannel_6 ADMUX= _BV(MUX2) | _BV(MUX0) #define ADCchannel_7 ADMUX= _BV(MUX2) | _BV(MUX1) #define ADCchannel_8 ADMUX= _BV(MUX2) | _BV(MUX1) | _BV(MUX0) #define ADCchannel_reset ADMUX= ~_BV(MUX2) & ~_BV(MUX1) & ~_BV(MUX0) uint16_t getadc(void) { while (ADCSRA & _BV(ADSC)) {} return ADC; }
mfg pebisoftCode:#include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <string.h> #include <stdint.h> #include <avr/delay.h> #include "adc.h" #define READ 1 #define WRITE 2 #define USART_BAUD_RATE 9600 #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1) #define GBPORT PORTB #define GBDDR DDRB #define GBPIN PINB #define CCLK 7 #define CLOAD 6 #define CSIN 5 #define CREAD 4 #define CSTART 1 #define CRESET 0 void delay_us(uint16_t us) { uint16_t zaehler; while (us) { zaehler = F_CPU / 5000000; while (zaehler) { asm volatile ("nop"); zaehler--; } us--; } } void usart_init(int Enable, int Interupts) { if (Enable & READ) UCSRB = (1<<RXEN); if (Enable & WRITE) UCSRB |= (1<<TXEN); if (Interupts & READ) UCSRB |= (1<<RXCIE); if (Interupts & WRITE) UCSRB |= (1<<TXCIE); UBRRL = (unsigned char) USART_BAUD_SELECT; } void usart_writeChar(unsigned char c) { while (!(UCSRA & (1<<UDRE))) {} UDR = c; while(!(UCSRA & (1<<TXC))) {} } void usart_writeString(unsigned char *string) { while (!(UCSRA & (1<<UDRE))) {} while ( *string) usart_writeChar(*string++); } // Laden der Register der gbcam void gbcam_load_register(uint8_t adresse, uint8_t daten) { /* 3-Bit Adresse und 8-Bit Daten Die Übertragung erfolgt über ein syncrones Protkoll mit CCLK, CSIN und CLOAD */ uint8_t i; adresse &= 0x07; // Übertragen der Adresse ( 3-Bit ) for (i=0;i<3;i++) { if ( ( adresse & 0x04 ) > 0 ) { GBPORT |= (1<<CSIN); } adresse <<= 1; GBPORT |= (1<<CCLK); delay_us(10); GBPORT &= ~(1<<CCLK); delay_us(1); GBPORT &= ~(1<<CSIN); delay_us(1); } // Übertragen der Daten ( 8-Bit ) for (i=0;i<8;i++) { if ( ( daten & 0x80 ) > 0 ) GBPORT |= (1<<CSIN); daten <<= 1; GBPORT |= (1<<CCLK); /* Beim letzen Bit muß zusätzlich die CLOAD Leitung gesetzt werden, Nachdem CCLK gesetzt wurde */ delay_us(5); if (i == 7) { PORTB |= (1<<CLOAD); } delay_us(5); GBPORT &= ~(1<<CCLK); delay_us(1); GBPORT &= ~((1<<CSIN)|(1<<CLOAD)); delay_us(1); } } // Starten der Aufnahme void gbcam_start(void) { // Startsignal erzeugen GBPORT |= (1<<CSTART); delay_us(1); GBPORT |= (1<<CCLK); delay_us(10); GBPORT &= ~(1<<CSTART); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // Kamera zurücksetzen void gbcam_reset(void) { // Resetleitung auf Low ziehen GBPORT &= ~(1<<CRESET); delay_us(1); GBPORT |= (1<<CCLK); delay_us(10); GBPORT |= (1<<CRESET); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // Intitialisieren der Gameboy Kamera void gbcam_init(void) { GBDDR = (1<<CCLK)|(1<<CLOAD)|(1<<CSIN)|(1<<CSTART)|(1<<CRESET); GBPORT = (1<<CRESET)|(1<<CREAD); gbcam_reset(); /* Laden der Register der Gameboy Kamera, Einstellungen für ein normales Bild */ gbcam_load_register( 0x00,0); // 000 GAIN gbcam_load_register( 0x01, 7); // Belichtungszeit gbcam_load_register( 0x02, 54); gbcam_load_register( 0x03, 1 ); gbcam_load_register( 0x04, 1 ); gbcam_load_register( 0x05, 0 ); gbcam_load_register( 0x06, 1 ); gbcam_load_register( 0x07, 7 ); } int main (void) { char wert_str[10]; uint16_t adc_wert; usart_init( (READ + WRITE) , READ); ADCchannel_init; ADCinit; ADCprescaler_16; ADCchannel_1; gbcam_reset(); gbcam_init(); gbcam_start(); /* Warten bis die gbcam bereit ist */ while ( ( GBPIN & (1<<CREAD) ) == 0 ) { GBPORT |= (1<<CCLK); delay_us(1); GBPORT &= ~(1<<CCLK); delay_us(1); } // 16384 Pixel auslesen while( ( GBPIN & (1<<CREAD ) ) != 0 ) { GBPORT |= (1<<CCLK); delay_us(1); // AD Wandler starten ADCstart; adc_wert=getadc(); // Daten einlesen itoa( adc_wert,wert_str, 10); usart_writeString(wert_str); GBPORT &= ~(1<<CCLK); delay_us(1); } }





Zitieren

Lesezeichen