Tiny416 Timer B one shot off prescaled Timer A clock

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Trying to learn this new AVR1 thing with ATtiny416 Xplained Nano, it fits a breadboard. I have a LED on Counter A running 500ms high, 500 low. Fused to 16Mhz/4 because 3.33Mhz offends my sensibilities for some reason. And I want to One Shot Counter B, starting it with a button and stopping it in ISR. That works and I want to run B off the pre-scaled clock input to Counter A. Smmes like the tiny book says I can @ 21.3.3.4 "In this setting the TCB will count either on the prescaled clock signal from TCA0". And my choices are 21.5.1 " CLK_PERCLK_PER / 2 and Use CLK_TCA from TCA0. But all three choices are 16ms on the LED here. Any help with this and critic of my general methods appreciated.

 

--John

 

 #include <avr/io.h>
 #include <avr/interrupt.h>
// #define F_CPU 4117000 //@ 75F 
 
void setup_pins();
void setup_timers();

int main(void)//*********************************************************
{
  // CCP = CCP_IOREG_gc; 
  // CLKCTRL_MCLKCTRLA = 128;  // output main clock for scope
	 CCP = CCP_IOREG_gc;       // enable CLKCTRL write
	 CLKCTRL_MCLKCTRLB  = 3;   // set clock/4 for 4Mhz
	 sei();                    // enable global interrupts
	setup_pins();
	setup_timers();	
     
    while (1) //********************************************************
    {
	if(!(PORTA_IN & PIN1_bm)) // if button pressed
	{		
	while(!(PORTA_IN & PIN1_bm));// let go the button	
	PORTC.OUTCLR = PIN1_bm;	// Low turns on LED 1	
	TCB0.CTRLA = 1 << TCB_ENABLE_bp;   // Enable counter	
	}
    }
}

ISR(TCA0_OVF_vect)// counter A heartbeat LED 2 *************************
{	
	PORTA.OUTTGL = PIN2_bm;//  LED 2 toggle	
	TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}

ISR(TCB0_INT_vect){ // Counter B ***************************************
 	
	PORTC.OUTSET =  PIN1_bm;// high turns off LED 1	
	TCB0.CTRLA = 0 << TCB_ENABLE_bp; // Disable counter
	TCB0_CNT = 0; // Set counter to bottom
	TCB0.INTFLAGS = 1; // Clear Interrupt	
}

void setup_pins()//*****************************************************
{
	PORTC.OUTSET =  PIN1_bm;// high turns off LED 1	
	PORTC.DIRSET = PIN1_bm; // LED 1	
	PORTA.DIRSET = PIN2_bm;//  LED 2 toggles on counter A	 	
	
	PORTA.PIN1CTRL = PORT_PULLUPEN_bm;// Button  
	  
}

void setup_timers()//****************************************************
{	 
	TCA0.SINGLE.PER = 2010; //counter TOP	 
	TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc // use main clock/1024
	| TCA_SINGLE_ENABLE_bm; // enable counter
	TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm; // counter TOP runs ISR	
	
	TCB0_CCMP = 0xffff; // counter TOP
	TCB0.CTRLA = TCB_CLKSEL_CLKTCA_gc   // 16ms 
	//TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc  // 16ms
	//TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc    // 16ms   
	| 0 << TCB_ENABLE_bp   // Disable counter
	| 0 << TCB_RUNSTDBY_bp //  '1' counter runs in Standby sleep mode
	| 0 << TCB_SYNCUPD_bp; //  '1', TCB will restart whenever TCA is restarted
		
	TCB0.CTRLB = 1 << TCB_ASYNC_bp  // Asynchronous Enable for Single Shot Mode 
	| 0 << TCB_CCMPINIT_bp  // set the initial output when a pin output is used
	| 0 << TCB_CCMPEN_bp    // Pin Output disabled	 
	| TCB_CNTMODE_SINGLE_gc;  // Single Shot Mode 	
	
	 TCB0.INTCTRL = 0x01; // counter TOP runs ISR	 
}