Using PWM with the ATtiny84

So, A couple of days ago I posted in regards to Debouncing hardware button press using the Atmel family. The reason why I needed to do this was because I was planning to send a pulse width modulation signal to an H-bridge controller. Now in your Int Main you need to initialize the parameters of your pulse width modulation, you can do that with the following of declared below in my main. Once done I used a interrupt request to then trigger that I pressed on the button and in this case a gas pedal. I then needed to bounce a gas pedal like I spoke about previously then from there increment OCRoA register from 0 to 255. Once done I then check to see if they gas pedal has been released and then set the register back to zero to halt the H-bridge from powering the motor. The example below should be hopefully straightforward. Good Luck
int main(void)
{
TCCR0A = (1 << COM0A1) | (1 << WGM00); // phase correct PWM mode
OCR0A = 0x00; // initial PWM pulse width
TCCR0B = (1 << CS01); // clock source = CLK/8, start PWM
//https://thewanderingengineer.com/2014/08/11/pin-change-interrupts-on-attiny85/
GIMSK = 0b00100000; // turns on pin change interrupts AKA PCIE. Pg.60 also for INT0 for the button press
PCMSK = 0b00000001; // turn on interrupts on pin PCINT0 aka PB0 for Gas and reverse
sei(); // enables interrupts
}
ISR(PCINT0_vect)
{
//PCMSK = 0b00000000; // turn on interrupts on pin PCINT0 aka PB0
debouncer = 0;
if (REVSWITCH_PIN & (1 << REVSWITCH_BIT))
{ // is switch open? Forward and reverse Switch
DIR_PORT |= (1 << DIR_BIT); // Pin n goes high
}
else
{
DIR_PORT &= ~(1 << DIR_BIT); // Pin n goes low
}
if (GAS_PIN & (1 << GAS_BIT))
{ // is switch open?
while (debouncer != 100 )
{
if (!(GAS_PIN & (1 << GAS_BIT)))
{
lcd_write_instruction_4d(lcd_Clear);
_delay_us(80);
lcd_write_instruction_4d(lcd_SetCursor | lcd_LineOne);
_delay_us(80);
lcd_write_string_4d(“Debounced”);
_delay_us(80);
return;
}
_delay_us(200);
debouncer++;
}
lcd_write_instruction_4d(lcd_Clear);
_delay_us(80);
for(int i=0;i<=0xff;i++)
{
if (!(GAS_PIN & (1 << GAS_BIT)))
{
return;// is switch open?
}
//_delay_ms(AccelerateSleepTimer);
OCR0A = i;
_delay_us(40); // 40 uS delay (min)
char str[4];
itoa(i, str, 10);
//lcd_write_instruction_4d(lcd_Clear);
//_delay_us(200); // 40 uS delay (min)
lcd_write_instruction_4d(lcd_SetCursor | lcd_LineOne);
_delay_us(80);
if (REVSWITCH_PIN & (1 << REVSWITCH_BIT))
{
lcd_write_string_4d(“Accelerating REV”);
}
else
{
lcd_write_string_4d(“Accelerating”);
}
// 40 uS delay (min)
_delay_us(40); // 40 uS delay (min)
lcd_write_instruction_4d(lcd_SetCursor | lcd_LineTwo);
_delay_us(40); // 40 uS delay (min)
lcd_write_string_4d(str);
}
//Clear the Pin Change Interrupt flag so it does not trigger a 2nd time.
GIFR |= (1<<PCIF0); //PCIFR |= (1<<PCIF2);
}
else
{
OCR0A = 0x00;
lcd_write_instruction_4d(lcd_SetCursor | lcd_LineTwo);
_delay_us(80); // 40 uS delay (min)
lcd_write_string_4d(“Stopped”);
}
//PCMSK = 0b00000011; // turn on interrupts on pin PCINT0 aka PB0
}

Leave a comment

Your email address will not be published. Required fields are marked *