Code:
#define F_CPU 16000000UL //CPU Tackt
#include <avr/io.h> // I/O Port definitions
#include <avr/interrupt.h> // Interrupt macros
#include <util/twi.h>
#include <util/delay.h>
#include "lcd.h"
#include "funktionen.h"
/*----------------------------------------------------------------------------------------*/
//MAIN AUFRUF
/*----------------------------------------------------------------------------------------*/
int main(void)
{
DDRA |= (1<<PORTA0);
PORTA |= (1<<PORTA0);
//Init Ports Steuerkreuz (Eingänge)
DDRD &= ~((1<<PORTD4) | (1<<PORTD5) | (1<<PORTD6) | (1<<PORTD7));
//Pullup aktivieren
PORTD |= (1<<PORTD4) | (1<<PORTD5) | (1<<PORTD6) | (1<<PORTD7) ;
//D7 Rechts
//D6 Links
//D5 Runter
//D4 Hoch
twi_init();
servo1 = 125;
servo2 = 125;
servo3 = 125;
servo4 = 125;
servo5 = 125;
servo6 = 125;
servo7 = 125;
servo8 = 125;
servo9 = 125;
servo10 = 125;
servo11 = 125;
servo12 = 125;
servo13 = 125;
servo14 = 125;
servo15 = 125;
servo16 = 125;
servo17 = 125;
servo18 = 125;
servochance = 1;
//screenup();
while(1)
{
if(tast(&PIND, PORTD7))
{
if(servochance<18)
servochance++;
else
servochance = 1;
dispz(servochance, servochance);
}
if(tast(&PIND, PORTD6))
{
if(servochance>1)
servochance--;
else
servochance = 18;
dispz(servochance, servochance);
}
if(tast(&PIND, PORTD4))
{
switch(servochance)
{
case 1:
if(servo1<250)
{
servo1= servo1+5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo1);
}
break;
/*
case 2:
if(servo2<250)
{
servo2= servo2+5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo2);
}
break;
case 3:
if(servo3<250)
{
servo3= servo3+5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo3);
}
break;
case 4:
if(servo4<250)
{
servo4= servo4+5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo4);
}
break;
case 5:
if(servo5<250)
{
servo5= servo5+5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo5);
}
break;
case 6:
if(servo6<250)
{
servo6= servo6+5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo6);
}
break;
case 7:
if(servo7<250)
{
servo7= servo7+5;;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo7);
}
break;
case 8:
if(servo8<250)
{
servo8= servo8+5;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo8);
}
break;
case 9:
if(servo9<250)
{
servo9= servo9+5;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo9);
}
break;
case 10:
if(servo10<250)
{
servo10= servo10+5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo10);
}
break;
case 11:
if(servo11<250)
{
servo11= servo11+5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo11);
}
break;
case 12:
if(servo12<250)
{
servo12= servo12+5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo12);
}
break;
case 13:
if(servo13<250)
{
servo13= servo13+5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo13);
}
break;
case 14:
if(servo14<250)
{
servo14= servo14+5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo14);
}
break;
case 15:
if(servo15<250)
{
servo15= servo15+5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo15);
}
break;
case 16:
if(servo16<250)
{
servo16= servo16+5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo16);
}
break;
case 17:
if(servo17<250)
{
servo17= servo17+5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo17);
}
break;
case 18:
if(servo18<250)
{
servo18= servo18+5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo18);
}
break;*/
}
}
if(tast(&PIND, PORTD5))
{
switch(servochance)
{
case 1:
if(servo1>1)
{
servo1= servo1-5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo1);
}
break;
/*
case 2:
if(servo2>1)
{
servo2= servo2-5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo2);
}
break;
case 3:
if(servo3>1)
{
servo3= servo3-5;
twi_servo(SLAVE_ADRESSE1, servo1, servo2, servo3);
dispz(servochance, servo3);
}
break;
case 4:
if(servo4>1)
{
servo4= servo4-5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo4);
}
break;
case 5:
if(servo5>1)
{
servo5= servo5-5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo5);
}
break;
case 6:
if(servo6>1)
{
servo6= servo6-5;
twi_servo(SLAVE_ADRESSE2, servo4, servo5, servo6);
dispz(servochance, servo6);
}
break;
case 7:
if(servo7>1)
{
servo7= servo7-5;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo7);
}
break;
case 8:
if(servo8>1)
{
servo8= servo8-5;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo8);
}
break;
case 9:
if(servo9>1)
{
servo9= servo9-5;
twi_servo(SLAVE_ADRESSE3, servo7, servo8, servo9);
dispz(servochance, servo9);
}
break;
case 10:
if(servo10>1)
{
servo10= servo10-5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo10);
}
break;
case 11:
if(servo11>1)
{
servo11= servo11-5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo11);
}
break;
case 12:
if(servo12>1)
{
servo12= servo12-5;
twi_servo(SLAVE_ADRESSE4, servo10, servo11, servo12);
dispz(servochance, servo12);
}
break;
case 13:
if(servo13>1)
{
servo13= servo13-5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo13);
}
break;
case 14:
if(servo14>1)
{
servo14= servo14-5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo14);
}
break;
case 15:
if(servo15>1)
{
servo15= servo15-5;
twi_servo(SLAVE_ADRESSE5, servo13, servo14, servo15);
dispz(servochance, servo15);
}
break;
case 16:
if(servo16>1)
{
servo16= servo16-5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo16);
}
break;
case 17:
if(servo17>1)
{
servo17= servo17-5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo17);
}
break;
case 18:
if(servo18>1)
{
servo18= servo18-5;
twi_servo(SLAVE_ADRESSE6, servo16, servo17, servo18);
dispz(servochance, servo18);
}
break;*/
}
}
}
}
funktionen.c
Code:
unsigned char twi_servo(unsigned char slave_adr, unsigned char servo1,unsigned char servo2,unsigned char servo3)
{
if(!(twi_start(slave_adr+0)))
{
twi_senden(0x00);
_delay_ms(10);
twi_senden(servo1);
_delay_ms(10);
twi_senden(servo2);
_delay_ms(10);
twi_senden(servo3);
_delay_ms(10);
twi_stop();
return 1;
}
return 0;
}
void twi_init(void)
{
DDRC &= !((1<<DD0) | (DD1));
PORTC = (1<<DD0) | (1<<DD1);
TWSR = 0x00; //Prescaler
TWBR = 12; //TWI 400khz
//Hintergrundbeleuchtung on
PORTA |= (1<<PORTA0);
//Initialisieren des Displays, Cursor off
lcd_init(LCD_DISP_ON);
//Display löschen, Cursor i Zeile, 1 Spalte
lcd_clrscr();
//Cursor auf 1 Zeile, 3 Buchstaben
lcd_gotoxy(0,0);
//String ausgeben
lcd_puts("I2C ");
//Cursor auf 2 Zeile, 3 Buchstaben
lcd_gotoxy (0, 1);
//String ausgeben
lcd_puts("Initialisieren");
//~3s warten
_delay_ms(1000);
//Display off
lcd_init(LCD_DISP_OFF);
//Hintergrundbeleuchtung off
PORTA &= ~(1<<PORTA0);
}
unsigned char twi_start(unsigned char adresse)
{
uint8_t twst;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //TWI aktivieren und Start condition auslösen
while(!(TWCR & (1<<TWINT))); //Warten auf Start condition
twst = TW_STATUS & 0xF8;
//if((TWSR & 0xF8) != 0x08);
if ((twst != TW_START) && (twst != TW_REP_START))return 1;
TWDR = adresse; //Adresse mit Schreibbit(xxxxxxx0) in Register
TWCR = (1<<TWINT) | (1<<TWEN); //senden
//if((TWSR & 0xF8) != 0x18);
while(!(TWCR & (1<<TWINT))); //warten auf ACK oder NACK
twst = TW_STATUS & 0xF8;
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) return 1;
return 0;
}
unsigned char twi_rep_start(unsigned char adresse)
{
return twi_start(adresse);
}
unsigned char twi_senden(unsigned char daten)
{
uint8_t twst;
TWDR = daten; //Byte in Datenregister laden
TWCR = (1<<TWINT) | (1<<TWEN); //senden
while (!(TWCR & (1<<TWINT))); //warten auf ACK oder NACK
twst = TW_STATUS & 0xF8;
if(twst != TW_MT_DATA_ACK) return 1;
return 0;
}
unsigned char twi_lesenAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
unsigned char twi_lesenNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
void twi_stop(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while(TWCR & (1<<TWSTO));
}
/*----------------------------------------------------------------------------------------*/
//Display ausgaben
/*----------------------------------------------------------------------------------------*/
void dispz(const char zahl1, const char zahl2)
{
char text1[17];
char text2[17];
itoa(zahl1, text1, 10);
itoa(zahl2, text2, 10);
//Initialisieren des Displays, Cursor off
lcd_init(LCD_DISP_ON);
//Display löschen, Cursor i Zeile, 1 Spalte
lcd_clrscr();
//Cursor auf 1 Zeile, 3 Buchstaben
lcd_gotoxy(0,0);
//String ausgeben
lcd_puts(text1);
//Cursor auf 2 Zeile, 3 Buchstaben
lcd_gotoxy (0, 1);
//String ausgeben
lcd_puts(text2);
_delay_ms(50);
}
int tast(volatile uint8_t *port, uint8_t pin)
{
if(!(*port & (1<<pin)))
{
_delay_ms(100);
if(!(*port & (1<<pin)))
{
_delay_ms(100);
return 1;
}
}
return 0;
}
und der code des Slaves, wobei ich denke das müsste passen:
Code:
#include <avr/io.h> //I/O Port definitions
#include <avr/interrupt.h> //Interrupt macros
#include <util/twi.h> //TWI STATUS
#define F_CPU 16000000UL //CPU Tackt
/*----------------------------------------------------------------------------------------*/
//TWI
/*----------------------------------------------------------------------------------------*/
#define SLAVE_ADRESSE 0x60 //Slaveadresse
#define buffer_size 5 //TWI_empfangsbuffer grösse
//ACK nach empfangenen Daten senden/erwarten
#define TWCR_ACK TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC)
//NACK nach empfangenen Daten senden/erwarten
#define TWCR_NACK TWCR =(1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC)
//wechseln zu nicht adressiertem Slavemodus
#define TWCR_RESET TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC)
uint8_t adresse; //Slaveadresse
volatile uint8_t buffer_adr; //Speicherposition
volatile uint8_t rxbuffer[buffer_size] = {1,1,1,1,1}; //TWI_empfangsbuffer
volatile uint8_t txbuffer[buffer_size] = {1,1,1,1,1}; //TWI_sendenbuffer
/*----------------------------------------------------------------------------------------*/
//PWM
/*----------------------------------------------------------------------------------------*/
//1000 = 1ms(links), 1500 = 1,5ms(mitte), 2000 = 2ms(rechts)
volatile int schulter= 1500;
volatile int huefte = 1500;
volatile int knie = 1500;
void twi_slave(uint8_t adresse); //TWI_Init funktion
void pwm_init(int schulter, int huefte, int knie); //PWM_init Funktion
void pwm_chance(int schulter, int huefte, int knie);//Anpassen der PWM grössen
/*----------------------------------------------------------------------------------------*/
//MAIN AUFRUF
/*----------------------------------------------------------------------------------------*/
int main(void)
{
adresse = SLAVE_ADRESSE; //Slave 1
DDRB = 0xFF; //B... AUSGANG
PORTB &= ~((1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3)); //B.. Low
sei(); //Globale Interupts zulassen
pwm_init(schulter, huefte, knie); //PWM initialisieren
twi_slave(adresse); //TWI initialisieren
while(1)
{
}
}
ISR(TWI_vect) //TWI Interupt (Ausgelöst bei Bus Ereignis)
{
uint8_t daten = 0;
switch(TW_STATUS) //TWI-Statusregister prüfen und agieren
{
case TW_SR_SLA_ACK: //0x60, Slave Receiver wurde adressiert
TWCR_ACK;
buffer_adr = 0xFF;
break;
case TW_SR_DATA_ACK: //0x80, Slave Receiver Daten empfangen
daten = TWDR; //Daten auslesen
if (buffer_adr == 0xFF)
{
if(daten<=buffer_size)
{
buffer_adr = daten;
}
else
{
buffer_adr=0;
}
TWCR_ACK;
}
else
{
rxbuffer[buffer_adr] = daten;
buffer_adr++;
//Zuweisen der neuen PWM werte
schulter = ((rxbuffer[0]*4)+1000);
huefte = ((rxbuffer[1]*4)+1000);
knie = ((rxbuffer[2]*4)+1000);
pwm_chance(schulter, huefte, knie); //PWM grössen anpassen
if (buffer_adr<(buffer_size-1))
{
TWCR_ACK;
}
else
{
TWCR_NACK;
}
}
break;
case TW_ST_DATA_ACK: //0xB8, Slave Transmitter Daten angefordert
if(buffer_adr == 0xFF)
{
buffer_adr = 0;
}
TWDR = txbuffer[buffer_adr];
buffer_adr++;
if(buffer_adr<(buffer_size-1))
{
TWCR_ACK;
}
else
{
TWCR_NACK;
}
break;
case TW_SR_STOP:
default:
TWCR_RESET;
break;
//Ende
}
}
Ich hoffe das reicht an Code, es fehlen Teile wie Headerfiles und funktionen die nichts mit dem Problem zu tun haben.
Lesezeichen