Frequency Division on T2313

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After searching and trying to understand basic timer functions, I am still a little in the dark as to advanced functions. What I am trying to do is divide a variable frequency approx 1.70 - 1.90 MHz (squarewave) by 5600. I can do a 256 followed by a 50 or 100 for a 4 or 8 MHz crystal, but the trigger will need to be input via T0 or T1, then toggle a pin with the divided output. Firstly is it possible to do? Secondly I don't want your code, just an understanding of a "block layout" of how it could be done, with my favorite, the Tiny2313. From what I understand I need to sample the input for a "time", divide that still further to a result. Is this correct? Will it result in the same frequency out, or will it be a variable out "/5600" of the primary trigger input" Thanks for your time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Set your OCR1A to 5600, the clock source to external, the mode to CTC, and any OC1 pin selection you desire.

If you want to use other pins or do things, you will need to have an interrupt service routine.

David. (who has not checked)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Set your OCR1A to 5600, the clock source to external, the mode to CTC, and any OC1 pin selection you desire.

At least it's putting out a "division" of sorts. Trying with a 10M xtal and 10M source. Frequency is 444KHz or so with the attached code. Somewhere I have gone wrong. Any help would be appreciated.

; Save global interrupt flag

	in 		R18,	SREG

; Disable interrupts

	cli

; Set TCNT1 to r17:r16

	ldi		R16,	$01   	; low ÷ By ? | 
	ldi		R17,	$00   	; high  	 | 

	out 	OCR1AH,	R17		; TCNT1 
	out 	OCR1AL,	R16		; TCNT1 

; Restore global interrupt flag

	out 	SREG,	R18
;	ret

WriteTCCR1A:

	ldi		R19,	$40 		; TCCR1A» COM1A Set 
	out		TCCR1A,	R19			; Toggle OC1A Pin On Match

WriteTCCR1B:

	ldi		R20,	$0F			; TCCR1B» WGM12, CS12, CS11 & CS10 Set
	out		TCCR1B,	R20			; CTC Mode, Select External Clock Source On Pin T1, Rising Edge

WriteTCCR1C:

	ldi		R21,	$00			;8 TCCR1C» FOC1A Set
	out		TCCR1C,	R21			; Force Output Compare On Channel A

WriteTIMSK:

	ldi		R22,	$48			; TIMSK» OCIE1A & ICIE1 Set
	out		TIMSK,	R22			; T/C1 Output Compare A Match Interrupt Enable
								; T/C1 Input Capture Interrupt Enable
	sei

Count:	
	 
	rjmp	Count				; Wait For Interrupt

Divide:	
	
	reti
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not too sure how you do the ISR vectors in ASM so I done it in C

#include 
#include 

ISR(TIMER1_COMPA_vect)
{
	// nothing to do cos we have CTC mode
}

int main(void)
{
	OCR1A = 5600;                      // max count
	TCCR1A = (0<<COM1A1)|(1<<COM1A0);  // toggle PB3
//	TCCR1B = (1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10); // CTC CK/1024
	TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS11)|(0<<CS10); // CTC EXTERNAL CLOCK
	TIMSK = (1<<OCIE1A);		   // enable Compare interrupt
	DDRB |= (1<<PB3);				// so we have OC1 as output
	sei();
	while (1) ;
}

I just tested it with an 8MHz internal clock divided by 1024 to flash an LED at 0.7Hz

You may want to set OCR1A to 2800 so that there are 5600 counts per complete output cycle.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems to work so I hope that I have got the Vector table correct. My first ASM program with interrupts !

	.include "tn2313def.inc"

	.org	0
	rjmp	reset
	.org	OC1Aaddr
TIMER1_COMPA_vect:
	reti
	
	.org	INT_VECTORS_SIZE	
reset:
	ldi	R16,LOW(5600)		; low ÷ By ? |
	ldi	R17,HIGH(5600)		; high      

	out	OCR1AH,R17	; TCNT1
	out	OCR1AL,R16	; TCNT1

	ldi	R19,(1<<COM1A0)		; TCCR1A» COM1A Set
	out	TCCR1A,R19	; Toggle OC1A Pin On Match

;	ldi	R20,(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10)	;CK/1024
	ldi	R20,(1<<WGM12)|(1<<CS12)|(1<<CS11)|(1<<CS10)
	out	TCCR1B,R20	; CTC Mode, Select External Clock Source On Pin T1, Rising Edge

	ldi	R21,$00		;8 TCCR1C» FOC1A Set
	out	TCCR1C,R21	; Force Output Compare On Channel A

	ldi	R22,(1<<OCIE1A)	; Set
	out	TIMSK,R22	; T/C1 Output Compare A Match Interrupt Enable

	sbi	DDRB,PB3
		
	sei

Count:

	rjmp	Count		; Wait For Interrupt