Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * pwm8.c
- *
- * Created on: 10.03.2019
- * Author: harry
- */
- #include "avr/io.h"
- #include <avr/interrupt.h>
- #include <stdio.h>
- #include "uart.h"
- #include "pwm8.h"
- #define LED_NUM 8// must be a multiple of 8
- #define DEBUG
- #define LATCH_PIN PB1 // STCP
- #define OE_PIN PB2 // OE
- #define MOSI_PIN PB3 // Din
- #define CLK_PIN PB5 // SHCP
- #define PORT_DIR DDRB
- #define OUT_PORT PORTB
- #define LATCH() OUT_PORT |= (1 << LATCH_PIN),OUT_PORT &= ~(1 << LATCH_PIN)
- #ifdef DEBUG
- #define TRIGGER_PIN PD2 // Debug-pin for triggering
- #define TRIGGER_DIR DDRD
- #define TRIGGER_PORT PORTD
- #define TRIGGER() TRIGGER_PORT ^= (1 << TRIGGER_PIN) //,PULSE_PORT &= ~(1 << TRIGGER_PIN)
- #endif
- #define TIM_BSY() tim_bsy = TRUE
- #define TIM_RDY() tim_bsy = FALSE
- #define SPI_BSY() spi_bsy = TRUE
- #define SPI_RDY() spi_bsy = FALSE
- /*
- * timingg-setting
- */
- #define DEADTIME 8
- static volatile uint8_t pwm_buf[LED_NUM];
- static volatile uint8_t tim_bsy = FALSE;
- static volatile uint8_t spi_bsy = FALSE;
- static volatile uint16_t bit_cnt = 0;
- static volatile uint8_t dummy;
- /*
- * Public Functions
- */
- void pwm8Init(void)
- {
- // Initialize GPIOs
- PORT_DIR |= ((1 << LATCH_PIN) | (1 << OE_PIN)
- | (1 << MOSI_PIN) | (1 << CLK_PIN)); // define Outputs
- #ifdef DEBUG
- TRIGGER_DIR |= (1 << TRIGGER_PIN);
- #endif
- OUT_PORT &= ~((1 << LATCH_PIN) | (1 << OE_PIN)); // Reset Latch and OE
- // Initialize SPI
- SPCR = (1 << SPIE) | (1 << SPE) | (1 << MSTR); // enable SPI
- dummy = SPSR; // clear pending interrupts
- dummy = SPDR;
- // Initialize Timer
- TCCR1A = 0;
- TCCR1A = (1 << COM1B1) | (1 << WGM11);
- TCCR1B = (1 << WGM12) | (1 << WGM13)
- | (1 << CS11) | (1 << CS10); // fast PWM-Mode
- TCNT1 = 0;
- GTCCR = ((1 << PSRSYNC) | (1 << TSM) | (1 << PSRASY)); // disable & synchronize prescaler
- TIFR1 = (1 << OCF1B); // clear any pending interrupt
- TIMSK1 = (1 << ICIE1);// | (1 << TOIE1); // enable OC0A interrupt
- sei();
- // Start first SPI-transfer
- SPDR = pwm_buf[bit_cnt];
- SPI_BSY();
- }
- /*
- * Set LED Nr. lednr
- * to PWM-Value pwm_val
- */
- void pwm8SetLED(uint8_t lednr, uint8_t pwm_val)
- {
- uint8_t pwm_mask, led_mask;
- pwm_mask = 1;
- led_mask = 1 << lednr;
- for (uint8_t i = 0; i < 8; i++)
- {
- if ((pwm_val & pwm_mask) == 0)
- {
- pwm_buf[i] = pwm_buf[i] | led_mask;
- }
- else
- {
- pwm_buf[i] = pwm_buf[i] & ~led_mask;
- }
- pwm_mask <<= 1;
- }
- }
- /*
- * Private Functions
- */
- // sart next Cycle
- static void pwm8KickCycle(void)
- {
- LATCH(); // enable new data
- #ifdef DEBUG
- if (bit_cnt == 0)
- TRIGGER();
- #endif
- // setup one-pulse-timer
- ICR1 = (1 << bit_cnt) + DEADTIME;
- OCR1B = DEADTIME;
- TCNT1 = 0;
- GTCCR = 0; // enable Prescaler and start Timer
- TIM_BSY(); // timer running
- bit_cnt = (bit_cnt +1) & 0b00000111; // advance to next cycle
- SPDR = pwm_buf[bit_cnt]; // send next pattern in advance
- SPI_BSY(); // SPI running
- }
- /*
- * Interrupts
- *
- */
- // SPI-Interrupt
- ISR( SPI_STC_vect )
- {
- dummy = SPDR;
- SPI_RDY();
- if (tim_bsy == FALSE)
- pwm8KickCycle();
- }
- // Timer Interrupt
- ISR( TIMER1_CAPT_vect )
- {
- GTCCR = (1<<TSM) | (1<<PSRASY) | (1<<PSRSYNC); // halt all timers
- TIM_RDY();
- if (spi_bsy == FALSE)
- pwm8KickCycle();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement