C Hilfe bei Xmas Projekt benötigt!

ravedave

Neues Mitglied
05. Juni 2011
11
0
1
Sprachen
Hallo

Ich bin beim Googeln auf ein für mich sehr interessantes Projekt gestoßen. Da ich meine Programme mit Bascom schreibe, noch Anfänger bin und mich mit AVR Studio und CodeVisionAVR nicht wirklich auskenne steck ich gerade beim Quelltext ziemlich in der Klemme.
AVR Studio bringt mir 15 Fehler beim Compilieren und mit CodeVisionAVR komm ich garnich klar.

http://wiki.electronics-irc.net/Intelligent_xmas_decoration
Das ist das Projekt.

Wäre jemand so nett und würde mir erklären wie ich mit AVR Studio oder CodeVisionAVR den Hexfile hin bekomm, oder würde den online stellen?

mfg Dave
 
hier is doch das programm, kannste doch überstzen nachbascom
Code:
// $Id: c.c,v 1.5 2006/09/23 20:16:12 michai Exp $

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <avr/io.h> 
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "cr.h"



#define EE_SIZE      64
#define EE_ADDR( x ) ( ( const uint8_t * )( uint16_t )( x ) )



#define DDR_LEDS   DDRB
#define OUTP_LEDS   PORTB

#define OUTM_LED_GRE   _BV( 0 )

#define OUTM_LED_RED   _BV( 1 )

#define OUTM_LED_YEL   _BV( 2 )

#define INM_VBATT   _BV( 3 );

#define DDR_LDR_CAP    DDRB
#define OUTP_LDR_CAP   PORTB
#define OUTM_LDR_CAP   _BV( 4 );



static void sleep_ms( uint8_t ms ) { while ( ms-- ) _delay_ms( 1 ); }



static void blink_green( void )
{
  OUTP_LEDS &= ~OUTM_LED_GRE;
  sleep_ms( 5 );
  OUTP_LEDS |= OUTM_LED_GRE;
}



static void blink_red( uint8_t N, uint8_t off_ms )
{
  bool forever = !N;

  while ( forever || N-- ) {
    OUTP_LEDS &= ~OUTM_LED_RED;
    _delay_ms( 5 );
    OUTP_LEDS |= OUTM_LED_RED;
    sleep_ms( off_ms );
  }
}

static void blink_for_counting( uint8_t N ) { blink_red( N, 250 ); }



#define PWM_PERIOD 22

static void set_led( uint8_t mask, uint8_t dc )
{
  uint8_t N;

  if      ( dc & _BV( 4 ) ) N = 1;
  else if ( dc & _BV( 3 ) ) N = 2;
  else if ( dc & _BV( 2 ) ) N = 3;
  else if ( dc & _BV( 1 ) ) N = 5;
  else                      N = 7;

  while ( N-- ) {

    if ( dc ) OUTP_LEDS &= ~mask;
    sleep_ms( dc );
    OUTP_LEDS |= mask;
    sleep_ms( ( PWM_PERIOD - 1 ) - dc );
  }
}



static void pwm_led( uint8_t mask )
{
  uint8_t dc;

  for ( dc = 0; dc < PWM_PERIOD; dc++ ) set_led( mask, dc );
  while ( --dc )                        set_led( mask, dc );
}



// (Only) assumes ADMUX has been set up correctly
static uint16_t get_adc_val( void )
{
  uint16_t sample;

  ADCSRA |= _BV( ADEN ); // enable ADC

  // Enable ADC
  ADCSRA |= _BV( ADEN );

  // Get sample
  ADCSRA |= _BV( ADSC ); // start conversion
  while ( ADCSRA & _BV( ADSC ) ) ;
  sample = ADCL;
  sample |= ( ( uint16_t )ADCH << 8 );

  // Disable ADC
  ADCSRA &= ~_BV( ADEN );

  return sample;
}



static uint16_t get_ldr_val( void )
{
  ADMUX = _BV( MUX1 ); // select ADC2 (PB4), Vcc as ref

  return get_adc_val();
}



static uint16_t get_batt_val( void )
{
  ADMUX = ( _BV( MUX1 ) | _BV( MUX0 ) ); // select ADC3 (PB3), Vcc as ref

  return get_adc_val();
}



static void init_leds( void )
{
  // LEDs are output
  DDR_LEDS = ( OUTM_LED_GRE | OUTM_LED_RED | OUTM_LED_YEL );

  // Turn off LEDs
  OUTP_LEDS = ( OUTM_LED_GRE | OUTM_LED_RED | OUTM_LED_YEL );
}



static uint8_t batt_is_ok( void ) { return ( get_batt_val() > ( ( 1024 * 9 ) / 33 ) ); }



static uint8_t get_ldr_darkness_perc( void )
{
  // Drain, then start recharging cap
  DDR_LDR_CAP |= OUTM_LDR_CAP;
  _delay_ms( 1 );
  DDR_LDR_CAP &= ~OUTM_LDR_CAP;

  // Measure ADC until it hits 66% of Vcc in 1ms intervals
  // (ADC-conversion itself + code takes about 600us, but
  // resulting percentage is just that, a percentage of something.

  uint8_t num_ok = 0;

  uint8_t perc;
  for ( perc = 0; perc < 100; perc++ ) {

    uint16_t sample = get_ldr_val();
    if ( sample > ( ( 2 * 1024 ) / 3 ) ) { num_ok++;   }
    else                                 { num_ok = 0; }

    if ( num_ok == 3 ) break;

    _delay_ms( 1 );
  }

  // how to interpret 'perc'?
  //
  //   TL-lit hobbyroom, uncovered             :  <5 
  //   TL-lit hobbyroom, hand 10cm over LDR    :   13
  //   TL-lit hobbyroom, hand 1cm over LDR     :   75
  //   2nd light hobbyroom, uncovered          :   18
  //   2nd light hobbyroom, hand 10cm over LDR :   80
  //   2nd light hobbyroom, hand 1cm over LDR  : >100
  //

  return perc;
}



static void init_wdt()
{
  // Clear possible WD-reset flag
  MCUSR &= ~_BV( WDRF );

  // Start timed sequence to change prescaler
  WDTCR |= ( _BV( WDTIE ) | _BV( WDCE ) );

  // Set prescaler to 1s
  WDTCR |= ( _BV( WDTIE ) | _BV( WDP2 ) | _BV( WDP1 ) );
  
  sei();
}



ISR( SIG_WATCHDOG_TIMEOUT ) { /* just continue where we left off */ }

//ISR( SIG_WATCHDOG_TIMEOUT ) 
//{
//    OUTP_LEDS ^= OUTM_LED_YEL;
//    _delay_ms( 5 );
//    OUTP_LEDS ^= OUTM_LED_YEL;
//}



static void power_down_1s( void )
{
  wdt_reset();

  // Enter power-down sleep, to be woken up by WDT
  set_sleep_mode( SLEEP_MODE_PWR_DOWN );
  sleep_enable();
  sleep_cpu();
  sleep_disable();
}



static void TASK_monitor_darkness( bool *enable )
{
  static const int8_t diff_thresh  = 20;
  static int8_t prev_dark_perc;
  static int8_t prev_prev_dark_perc;
  static int8_t xmas_eff_perc; // to see how long dark-period continues
  static uint8_t i;

  int8_t dark_perc = get_ldr_darkness_perc();
  int8_t delta_dark_perc = ( ( int8_t )dark_perc - prev_prev_dark_perc );
  prev_prev_dark_perc = prev_dark_perc;
  prev_dark_perc = dark_perc;

  bool to_dark  = ( delta_dark_perc >=  diff_thresh );
  bool to_light = ( delta_dark_perc <= -diff_thresh );

  CR_BEGIN;

  for ( ;; ) {

    *enable = false;

    // Wait until light goes off
    do { CR_YIELD; } while ( !to_dark );
    blink_green();
    CR_YIELD; // stabilise after transition

    // Wait T_dark ( 1s <= T_dark <= 3s )
    CR_YIELD; // don't check for 1st second   XXX should be stable
    for ( i = 0; i < 2; i++ ) {
      CR_YIELD;
      if ( to_dark )  { blink_for_counting( 1 ); CR_RESET; }
      if ( to_light ) break;
    }
    if ( !to_light ) { blink_for_counting( 2 ); CR_RESET; }
    blink_green();
    CR_YIELD; // stabilise after transition

    // Wait T_light ( 1s <= T_light <= 3s )
    CR_YIELD; // don't check for 1st second   XXX should be stable
    for ( i = 0; i < 2; i++ ) {
      CR_YIELD;
      if ( to_light ) { blink_for_counting( 3 ); CR_RESET; }
      if ( to_dark )  break;
    }
    if ( !to_dark ) { blink_for_counting( 4 ); CR_RESET; }
    blink_green();

    // Enable, and latch current darkness
    *enable = true;
    xmas_eff_perc = dark_perc;

    // Indicate start-of-fun
    blink_red( 5, 100 );

    // Keep enabled as long as it's dark
    while ( ( xmas_eff_perc - dark_perc ) < diff_thresh ) CR_YIELD;

    // Indicate end-of-fun, and redo from start
    blink_red( 5, 100 );
  }

  CR_END;
}



