Atmega8 - Max output frequency seems to be devide by 4... - Page 1
Forum section: electronics / general

author: CrH
author_rank: Newbie
timestamp: February 11, 2016, 04:20:57 pm
content: Hi everyone,I'm a little bit confuse, and hope that someone here can point me out what I'm missing...I'm using an Atmega8-16PU,Flashed the fuse with :avrdude -b 19200 -c avrisp -P /dev/tty.usbserial-A9IHTRVJ -p atmega8 -U lfuse:w:0xe4:m -U hfuse:w:0xd9:mwhich means.. according tohttp://www.engbedded.com/fusecalc/that I'm using int. osc 8MhzIn my code, I override OSCAL to OSCCAL = 0xFF; in order to work at its max frequency.nevertheless, in a for loop (also tried with a 'while'), I'm only toggling a pin LED1_STATE^=(1<<LED1_PIN);and I'm measuring 1.6Mhz ...I was thinking that AVR where able to execute one instruction by system clock... here it seems that the FCPU is divided by 4..-----I also tried using Timer0 and its overflow interrupt with ;Code:TCNT0 = 254;TIMSK |= (1<<TOIE0); // enable interruptTCCR0 = 0x01; //prescaler = 1sei();ISR(TIMER0_OVF_vect){LED1_STATE ^=(1<<LED1_PIN);TCNT0 = 254;}and here the signal output 200Khz ....can someone help me figure it out what is going on ? I am not enough considering the necessary 'instructions' time ?Many thanks internetRegards

author: dannyf
author_rank: Super Contributor
timestamp: February 11, 2016, 10:58:32 pm
content: You have two unrelated questions.In the first case, one C statement may be compiled into multiple Assembly statement. In your case, that plus loop overhead appears to be five statements - check your list file for sure.Avr does provide a single instruction flip - check the gpio part of the data sheet for sure.In the second case, you have iae overhead, 10 to 20 instructions, prescaler, plus the isr execution itself. In your case, you don't have enough time to finish isr execution before it is fired again, because the timer offset is too large.If you want fast output without loading up the mcu, use the pwm generation function to produce 50 percent duty cycle pulse trains.

author: andersm
author_rank: Super Contributor
timestamp: February 11, 2016, 11:19:36 pm
content: For the first case, have you turned compiler optimizations on? For the second case, the interval is so short that the timer will complete a full cycle before the interrupt is pended.

author: westfw
author_rank: Super Contributor
timestamp: February 12, 2016, 01:21:44 am
content: A jump (loop) is a two-cycle instruction, and a read/modify/write of an IOPORT is probably going to run at least 3 cycles. There is extensive discussion here:http://forum.arduino.cc/index.php?topic=4324(including bad-mouthing the arduino digitalWrite() functions, which slow things down by a factor of 20+) Simple loops on the 16MHz Arduino ran at 2.6667MHz, so your 1.6MHz result for a 8MHz clock sounds "about right", depending on exactly what code was produced (which you SHOULD be looking at, and posting, if you care about the results.)Code:int main() {while (1) {PORTB ^= 1;38: 91 e0 ldi r25, 0x01 ;;; outside of loop3a: 88 b3 in r24, 0x18 ;;; get port bit 13c: 89 27 eor r24, r25 ;;; invert 23e: 88 bb out 0x18, r24 ;;; write 340: fc cf rjmp .-8 ;;; loop 4,58MHz/5cycles = 1.6MHz...

author: sleemanj
author_rank: Super Contributor
timestamp: February 12, 2016, 05:05:52 am
content: Quote from: dannyf on February 11, 2016, 10:58:32 pmSpecifically on most current avr if you write the appropriate bit to 1 in the PIN register for a pin in output mode, it will toggle the pin.

author: westfw
author_rank: Super Contributor
timestamp: February 12, 2016, 06:37:30 am
content: QuoteNOT including ATmega8, which is more-or-less a "legacy" part these days (modern equiv: atmega88)

author: sleemanj
author_rank: Super Contributor
timestamp: February 12, 2016, 08:24:57 am
content: Quote from: westfw on February 12, 2016, 06:37:30 amOh yes, quite right. FWIW when I was doing sometidy-up in the optiboot makefiles a while back I dug into it a bit, for the *8 series these ones can toggle, excuse the copy-paste of code...Code:defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48PB__) \|| defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__) \|| defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) \|| defined(__AVR_ATmega328P__)I expect add the new 168/328 PB to those as well of course, not that they are really in the wild yet.To determine if your particular chip can toggle, generally just search for "toggling the pin" in the datasheet.