Hallo,
ich möchte gerne einen 8x PWM I²C Slave mit einem ATmega8 in C programmieren. Dabei benutze ich die Soft-PWM Lib von mikrocontroller.net und die twislave Lib aus dem RN-Wissen. Mit dem Soft-PWM funktioniert soweit alles einwandfrei, aber es gibt noch ein paar Probleme mit dem I²C Slave. Der Slave wird vom Master erkannt, wenn ich ihn unter der angegebenen Adresse anspreche, aber ich kann dann nichts in das Data Array vom Slave schreiben und auch nichts auslesen (Der Master selbst funktioniert, ich kann problemlos einen PCF8574 ansprechen). Der Master bleibt also nicht hängen, die Status LED leuchtet nicht. Die Werte von i2cdata[] im Slave bleiben aber alle 0. Ich vermute jetzt, dass das daran liegt, dass die twislave.c auf den ATmega32 abgestimmt wurde. Die einzelnen TWI Register (TWCR etc.) stimmen also vermutlich nicht alle (deshalb funktioniert nur die Hälfte). Den Buffer im twislave.c habe ich entsprechend groß gewählt. Wenn das das Problem ist: Welche Register müssen jetzt geändert werden? Durch die beiden Datenblätter steige ich nicht ganz durch. Hier mein Code:
Slave:
Code:
#include <util/twi.h> 	    //enthält z.B. die Bezeichnungen für die Statuscodes in TWSR
#include <avr/interrupt.h>  //dient zur Behandlung der Interrupts
//#include <stdint.h> 	    //definiert den Datentyp uint8_t
#include <stdlib.h>         //nötig für Zahlumwandlung mit itoa
#include <util/delay.h>

//Software PWM:
// Defines an den Controller und die Anwendung anpassen
#define F_CPU         8000000L           // Systemtakt in Hz
#define F_PWM         100L               // PWM-Frequenz in Hz
#define PWM_PRESCALER 8                  // Vorteiler für den Timer
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)
#define PWM_PORT      PORTD              // Port für PWM
#define PWM_DDR       DDRD               // Datenrichtungsregister für PWM
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle

#include "twislave.c"
#include "softpwm.h"

int main (void)
{
  DDRB = 0xff;
  DDRD = 0xff;
  DDRC = ((0 << PB0 ) | (0<<PB1) | (0<<PB2) | (0<<PB3) | (1<<PB4) | (1<<PB5));

  init_software_pwm();
  init_twi_slave(I2C_ADR_SLAVE); //TWI als Slave mit Adresse starten

  sei();

  while(1)
  {
	  for(uint8_t i=0; i<8; i++) //Software PWM Daten aus i2cdata lesen
    {
      pwm_setting[i]=i2cdata[i];
    }
    pwm_update();

    OCR1A = i2cdata[8];
    OCR1B = i2cdata[9];
    OCR2 = i2cdata[10];

    for(uint8_t i=11; i<15; i++)
    {
      i2cdata[i] = ADC_Read(i-11);
    }
    
    if(i2cdata[15]==1){
      PORTB |= (1<<0);}
    else{
      PORTB &= ~(1<<0);}
    if(i2cdata[16]==1){
      PORTB |= (1<<4);}
    else{
      PORTB &= ~(1<<4);}
    if(i2cdata[17]==1){
      PORTB |= (1<<5);}
    else{
      PORTB &= (1<<5);}
  } //end.while
} //end.main
Codeausschnitt Master:
Code:
uint8_t ret = i2c_start(0x19+I2C_WRITE);       // set device address and write mode

    if ( ret )
    {

        /* failed to issue start condition, possibly no device found */

        i2c_stop();

        PORTD |= (1<<4); //Status LED an                        

    }
    else
    {

        /* issuing start condition ok, device accessible */

        i2c_write(0x00);   //Buffer Startadresse                    
        i2c_write(0x0A);  //10            
        i2c_write(0x14);  //20
        i2c_write(0x1E);  //30
        i2c_write(0x28);  //40
        i2c_write(0x64);  //100
        i2c_stop();                            // set stop conditon = release bus
        PORTD &= ~(1<<4); //Status LED aus
    }
Ich hoffe, ihr könnt mir helfen.
Vielen Dank schonmal im Vorraus und
Viele Grüße
teamohnename