static void TASK_pwm_leds( void )
{
  CR_BEGIN;

  static const uint8_t ledmasks[] = { OUTM_LED_GRE, OUTM_LED_RED, OUTM_LED_YEL, 0 };

  for ( ;; ) {

    static uint8_t ee_idx;
//    ee_idx++;
//    ee_idx &= 63;
    for ( ee_idx = 0; ee_idx < EE_SIZE; ee_idx++ ) {

      static uint8_t byte;
      byte = eeprom_read_byte( EE_ADDR( ee_idx ) );

      static uint8_t i;
      for ( i = 0; i < 2; i++ ) {

        uint8_t ledmask = ledmasks[ byte & 0x03 ];
        byte >>= 2;

        pwm_led( ledmask );

        static uint8_t delay;
        delay = ( ( byte & 0x03 ) + 1 );
        byte >>= 2;

        while ( delay-- ) CR_YIELD;
      }
    }
  }

  CR_END;
}



int main( void )
{
  // Disable input-buffer for all ADC-pins
  DIDR0 = (
      _BV( ADC2D ) |  // V_ldr_cap
      _BV( ADC3D ) ); // V_batt

  init_leds();
  init_wdt();

  blink_red( 5, 100 );

  bool enable;
  for ( ;; ) {

    power_down_1s();

    TASK_monitor_darkness( &enable );
    if ( enable ) {
      TASK_pwm_leds();
    }
    else {
      if ( !batt_is_ok() ) {
        blink_red( 1, 0 );
      }
    }
  }

  return 0;
}
 
Das ist leichter gesagt als getan.Wie gesagt ich bin Anfänger und habe beruflich auch nicht viel damit am Hut. Ich arbeite mich zur Zeit durch das BascomBuch von Rowalt und auf Grund mangelnder Freizeit bin ich da noch nicht so weit.

Leider haben wir schon Dezember und es brennt zeitlich etwas mit den Dingern. soweit hab ich ja alles fertig die Platinen liegen hier schon fertig rum, nur leider bekomm ich aus dem eigentlich fertigem C Programm keinen hex File für die Attinys. Wie oben beschrieben 15 Fehler bei AVR Studio und CodeVisionAVR geht garnich.
 
hi,

Es sieht nach einem GCC Projekt aus (also WinAVR & AVR Studio) ... (wie kommst du auf codevision ?)

Man könnte dir leichter helfen wenn du ein paar dinnge nennst ^^

was bekommst du den für Fehler ?

hast du den Tiny13 auch verwendet / im Studio eingestellt ?

Hast du ein GCC Projekt erstellt ?

was hast du bisslangt versucht ...
wo klemmt es ...

dann kann man dir eventuell leichter helfen :)

Gruß,
Manuel
 
Also den Tiny13V habe ich bei AVR Studio5 eingestellt und auch ein GCC Projekt erstellt.
Folgende Fehler bekomme ich angezeigt:

warning F_CPU not defined for <util/delay.h>
warning Compiler optimization disabled; funktions from <util/delay.h> won't work as designed
cr.h: No such file or dictonary
 
Hallo Dave!


(1) cr.h: No such file or dictonary


Es fehlt noch ein Header-File, das findest du auch auf der Webseite. Ich füge es mal hier ein:
Im AVR Studio erstellst du ein neues Header-File cr.h mit folgendem Code ...
Code:
#ifndef CR_H_INCLUDED
#define CR_H_INCLUDED

// example:
//
//   void print_2nd_word( char c )
//   {
//     CR_BEGIN;
//   
//     while ( c != ' ' )
//       CR_YIELD;
//   
//     CR_YIELD; // skip space
//   
//     while ( c != ' ' ) {
//       putchar( c );
//       CR_YIELD;
//     }
//   
//     CR_END;
//   }



#define GLUE2( a, b ) a##b
#define GLUE( a, b ) GLUE2( a, b )

#define CR_BEGIN static void *jmp = &&lbl_crstart; goto *jmp; lbl_crstart: ( void )jmp; {

#define CR_YIELD { jmp = &&GLUE( lbl, __LINE__ ); return; GLUE( lbl, __LINE__ ): ( void )jmp; } while( 0 )

#define CR_RESET do { jmp = &&lbl_crstart; return; } while ( 0 )

#define CR_END }



#endif // ndef CR_H_INCLUDED

(2) warning F_CPU not defined for <util/delay.h>
warning Compiler optimization disabled; funktions from <util/delay.h> won't work as designed


delay.h muss wissen wir hoch der Systemtakt ist. Am einfachsten du gibst den Takt bei der Projekt Konfiguration an (Menüpunkt Project/ConfigurationOptions).

Gruß,
Dirk
 
Muss sich der Header-File in einem bestimmten Ordner befinden? Im Quelltext wird er mir noch rot unterlegt obwohl er bei Dokumente/AVRStudio vorhanden ist und der Fehler kommt auch noch.

delay.h muss wissen wir hoch der Systemtakt ist. Am einfachsten du gibst den Takt bei der Projekt Konfiguration an (Menüpunkt Project/ConfigurationOptions).

