Advertisement
Christof_Ermer

PWM_LED_SPI_75595.ino

Dec 12th, 2019
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.11 KB | None | 0 0
  1. /*
  2. PWM  mit Shift Baustein 74595
  3. Speichere dies als
  4. PWM_LED_SPI_75595.ino
  5. und öffne es mit der SKETCH Oberfläche
  6. */
  7.  
  8.  //#include <util/delay.h>
  9. #include <avr\wdt.h>
  10.  
  11. #define  DEF_OCR2A_COMP_VALUE  54
  12. #define TWO_CYCLES() __asm__ __volatile__( "rjmp 1f\n 1:" ) // 2 cycles
  13.  
  14. #ifndef SPI_SHIFTOUT_74_595_HEADER
  15.   #define SPI_SHIFTOUT_74_595_HEADER
  16.  
  17. //SPI_BUS ATMega328p
  18. #define SCK_PIN   PB5
  19. #define MISO_PIN  PB4
  20. #define MOSI_PIN  PB3
  21. #define SS_PIN    PB2
  22.  
  23. #define SPI_DDRX                DDRB
  24. #define SPI_PORTX               PORTB
  25. #define TTL74595_DS_PIN_NR      MOSI_PIN  //DATA
  26. #define TTL74595_SH_CP_PIN_NR   SCK_PIN //SCK
  27. #define TTL74595_ST_CP_PIN_NR   SS_PIN //RCK
  28.  
  29. //PINS
  30. #define DS_TTL74595     (1<< TTL74595_DS_PIN_NR  )   // DATA
  31. #define SH_CP_TTL74595  (1<< TTL74595_SH_CP_PIN_NR ) //SCK
  32. #define ST_CP_TTL74595  (1<< TTL74595_ST_CP_PIN_NR )  // Store / RCK
  33.  
  34. #define OUT_TTL74595_RCK_HIGH() (SPI_PORTX |= ST_CP_TTL74595)
  35. #define OUT_TTL74595_RCK_LOW()  (SPI_PORTX &= ~ST_CP_TTL74595)
  36.  
  37. #endif //SPI_SHIFTOUT_74_595_HEADER
  38.  
  39. // *************************************************************************************
  40. //GLOBAL
  41. volatile uint8_t gu8LedPWM[8];
  42. // *************************************************************************************
  43.  
  44. // *******************************
  45. void SPI_SlaveInit(void)
  46. // *******************************
  47. {
  48. /* Set MISO output, all others input */
  49. PRR &= ~(1<<PRSPI);  //POWER ON SPI
  50. /* Enable SPI */
  51. //SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //fosc/4
  52. SPI_DDRX |= DS_TTL74595 | SH_CP_TTL74595  | ST_CP_TTL74595;
  53. }
  54.  
  55. // *********************************************
  56. ISR( SPI_STC_vect  )  //SPI Transfer complete
  57. // *********************************************
  58. {
  59. OUT_TTL74595_RCK_HIGH(); // Latch Data to Output
  60. __asm__ __volatile__( "rjmp 1f\n 1:" ); // 2 cycles
  61. OUT_TTL74595_RCK_LOW();
  62. };
  63.  
  64. // **************************************
  65. void SPI_TTL74595( uint8_t u8Val )  //uint16_t uint32_t
  66. // **************************************
  67. {
  68.   //S:174
  69.   SPDR = ~u8Val; // Mache Komplement, weil LED_ LIEGET AN PLUS
  70.   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0) | (1<<SPIE); //fosc/4  + SPI Interrupt
  71. };
  72.  
  73.  
  74. //Für Test mit Oszi:
  75. void ToogleBit(void)
  76. {
  77.   DDRC |= 0x01;
  78.   PORTC |= 0x01;
  79.     //TWO_CYCLES();
  80.   _delay_us(2);
  81.   PORTC &= ~0x01;  
  82. }
  83.  
  84. // ****************************************************************
  85.   //ISR( TIMER2_OVF_vect )
  86. ISR( TIMER2_COMPA_vect )
  87. // *******************************************************************
  88. {
  89.  volatile uint8_t u8NN;
  90.   //uint8_t u8Sreg = SREG;  
  91.  volatile static uint8_t u8Periode=0;
  92.  volatile static uint8_t u8Val=0xFF;
  93.   if( !u8Periode  ) //== 0
  94.     {
  95.     u8Val=0xFF;
  96.     }
  97.   else
  98.     {
  99.     for( u8NN=0; u8NN < 8; u8NN++)
  100.       {//Clear passenden OutBit if Match
  101.        if( gu8LedPWM[u8NN] == u8Periode )
  102.         {
  103.         u8Val &= ~(1 << u8NN);
  104.         };
  105.       }
  106.     };
  107.   //S:174
  108.   SPDR = ~u8Val; // Mache Komplement, weil LED_ LIEGET AN PLUS
  109.   SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<SPIE); //fosc/4  + SPI Interrupt
  110.  //SPI_TTL74595(u8Val);
  111.  u8Periode++; //u8 Interrupt Durchlaufzähler mit 0
  112.  //SREG = u8Sreg;
  113. };
  114.  
  115. // ************************
  116. int main(void)
  117. // ************************
  118. {  // put your main code here, to run repeatedly:
  119. uint8_t u8NN;
  120. uint8_t u8FF;
  121. uint8_t u8MemVal;
  122.  
  123. //wdt_enable(WDTO_500MS); //WatchDog ENABLE
  124. wdt_disable();
  125. for( u8NN=0; u8NN < 8; u8NN++)
  126.   {
  127.     gu8LedPWM[u8NN] = u8NN *32;
  128.   };
  129.    
  130. SPI_SlaveInit();
  131.    
  132.   TCNT2 = 0;  
  133. //COMP SECTION
  134.   OCR2A =  DEF_OCR2A_COMP_VALUE;  //?? >50%
  135.   TCCR2A= (1<<WGM21); //CTC Mode
  136.   TIMSK2 = (1 << OCIE2A);
  137.  TCCR2B = (1 << CS21); // CLOCK /8
  138.  
  139. while(1)
  140.   {
  141. //ToogleBit();  // Trigger für Test Oszi
  142. //wdt_reset();  //WATCHDOG!
  143.  
  144. //Erzeuge 8 Sinus Modulationen für 8 PWM Bits mit Phasenabstand 265/8 =32
  145.   u8NN++;  //Phasenschieber
  146.   for(u8FF=0; u8FF < 8; u8FF++)
  147.     {
  148.       u8MemVal = 128 + 127*sin(2*M_PI*(((uint8_t)(u8NN+(u8FF*32)))/256.0));
  149.      //Damits schnell geht ohne Rechnung
  150.      cli();
  151.      gu8LedPWM[u8FF] = u8MemVal;
  152.      //gu8LedPWM[u8FF] = 70;
  153.      sei();
  154.     };
  155.   _delay_ms(5);
  156.   };
  157.  };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement