Advertisement
Guest User

Summensignal I2C (mit Arrays)

a guest
Jun 20th, 2011
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.70 KB | None | 0 0
  1. /*
  2.  * main.c
  3.  *
  4.  *  Created on: 18.06.2011
  5.  *      Author: peka
  6.  */
  7.  
  8. //#define F_CPU = 20MHz //(ext Crystal)
  9.  
  10. // Defines
  11. #define setBit(ADDRESS, BIT)    (ADDRESS |=  (1<<BIT))
  12. #define clrBit(ADDRESS, BIT)    (ADDRESS &=  ~(1<<BIT))
  13. #define tglBit(ADDRESS, BIT)    (ADDRESS ^=  (1<<BIT))
  14. #define getBit(ADDRESS, BIT)    ((ADDRESS & (1<<BIT))?1:0)
  15. #define lowByte(WORD)           ((uint8_t)(WORD))
  16. #define highByte(WORD)          ((uint8_t)(((uint16_t)(WORD)) >> 8))
  17. #define getWord(HIGH,LOW)       (((uint16_t)HIGH << 8) | LOW)
  18.  
  19. #define TWI_ADDR                20 <<1    // --> Address 20
  20. // Includes
  21. #include <avr/io.h>
  22. #include <avr/interrupt.h>
  23. #include "usiTwiSlave.h" //I2C Lib
  24. // Global Vars
  25. volatile uint16_t timerCounter = 0;
  26. volatile uint16_t pulseTimer = 0;
  27. volatile uint8_t servoIndex = 0;
  28. volatile uint16_t servoPos[] =
  29. { 0, 0, 0, 0, 0, 0, 0, 0 };
  30. volatile uint16_t syncTime = 0;
  31. volatile uint8_t updateFlag = 0;
  32.  
  33. // Main Program
  34. int main(void)
  35. {
  36.     // Timer 1
  37.     setBit(TCCR1, CS10);
  38.     setBit(TCCR1, CS12); // Prescaler 16 - 800ns Auflösung
  39.     setBit(TIMSK, OCIE1A); // Timer/Counter1, Output Compare A Match Interrupt Enable
  40.     OCR1A = 250; // 200µs
  41.  
  42.     // RCRx Interrupt
  43.     clrBit(DDRB, PB1); //Input
  44.     setBit(PORTB, PB1); //int. Pullup
  45.     setBit(GIMSK, PCIE); //Pin Change Interrupt Enable
  46.     PCMSK = 0x00;
  47.     setBit(PCMSK, PCINT1); //Enable PCINT only on PB1
  48.  
  49.     // TWI
  50.     usiTwiSlaveInit(TWI_ADDR); // TWI starten
  51.     for (int i = 0; i < 24; i++) // Buffer füllen
  52.         txbuffer[i] = 0xFF;
  53.  
  54.     // Interrupts aktivieren
  55.     sei();
  56.  
  57.     // Hauptprogrammschleife
  58.     while (1)
  59.     {
  60.         while (updateFlag == 0)
  61.         {
  62.             ; //warte auf neue servoPosition
  63.         }
  64.  
  65.         txbuffer[0] = 0; //dataReady Flag
  66.         for (uint8_t i = 0; i < 7; i++)
  67.         {
  68.             txbuffer[1 + 2 * i] = highByte(servoPos[i]);
  69.             txbuffer[1 + 2 * i + 1] = lowByte(servoPos[i]);
  70.         }
  71.         txbuffer[17] = highByte(syncTime);
  72.         txbuffer[18] = lowByte(syncTime);
  73.         txbuffer[0] = 1; //dataReady Flag
  74.  
  75.         updateFlag = 0;
  76.     }
  77. }
  78.  
  79. ISR( TIMER1_COMPA_vect )
  80. {
  81.     TCNT1 = 0;
  82.     pulseTimer++; // 1 tick = 200µs
  83. }
  84.  
  85. ISR( PCINT0_vect )
  86. {
  87.     if (getBit(PINB, PB1) == 0) //reagiere nur auf fallende Flanke
  88.     {
  89.         uint16_t pulseTimerFraction = 4 * TCNT1 / 5;
  90.         uint16_t pulseTime = pulseTimer * 200 + pulseTimerFraction; // 1 tick = 1µs
  91.  
  92.         TCNT1 = 0; // timer zurücksetzen
  93.         pulseTimer = 0;
  94.  
  95.         if (pulseTime > 3000) //Pulspause > 3000µs --> Sync
  96.         {
  97.             servoIndex = 0; //nächster Puls wird wieder die länge von Servo0 angeben
  98.             syncTime = pulseTime;
  99.             updateFlag = 1; //servowerte dürfen in der hauptschleife ins i2c buffer geschrieben werden
  100.         }
  101.         else if (servoIndex < 8)
  102.         {
  103.             servoPos[servoIndex] = pulseTime;
  104.             servoIndex++; //nächster Puls wird nächsten Servowert geben oder sync sein.
  105.         }
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement