Forum: Mikrocontroller und Digitale Elektronik Mpu6050 mit ATtiny817


von Nils K. (flying_nils)


Lesenswert?

Hallo zusammen,
Ich möchte in eine Projekt den Sensor Mpu6050 verwenden und mit dem 
relativ neuen ATtiny817 auswerten. Allerdings gibt es keine fertige 
Library, wie bei Arduino. Ich habe ein I2C Programm aus einem anderen 
Forum gefunden und zu meinem Programm hinzugefügt 
(https://www.avrfreaks.net/comment/2294081).
Dieses Programm hat auch super mit einem angeschlossenen Arduino nano 
funktioniert. Ich habe auch ein Programm zum auslesen vom Mpu6050 
gefunden, das ohne I2C Library auskommt 
(https://www.avrfreaks.net/forum/mpu6050-pure-avr-c-328p-without-library-help-me-please). 
Allerdings musste ich einiges ändern, da I2C bei meinem ATtiny sehr 
verschieden zu benutzen ist. Wie es aussieht, kann ich auf dem Sensor 
schreiben, aber der "Read Interrupt Flag" wird beim Werte lesen nicht 
gesetzt und ich hab keine Ahnung warum. Laut Datenblatt ist meine 
Datenübertragung richtig.
Das ist mein "TWI_Master.c" File:
1
#include <avr/io.h>
2
#include "TWI_master.h"
3
#include "UART.h"
4
#include "General.h"
5
void TWI_init()
6
{
7
  TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000);          // set MBAUD register for 100kHz
8
  TWI0.MCTRLA = 1 << TWI_ENABLE_bp      /* Enable TWI Master: enabled */
9
  | 0 << TWI_QCEN_bp          /* Quick Command Enable: disabled */
10
  | 0 << TWI_RIEN_bp          /* Read Interrupt Enable: disabled */
11
  | 1 << TWI_SMEN_bp          /* Smart Mode Enable: enabled */
12
  | TWI_TIMEOUT_DISABLED_gc        /* Bus Timeout Disabled */
13
  | 0 << TWI_WIEN_bp;          /* Write Interrupt Enable: disabled */
14
15
  TWI0.MCTRLB |= TWI_FLUSH_bm ;        /* Purge MADDR and MDATA */
16
  TWI0.MSTATUS |= TWI_BUSSTATE_IDLE_gc ;            //Force TWI state machine into IDLE state
17
  TWI0.MSTATUS |= (TWI_RIF_bm | TWI_WIF_bm) ;
18
}
19
20
uint8_t TWI_start(uint8_t deviceAddr)
21
{
22
  if ((TWI0.MSTATUS & TWI_BUSSTATE_gm) != TWI_BUSSTATE_BUSY_gc)    //Verify Bus is not busy
23
  {
24
    TWI0.MCTRLB &= ~(1 << TWI_ACKACT_bp);
25
    TWI0.MADDR = deviceAddr ;
26
    printString("bw");
27
    if (deviceAddr&0x01)  {while(!(TWI0.MSTATUS & TWI_RIF_bm));}  
28
    else      {while(!(TWI0.MSTATUS & TWI_WIF_bm));}  
29
    printString("aw");
30
    return 0;
31
  }
32
  else return 1;                                                          //Bus is busy
33
}
34
35
uint8_t TWI_read(uint8_t ACK)              // ACK=1 send ACK ; ACK=0 send NACK
36
{
37
38
  if ((TWI0.MSTATUS & TWI_BUSSTATE_gm) == TWI_BUSSTATE_OWNER_gc)    //Verify Master owns the bus
39
  {
40
    while(!(TWI0.MSTATUS & TWI_RIF_bm));        // Wait until RIF set
41
    uint8_t data=TWI0.MDATA;
42
    if  (ACK==1)  {TWI0.MCTRLB &= ~(1<<TWI_ACKACT_bp);}    
43
    else      {TWI0.MCTRLB |= (1<<TWI_ACKACT_bp);  }  
44
    USART_write((uint8_t)data);
45
    return data ;
46
  }
47
  else
48
  return 1;  //Master does not own the bus
49
50
}
51
uint8_t TWI_WRITE(uint8_t write_data)
52
{
53
  if ((TWI0.MSTATUS&TWI_BUSSTATE_gm) == TWI_BUSSTATE_OWNER_gc)                      //Verify Master owns the bus
54
  {
55
    TWI0.MDATA = write_data;
56
    while (!((TWI0.MSTATUS & TWI_WIF_bm) | (TWI0.MSTATUS & TWI_RXACK_bm))) ;    //Wait until WIF set and RXACK cleared
57
    return 0;
58
  }
59
  else
60
  return 1;  //Master does not own the bus
61
}
62
uint8_t TWI_RW(uint8_t reg, uint8_t addrW, uint8_t addrR)
63
{
64
  TWI_start(addrW, 0);
65
  TWI_WRITE(reg);
66
  TWI_start(addrR, 1);
67
  uint8_t result = TWI_read(1);
68
  TWI_STOP();
69
  return (result);
70
}
71
void TWI_STOP(void)
72
{
73
  TWI0.MCTRLB |= TWI_ACKACT_NACK_gc;
74
  TWI0.MCTRLB |= TWI_MCMD_STOP_gc;
75
}
76
int Mpu6050_Setup()
77
{
78
  //START i2c
79
  //startI2c();//Just rate of i2c
80
81
  //WRITE MPU6050
82
  Mpu6050_writeReg (0x19, 0b00000111);//WRITE Sample Rate Divider
83
  Mpu6050_writeReg (0x6b, 0b00000001);//WRITE Power Management 1
84
  Mpu6050_writeReg (0x1b, 0b10000000);//WRITE Gyroscope Configuration (1000°/s)
85
  return(0);
86
}
87
void Mpu6050_writeReg (const uint8_t ADDRESS, const uint8_t DATA)
88
{
89
  TWI_start(Sensor_Write, 0);
90
  TWI_WRITE(ADDRESS);
91
  TWI_WRITE(DATA);
92
  TWI_STOP();
93
}

Hier ist mein "main.c" File:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include "TWI_master.h"
5
#include "UART.h"
6
#include "General.h"
7
8
volatile uint32_t TCA_t_counter = 200; // Counter variable
9
volatile uint32_t Delay1_time = 200000; // Delay1 delay value
10
volatile uint32_t Delay1_old = 0; // Delay1 old counter value
11
12
void timerAInit(void);
13
void clkInit(void);
14
15
void clkInit(void){
16
  CPU_CCP = 0xD8;
17
  CLKCTRL.MCLKCTRLA |= (1<<7); // Enables CLKOUT
18
  CPU_CCP = 0xD8;
19
  CLKCTRL.MCLKCTRLA &= ~(1<<0) & ~(1<<1); //Selects OSC20M as main clock source
20
  CPU_CCP = 0xD8;
21
  CLKCTRL.MCLKCTRLB &= ~(1<<0); //Disables main clock prescaler
22
  CPU_CCP = 0xD8;
23
  CLKCTRL.OSC20MCTRLA |= (1<<1); //Lets OSC20M run in standby
24
}
25
void timerAInit(void)
26
{
27
  TCA0.SINGLE.PER = 96; // Set prescaler to 96
28
  TCA0.SINGLE.CTRLA |= (TCA_SINGLE_CLKSEL_DIV1_gc) | (TCA_SINGLE_ENABLE_bm); // Enable TCA0 and set CLKDIV to 8
29
  TCA0.SINGLE.INTCTRL |= (TCA_SINGLE_OVF_bm);  // Enable interrupt
30
}
31
ISR(TCA0_OVF_vect)
32
{
33
  //PORTC.OUTTGL |= (1<<0); //Test Signal
34
  TCA_t_counter ++; // Increases the TCA0 Counter
35
  TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; //Clears the TCA0 interrupt
36
}
37
38
int main(void)
39
{
40
  PORTB.DIR |= (1<<0) | (1<<1) | (1<<5);
41
  PORTC.DIR |= (1<<0);
42
  TWI_init();
43
  clkInit();
44
  USART_init();
45
  timerAInit();
46
  sei(); // Enable global interrupts
47
  Mpu6050_Setup();
48
  
49
  while (1)
50
  {
51
    if(TCA_t_counter >= Delay1_old + Delay1_time){
52
      printString(" Hallo ");
53
      Delay1_old = TCA_t_counter;
54
      int rawGyroZ = TWI_RW (0x3f, Sensor_Write, Sensor_Read);
55
      PORTC.OUTTGL |= (1<<0); //Test Signal
56
      USART_write((int)rawGyroZ);
57
      
58
      //   int rawAccX = readI2c (0x43);
59
      //   int rawAccY = readI2c (0x45);
60
      //   int rawAccZ = readI2c (0x47);
61
      //  int rawGyroX = readI2c (0x3b);
62
      //   int rawGyroY = readI2c (0x3d);
63
      //   int rawGyroZ = readI2c (0x3f);
64
      //   int rawTemperature = readI2c (0x41);
65
      
66
    }
67
  }
68
}
Ich habe ertestet, dass der Chip bei der while-Schleife in der Funktion 
"TWI_start" hängenbleibt. Wenn man diese auskommentiert, hängt er in der 
while-Schleife in der Funktion "TWI_read" fest.
Hat jemand eine ahnung, warum der RIF nicht gesetzt wir, oder was ich 
falsch mache?
Danke für die Hilfe,
Nils

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.