PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USB 1 LED Switch



Tux12Fun
13.05.2009, 00:34
Hallo,

ich befasse mich gerade ein wenig mit USB und ATMEGA.

Vielleicht könnte mir jemand helfen folgenden Schaltplan auf einen ATMEAG 32 zu Portieren. Das ganze nur mit einem PB Ausgang für eine LED. Damit man beim Testen sieht ob es funktioniert. Ich möchte das ganze so einfach wie möglich halten und auf einem Steckbrett aufbauen. Deshalb möchte ich alle Teile die nicht unbedingt benötigt werden weglassen. Da ich nur einen AT Mega 32 mit einem ext. Quarz 16MHZ rumliegen habe möchte ich das ganze mit dem Versuchen.

Hier ist der noch etwas große Schaltplan
http://www.obdev.at/products/vusb/powerswitch.html

Ich denke mal die Relais + Transistoren kann ich einfach ohne Probleme rauswerfen. Eben so 7 LEDś + Vorwiderstände.

Nur wie muss ich bei dem USB Teil die Widerstände dann definieren, damit es mit dem ATMEGA32 klappt. Den komischen Spannungswandler muss ich auch noch auftreiben. Bei Reichelt gibtś den leider nicht und beim großen C muss ich noch nachsehen.

Währe echt super, wenn mir da jemand unter die Arme greifen könnte, da ich noch nicht so viel Erfahrung im Microcontrollerbreich habe.

Danke schon mal im Voraus für die Hilfe

Gock
13.05.2009, 10:17
Bitte Stell ein Bild der Schaltung rein, Danke
Gruß

Hubert.G
13.05.2009, 12:33
Wenn du unter Downloads schaust, findest du eine Schaltung mit Mega8, ohne Spannungsregler.
Wenn du es unbedingt mit Spannungsregler machen willst, zum testen geht auch ein LM317.
Der Unterschied sind nur die beiden Z-Dioden an der USB +D und -D Leitung bei einer 5V Version und das die 3,3V Version angeblich stabiler läuft.

Tux12Fun
13.05.2009, 22:23
Hallo,

danke für den Tipp, der war schon mal gold Wert. Nun brauche ich aber doch nochmal eure hilfe. Ich haben den Quelltext nun auf dem ATMEAG32 laufen. Leider sagt mein PC, dass er ein USB Device findet, dies aber Unknown ist und nicht erkannt wurde.

Ich tippe, das liegt evtl daran das ich den Prescaler in der Firmware nicht angepasst habe. Aber auf was soll ich den bei einem ATMEAG32 mit 16MHz setzen ???