Im Menüpunkt Projekt habe ich nur AVRGCC1 Properties, aber da finde ich nix wo ich den Systemtakt einstellen kann.

Edit: Also jetzt scheint alles geklappt zu haben.
Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

Allerdings ist der Hexfile im Ordner AVRGCC1/AVRGCC1/Debug zu groß für den speicher des Tiny13.
Laut meinem myAVR Prog Tool ist der hexfile 5666 Byte groß und beim beschreiben kommt: time out beim schreiben des flash.
 
Du nutzt sicherlich Version 5 des AVR Studio. Du kannst dort den Systemtakt auch in den Projekteinstellungen vorgeben, so dass der global bekannt ist.
Alternativ schreibst du direkt vor #include <util/delay.h> folgende Zeile: #define F_CPU 1000000UL // in Herz. (hier gibst du die Systemfrequenz deines Mikrocontrollers an).

Unter AVR Studio 4 compiliert ergibt sich folgende Codegröße (Optimierung: -Os):
Code:
AVR Memory Usage
----------------
Device: attiny13

Program:    [B]1000 bytes[/B] (97.7% Full)
(.text + .data + .bootloader)

Data:         16 bytes (25.0% Full)
(.data + .bss + .noinit)

Build succeeded with 0 Warnings...

Ich habe nun hier auf meinem Rechner kein AVR Studio 5 installiert und kann den Code somit damit mal nicht schnell kompilieren.
Das Ergebnis vom Studio 4 habe ich mal angehängt (ATtiny13, 1,2MHz).
(Nutzung auf eigene Gefahr)

Dirk
 

Anhänge

  • tiny13.zip
    1,3 KB · Aufrufe: 2
Habs mal fix auf'n Breadboard aufgesteckt und das Programm aufgespielt. Leider leuchten alle 3 Led's und auch bei Licht an und aus keine Reaktion. Dazu muss ich allerdings sagen hatte grad nur nen 4,7uF Elko für den LDR zur Hand und in der Beschreibung steht auch nix davon was das für'n LDR ist also hab ich nen LDR03 von Reichelt benutzt.

Auf alle Fälle schon mal Danke für deine Unterstützung, werd mir die Woche nen 1uF besorgen und mit verschiedenen LDR's nochmal testen.
 
Habs mal fix auf'n Breadboard aufgesteckt und das Programm aufgespielt. Leider leuchten alle 3 Led's und auch bei Licht an und aus keine Reaktion. Dazu muss ich allerdings sagen hatte grad nur nen 4,7uF Elko für den LDR zur Hand und in der Beschreibung steht auch nix davon was das für'n LDR ist also hab ich nen LDR03 von Reichelt benutzt.

Auf alle Fälle schon mal Danke für deine Unterstützung, werd mir die Woche nen 1uF besorgen und mit verschiedenen LDR's nochmal testen.
mit 4,7µF statt dem 1µF verändert sich die Zeitkonstante natürlich um das beinahe 5fache. Damit kann man die Schwellwerte im Programm natürlich in die Tonne hauen. Also kein Wunder das er nicht reagiert wenn er was anderes mißt als im Programm verwendet wird.
Clock is selected to be internal 128 kHz resonator for minimum power-consumption.
also dürfte das von Dirk übersetzte Programm mit den angegebenen 1,2MHz um den Faktor 10 daneben liegen.

Über den LDR steht noch nicht mal im Quellcode was drin. Keine Typangabe. Eventuell nimmt man erst mal nen Poti mit 500kOhm mit nem weiteren 4,7kOhm in Reihe um damit den LDR zu simulieren. Wenn man dann weiß bei welchem Wert die Schaltung entsprechend reagiert kann man sich den passenden LDR besorgen. Andersrum besorgt man sich einen LDR der einem in der Größe gefällt und paßt das Programm entsprechend an. Die Werte von den Dingern sind doch stark unterschiedlich :rolleyes:

Gruß
Dino
 
Hallo Dino!
...also dürfte das von Dirk übersetzte Programm mit den angegebenen 1,2MHz um den Faktor 10 daneben liegen.

Es wäre doch recht einfach mit 1,2MHz testbar. Ich schätze mal, dass die Fuses sowieso noch im Originalzustand stehen, also 9,6MHz/8. :)

Hier nochmal die 128kHz Version ...

Gruß,
Dirk
 

Anhänge

  • tiny13_128000.zip
    1,3 KB · Aufrufe: 2
Danke für eure Hilfe. Werd mit der 128k Version dem richtigen Kondensator und der Potimethode morgen nochnal testen. Die Anpassung des Programm's an den LDR würde ich mit C nicht hinbekommen, Bin ja schon dabei gescheitert den Hex-File zu bekommen,
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)