Hier mal die Firmware, wie ich sie auf den AT gespielt habe. (Habe eigentlich alles so gelassen nur in der Makefile die CPU geändert und F_CPU auf 16 Mhz gesetzt. Dann habe ich noch in der USB Lib die 16 MHz aktiviert. Also denke ich dass es wirklich nur noch an dem Prescaler liegen kann.



/* Name: main.c
* Project: PowerSwitch based on AVR USB driver
* Author: Christian Starkjohann
* Creation Date: 2005-01-16
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
* This Revision: $Id: main.c 523 2008-02-15 09:46:40Z cs $
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>

#include "usbdrv.h"
#include "oddebug.h"
#include <util/delay.h>

/*
This module implements an 8 bit parallel output controlled via USB. It is
intended to switch the power supply to computers and/or other electronic
devices.

Application examples:
- Rebooting computers located at the provider's site
- Remotely switch on/off of rarely used computers
- Rebooting other electronic equipment which is left unattended
- Control room heating from remote
*/

#ifndef TEST_DRIVER_SIZE /* define this to check out size of pure driver */

#define EEPROM_LOCATION (void *)37

static uchar actionTimers[8];

/* This is the AT90S2313 version of the routine. Change for others. */
static void outputByte(uchar b)
{
PORTB = (PORTB & ~0xfc) | (b & 0xfc);
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
}

static uchar computeTemporaryChanges(void)
{
uchar i, status = 0, mask = 1;

for(i=0;i<8;i++){
if(actionTimers[i])
status |= mask;
mask <<= 1;
}
return status;
}
static void computeOutputStatus(void)
{
uchar status = eeprom_read_byte(EEPROM_LOCATION) ^ computeTemporaryChanges();

outputByte(status);
}

/* We poll for the timer interrupt instead of declaring an interrupt handler
* with global interrupts enabled. This saves recursion depth. Our timer does
* not need high precision and does not run at a high rate anyway.
*/
static void timerInterrupt(void)
{
static uchar prescaler;
uchar i;

if(!prescaler--){
prescaler = 8; /* rate = 12M / 1024 * 256 * 9 */
for(i=0;i<8;i++){
if(actionTimers[i])
actionTimers[i]--;
}
computeOutputStatus();
}
}

USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
uchar status = eeprom_read_byte(EEPROM_LOCATION);
static uchar replyBuf[2];

usbMsgPtr = replyBuf;
if(rq->bRequest == 0){ /* ECHO */
replyBuf[0] = rq->wValue.bytes[0];
replyBuf[1] = rq->wValue.bytes[1];
return 2;
}
if(rq->bRequest == 1){ /* GET_STATUS -> result = 2 bytes */
replyBuf[0] = status;
replyBuf[1] = computeTemporaryChanges();
return 2;
}
if(rq->bRequest == 2 || rq->bRequest == 3){ /* SWITCH_ON or SWITCH_OFF, index = bit number */
uchar bit = rq->wIndex.bytes[0] & 7;
uchar mask = 1 << bit;
uchar needChange, isOn = status & mask;
if(rq->bRequest == 2){ /* SWITCH_ON */
status |= mask;
needChange = !isOn;
}else{ /* SWITCH_OFF */
status &= ~mask;
needChange = isOn;
}
if(rq->wValue.bytes[0] == 0){ /* duration == 0 -> permanent switch */
actionTimers[bit] = 0; eeprom_write_byte(EEPROM_LOCATION, status);
}else if(needChange){ /* temporary switch: value = duration in 200ms units */
actionTimers[bit] = rq->wValue.bytes[0];
}
}
computeOutputStatus();
return 0;
}

/* allow some inter-device compatibility */
#if !defined TCCR0 && defined TCCR0B
#define TCCR0 TCCR0B
#endif
#if !defined TIFR && defined TIFR0
#define TIFR TIFR0
#endif

int main(void)
{
uchar i;

wdt_enable(WDTO_1S);
odDebugInit();
DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */
PORTD = 0;
PORTB = 0; /* no pullups on USB pins */
/* We fake an USB disconnect by pulling D+ and D- to 0 during reset. This is
* necessary if we had a watchdog reset or brownout reset to notify the host
* that it should re-enumerate the device. Otherwise the host's and device's
* concept of the device-ID would be out of sync.
*/
DDRB = ~USBMASK; /* set all pins as outputs except USB */
computeOutputStatus(); /* set output status before we do the delay */
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 500 ms */
wdt_reset();
_delay_ms(2);
}
usbDeviceConnect();
TCCR0 = 5; /* set prescaler to 1/1024 */
usbInit();
sei();
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
if(TIFR & (1 << TOV0)){
TIFR |= 1 << TOV0; /* clear pending flag */
timerInterrupt();
}
}
return 0;
}

#else /* TEST_DRIVER_SIZE */
/* This is the minimum do-nothing function to determine driver size. The
* resulting binary will consist of the C startup code, space for interrupt
* vectors and our minimal initialization. The C startup code and vectors
* (together ca. 70 bytes of flash) can not directly be considered a part
* of this driver. The driver is therefore ca. 70 bytes smaller than the
* resulting binary due to this overhead. The driver also contains strings
* of arbitrary length. You can save another ca. 50 bytes if you don't
* include a textual product and vendor description.
*/
uchar usbFunctionSetup(uchar data[8])
{
return 0;
}

int main(void)
{
#ifdef PORTD
PORTD = 0;
DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */
#endif
PORTB = 0; /* no pullups on USB pins */
DDRB = ~USBMASK; /* all outputs except USB data */
usbInit();
sei();
for(;;){ /* main event loop */
usbPoll();
}
return 0;
}

#endif /* TEST_DRIVER_SIZE */

Tux12Fun
13.05.2009, 22:33
Ein Bild vom Aufbau auf dem Steckbrett
http://www.wuala.com/Tux12Fun/worldpublic/electronic/testaufbau.jpg

Tux12Fun
13.05.2009, 23:36
Problem gelöst habe eine Leitung vergessen