Adapting Timer0 - Changing Fcpu 8MHz to 1MHz - Problem

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

The original code was for Fcpu = 8MHz, ATmega8. I am adapting the code for Fcpu = 1MHz, ATmega16. The critical code is for initialising Timer0. From the datasheets it is noted that the register and bit names for Timer0 in mega8 and mega16 remain the same. As approx 122 interrupts was originally required by the ISR(TIMER0_OVF_vect) [Timer0 overflow interrupt service routine], the prescaler and preload were changed as indicated below.

Original Code Fcpu = 8MHz = ATmega8

void Timer0_init(void)
{
	// This was with 8MHz = orig. ATmega8
	TCNT0=0x00;
	TCCR0|=(1<<CS02); //prescaller 256 ~122 interrupts/s ==> okay
	TIMSK|=(1<<TOV0);//Enable Timer0 Overflow interrupts ==> ?? (1<<TOIE0)
	sei();
}

Adapting Code Fcpu = 1MHz = ATmega16

void Timer0_init(void)
{
	// Below redo for 1 MHz => ATmega16 (regs and bit names same)
	TCNT0=0x80; // 128 preload ie 1/2 of 256 ==> ~122 interrupts
	TCCR0|=(1<<CS01)|(1<<CS00); //prescaller 64 ~??? interrupts/s
	TIMSK|=(1<<TOIE0);//Enable Timer0 Overflow interrupts corrected
	sei();
}

Querry 1 :
One issue not understood was, orignally TIMSK|=(1<<TOV0); was written, it should have been TIMSK|=(1<<TOIE0); as per my understanding, please correct me if I am wrong.
Querry 2 :
The ISR gets triggered, but not as desired, i.e. the sub-routines are incorrectly initiated, which would mean my adaptations for 1 MHz was not correct, please correct me if I am wrong.

For those who would like to know the original source, it is:-
http://winavr.scienceprog.com/ex...

Compiler : WinAVR 20070525 and its accompanying lib-c

I humbly request your guidance.
India_AVR

PS : my internal RC-oscillator is working fine for UART, SPI, Timer, routines hence I did not want to disturb the same.

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Surely you just divide the timings by 8?

If the comments are right and a /256 prscaler were being used then now you want it to run 8 times faster (compared to FCPU) to get the same tick rate so you want the prescale to be 32

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

Quote:
same tick rate so you want the prescale to be 32

Except that timer0 doesn't have 32 as a pre-scale option.

  TCNT0=0x80; // 128 preload ie 1/2 of 256 ==> ~122 

This will for the other factor of two. However, it will only be for the first time through. When the timer overflows, it will start at 0. You will need to set it to 128 again in the timer overflow interrupt.

However, there is an easier way. Use CTC mode and set OCR0 to 127. Then the timer (with a 64 pre-scaler) will be at the speed ypu want. But instead of using the overflow interrupt, you need to use the compare match interrupt.

Regards,
Steve A.

The Board helps those that help themselves.

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

Thanks Clawson and Steve. The new code is :-

void Timer0_init(void)
{
	// Below redo with CTC and o/p compare interrupt 
	TCCR0 |= (1<<WGM01); // Config Timer0 for CTC mode
	TIMSK |= (1<<OCIE0); // enable CTC o/p compare interrupt reqd for ISR
	sei(); // enable global interrupts
	 OCR0 = 127; // Set compare value with Prescale 64 = 122 interrupts ???
	TCCR0 |= ((1<<CS01) | (1<<CS00));  // start timer Fcpu / 64
}

The program runs with same wrong behaviour as earlier but with ISR(TIMER0_COMP_vect).
I am studying where else the Fcpu could be contributing to the misbehaviour.

Please may I also request comments on querry 1 of my post.

Thanks.
India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Are you sure that the mega16 is actually running at 1MHz? (The CLKSEL bits should b e 0001).

Quote:
lease may I also request comments on querry 1 of my post.

TOV0 and TOIE0 are both just macros for bit numbers. In this case, both happen to be the same number (0).

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
Are you sure that the mega16 is actually running at 1MHz? (The CLKSEL bits should b e 0001).

TOV0 and TOIE0 are both just macros for bit numbers. In this case, both happen to be the same number (0).


Yes CLKSEL is correctly defined and also checked with a timer code to obtain one sec, using Fcpu = 1 MHz. Thanks for clarifying TOV0/TOIE0 both having same number; next time I will always look deeper.
India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

To recap, this is an interrupt based menu selection. I am modifying a known program code for ATmega16 running at 8 MHz to work at 1 MHz. The ISR and settings for the ISR has been modified. In the meantime, I thought shifting the three LCD-Control lines (RS,RW,E) and the three outputs to LEDs from PORTB of the ATmega16 to PORTA may help. This was to ensure that the alternate functions of the AVR pins should not interfere. Earlier some of the programmed menus would never work and other times the menu would be at random. Now atleast all programmed menus are working, but ofcourse still not repeatedly or in the programmed manner. What was expected from the program.
(1) On startup LCD => <<Menu Demo>>, LED => all off
(2) Press SW-RIGHT(PC2), LCD => <<One LED>> <<R ON>>, LED => R(PA5) glow
(3) Press SW-RIGHT(PC2), LCD => <<One LED>> <<G ON>>, LED => G(PA4) glow
(4) Press SW-RIGHT(PC2), LCD => <<One LED>> <<B ON>>, LED => B(PA3) glow

(5) Press SW-UP(PC0), LCD => <<All ON/OFF>> <<All ON>>, LED => R,G,B glow
(6) Press SW-UP(PC0), LCD => <<All ON/OFF>> <<All OFF>>, LED => R,G,B dark

(7) Press SW-LEFT(PC1), LCD => <<Auto scroll>> <<Left>>, LED => R->G->B glow each contineous
{8} Press SW-LEFT(PC1), LCD => <<Auto scroll>> <<Right>>, LED => B->G->R glow each contineous

(9) Press SW-DOWN(PC3), LCD => <<Blink All>> <<Blink Fast>>, LED => R,G,B blink fast once
(10) Press SW-DOWN(PC3), LCD => <<Blink All>> <<Blink Slow>>, LED => R,G,B blink slow once

What is actually happening :-
On power-on / reset, always :-
LCD => <<Menu Demo>> quickly passes on to LCD => <<One LED>> <<R ON>>, LED => R(PA5) glow.
Then there is no corelation of SW press to LCD/LED display, ie for any switch press any menu appears. However the LCD and LED combination always have corelation i.e. what is displayed on LCD is displayed on LEDs, but not what was expected for the corresponding switch press. Thus there seems, the basic pointer to the menu structure is not getting properly directed. My initial reasoning was, this could be due to improper timing. The cause for this could be (a) CPU fuse settings (b) the ISR setting (c) the switch debouncing.

(a) the CPU fuse settings is shown in attached file
(b) we have already gone through the ISR settings in earlier postings, but same code tested as
(c) the debouncing seems reasonably programmed ( I have no scope to verify ), but same code tested as
(d) issues related to compiler optimisation, normaly I use "s", tried "0", "1", "2", "3", functionally same working problem
(e) Changing values of OCR0 127 -> 250 -> 50, functionally same working problem, contribution of timer not much effect !
(f) [Please dont laugh] Compiled original code for 8MHz and ran on 1MHz cpu-setting, LCD & LED working same problem ! ! !
(g) Below is tabulated "switch-press, LCD display and LED display" that I get 95% of the time, but *once in a while I get at random differently*.

SW1=SW-UP, SW2=SW-LEFT, SW3=SW-RIGHT, SW4=SW-DOWN

+--------+------------+------------+------------+
| Switch |    Menu    |   SubMenu  | LED Output |
+--------+------------+------------+------------+
| Start  |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
| SW1    | All on/off | All ON     | R,G,B      |
+--------+------------+------------+------------+
| SW1    | Auto Scrol |  Left      | R->G->B    |
+--------+------------+------------+------------+
| SW1    | Blink All  | Blink Fast | RGB Fast   |
+--------+------------+------------+------------+
| SW1    |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
|        |            |            |            |
+--------+------------+------------+------------+
| Reset  |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
| SW2    |  One led   |  G  ON     |    G       |
+--------+------------+------------+------------+
| SW2    |  One led   |  B  ON     |    B       |
+--------+------------+------------+------------+
| SW2    |  One led   |  G  ON     |    G       |
+--------+------------+------------+------------+
| SW2    |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
|        |            |            |            |
+--------+------------+------------+------------+
| Reset  |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
| SW3    |  One led   |  B  ON     |    B       |
+--------+------------+------------+------------+
| SW3    |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
| SW3    |  One led   |  G  ON     |    G       |
+--------+------------+------------+------------+
| SW3    |  One led   |  B  ON     |    B       |
+--------+------------+------------+------------+
| SW3    |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
|        |            |            |            |
+--------+------------+------------+------------+
| Reset  |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+
| SW4    | Blink All  | Blink Fast | RGB Fast   |
+--------+------------+------------+------------+
| SW4    | Auto Scrol |  Left      | R->G->B    |
+--------+------------+------------+------------+
| SW4    | All on/off | All ON     | R,G,B      |
+--------+------------+------------+------------+
| SW4    |  One led   |  R  ON     |    R       |
+--------+------------+------------+------------+

Please may I humbly request, if someone can indicate how to trace the misbehaviour [I do not have a simulator / scope]. Many thanks in advance.
India_AVR

Attachment(s): 

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
I do not have a simulator

Apart from the one built into AVR Studio? That will simulate the mega16 just fine.

I guess by "simulator" you meant an On Chip Debuggger providing a JTAG interface to the mega16? But you should be able to see SOME of what's going on in Studio's software simulator.

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

clawson wrote:
Quote:
I do not have a simulator

Apart from the one built into AVR Studio? That will simulate the mega16 just fine.

I guess by "simulator" you meant an On Chip Debuggger providing a JTAG interface to the mega16? But you should be able to see SOME of what's going on in Studio's software simulator.


Till date had never used AVR Studio, as I was using Notepad2 and proprietory ISP. I think I will have to work on this.

In the meantime, I thought fit to report the compilation report in which I have marked "<=========" which give "Warning" but completes compilation. Could this be the problem ? If so, some guidance to correct these would be most thankfully acknowledged.

> "make.exe" all

-------- begin --------
avr-gcc (GCC) 4.1.2 (WinAVR 20070525)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling C: menu.c
avr-gcc -c -mmcu=atmega16 -I. -gstabs -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./menu.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/menu.o.d menu.c -o menu.o

Compiling C: lcd_lib.c
avr-gcc -c -mmcu=atmega16 -I. -gstabs -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./lcd_lib.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/lcd_lib.o.d lcd_lib.c -o lcd_lib.o

Linking: menu.elf
avr-gcc -mmcu=atmega16 -I. -gstabs -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=menu.o  -std=gnu99 -Wundef -MMD -MP -MF .dep/menu.elf.d menu.o lcd_lib.o --output menu.elf -Wl,-Map=menu.map,--cref     -lm

Creating load file for Flash: menu.hex
avr-objcopy -O ihex -R .eeprom menu.elf menu.hex

Creating load file for EEPROM: menu.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
	--change-section-lma .eeprom=0 --no-change-warnings -O ihex menu.elf menu.eep || exit 0
c:\WinAVR-20070525\bin\avr-objcopy.exe: there are no sections to be copied!

Creating Extended Listing: menu.lss
avr-objdump -h -S menu.elf > menu.lss

Creating Symbol Table: menu.sym
avr-nm -n menu.elf > menu.sym

Converting to AVR Extended COFF: menu.cof
avr-objcopy --debugging --change-section-address .data-0x800000 --change-section-address .bss-0x800000 --change-section-address .noinit-0x800000 --change-section-address .eeprom-0x810000 -O coff-ext-avr menu.elf menu.cof
Warning: file C:/WINDOWS/TEMP/ccSQUx8u.s not found in symbol table, ignoring <=======
Warning: ignoring function __vectors() outside any compilation unit <=======
Warning: ignoring function __bad_interrupt() outside any compilation unit <=======
avr-objcopy: --change-section-vma .eeprom+0xff7f0000 never used
avr-objcopy: --change-section-lma .eeprom+0xff7f0000 never used
avr-objcopy: --change-section-vma .noinit+0xff800000 never used
avr-objcopy: --change-section-lma .noinit+0xff800000 never used
Size after:AVR Memory Usage
----------------
Device: Unknown

Program:    1816 bytes
(.text + .data + .bootloader)

Data:         32 bytes
(.data + .bss + .noinit)

-------- end --------

> Process Exit Code: 0
> Time Taken: 00:02

Many Thanks in Advance.
India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
Converting to AVR Extended COFF: menu.cof

Are you sure your makefile is up to date? The latest versions of avr-gcc don't use COFF.

Regards,
Steve A.

The Board helps those that help themselves.

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

That does look like an old makfile, so I suggest you update. Grab the latest template from C:\WinAVR-20071221rc1\mfile\makefile_template, rename it to makefile in your directory and modify to your heart's content.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Steve and Dean:
Only a few months back I had upgraded to avr-gcc (GCC) 4.1.2 (WinAVR 20070525). Already I had some time spent on deprecated issues. With a fresh WinAVR-20071221, it will take some more time to get aclimatised to. But if it will solve the problem, then I believe, I have no alternative but to upgrade. [ Just a thought that using only a new Makefile may have some pitfalls. ]

All of the Fraternity :
I humbly request if someone is able to spare some time to look over my problem and suggest where I could try to look for the cause of the issue. I have already indicated where all I had looked and what I did for those issues.

Many thanks in advance.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Sorry, it took some time to change over to WinAVR 20071221. With "20071221-Makefile" and below is the compiler report for the same program code with NO warnings now :-

Quote:
> "make.exe" all

-------- begin --------
avr-gcc (GCC) 4.2.2 (WinAVR 20071221)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling C: menu.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./menu.lst -std=gnu99 -Wundef -MMD -MP -MF .dep/menu.o.d menu.c -o menu.o

Compiling C: lcd_lib.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./lcd_lib.lst -std=gnu99 -Wundef -MMD -MP -MF .dep/lcd_lib.o.d lcd_lib.c -o lcd_lib.o

Linking: menu.elf
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=menu.o -std=gnu99 -Wundef -MMD -MP -MF .dep/menu.elf.d menu.o lcd_lib.o --output menu.elf -Wl,-Map=menu.map,--cref -lm

Creating load file for Flash: menu.hex
avr-objcopy -O ihex -R .eeprom menu.elf menu.hex

Creating load file for EEPROM: menu.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex menu.elf menu.eep || exit 0

Creating Extended Listing: menu.lss
avr-objdump -h -S -z menu.elf > menu.lss

Creating Symbol Table: menu.sym
avr-nm -n menu.elf > menu.sym
Size after:
AVR Memory Usage
----------------
Device: atmega16

Program: 1850 bytes (11.3% Full)
(.text + .data + .bootloader)

Data: 32 bytes (3.1% Full)
(.data + .bss + .noinit)

-------- end --------
> Process Exit Code: 0
> Time Taken: 00:06


But the program funtioning has not improved, it still does not follow the corresponding switch pressing. Rechecking the program did not elicit error in the code. Any leading direction to persue would be most gratefully followed up.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Admittedly I haven't re-read this whole thread but is this something to do with bounce?

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

clawson wrote:
Admittedly I haven't re-read this whole thread but is this something to do with bounce?

It is supposed to take care of both bounce and menu selection in one go. Highlighting the important lines :-

void Timer0_init(void)
{
	// Below redo with CTC and o/p compare interrupt ---[C]
	TCCR0 |= (1<<WGM01); // Config Timer0 for CTC mode
	TIMSK |= (1<<OCIE0); // enable CTC o/p compare interrupt reqd for ISR
	sei(); // enable global interrupts
	OCR0 = 127; // Set compare value with Prescale 64 = 122 interrupts ???
	TCCR0 |= ((1<<CS01) | (1<<CS00));  // start timer Fcpu / 64
}

ISR(TIMER0_COMP_vect)
{
	//if button UP pressed
	if (bit_is_clear(BT_PIN, UP))
	{
		<< Menu & SubMenu >>
	}
	//if Button DOWN pressed
	if (bit_is_clear(BT_PIN, DOWN))
	{
		<< Menu & SubMenu >>
	}
	//If Button RIGHT pressed
	if (bit_is_clear(BT_PIN, RIGHT))
	{
		<< Menu & SubMenu >>
	}
	//If button LEFT pressed
	if (bit_is_clear(BT_PIN, LEFT))
	{
		<< Menu & SubMenu >>
	}	
}

The criteria was to achieve approx 122 interrupts which would have been okay for considering bounce. More often one of the submenus of "UP" would get triggered for any one of the four keys, apart from other random submenus. It did not matter,when the interrupts were changed from 5 to 250 per second. This is what has me surprised. Possibly you may be able to lead me to search further.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

I can't see how that accounts for bounce. You're checking the buttons over a hundred times a second, and performing an action each time the ISR fires. What if the user holds a button down - is it supposed to cycle through the menu hundreds of times per second?

For bounce, you need to start filtering the values in the interrupt. Each time the interrupt fires, store the value of all the buttons in a temp variable. Compare the new value with the last, and see if the result is identical -- if it is, increment a static counter. Once the counter reaches a critical value, say 50 counts or nearly half of a second, reset the counter and perform an action.

Psudocode:

ISR(TIMER0_COMP_vect)
{
	static uint8_t PreviousValue;
	static uint8_t IdenticalCompares;
	static uint8_t HandledButtonPress;
	
	uint8_t CurrentValue = (BT_PIN & ((1 << UP) | (1 << DOWN) | (1 << LEFT) | (1 << RIGHT));
	
	if (CurrentValue == PreviousValue)
	{
		IdenticalCompares++; // Values match, increment the debounce counter
	}
	else
	{
		PreviousValue      = CurrentValue; // Mismatch, store the new button status
		HandledButtonPress = 0; // When button status changes, indicate new states not processed
	}
	  
	if ((IdenticalCompares > 50) && !(HandledButtonPress))
	{
		IdenticalCompares = 0;
		HandledButtonPress = 1;

	   //if button UP pressed
	   if (bit_is_clear(BT_PIN, UP))
	   {
		  << Menu & SubMenu >>
	   }
	   //if Button DOWN pressed
	   if (bit_is_clear(BT_PIN, DOWN))
	   {
		  << Menu & SubMenu >>
	   }
	   //If Button RIGHT pressed
	   if (bit_is_clear(BT_PIN, RIGHT))
	   {
		  << Menu & SubMenu >>
	   }
	   //If button LEFT pressed
	   if (bit_is_clear(BT_PIN, LEFT))
	   {
		  << Menu & SubMenu >>
	   }
	}
}

Note the inclusion of a "HandledButtonPress" variable -- that prevents more than one action from being activated for each button press (i.e. holding down a button will not perform more than one action).

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

abcminiuser wrote:
I can't see how that accounts for bounce. You're checking the buttons over a hundred times a second, and performing an action each time the ISR fires. What if the user holds a button down - is it supposed to cycle through the menu hundreds of times per second?

Sorry, for concentrating on menu selection the portions which check for key-press/debounce was not shown in my post. However additionally your code was also included. I introduced a "blinky6" before
      //if button UP pressed
      if (bit_is_clear(BT_PIN, UP)) 

and a "blinky7" inside the while(1) loop. I found that "blinky6" blinks twice for every key-press. While "blinky7" mostly contineously blinks but on some occassions blinks only once for each key-press. I also included one "blinky5" inside MFindex(), this sometimes blinks once and sometimes does not blink at a key-press.

But even with your additional code from above post, still the "LCD/LED" does not follow the key-press menu.

Possibly I am still missing something.

India_AVR

PS : *blinky = blinking LED, 5/6/7 => different LED No.

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
I found that "blinky6" blinks twice for every key-press.

You have read Ganssle ( http://www.ganssle.com/debouncin... ) haven't you?

I would defy any human eye/brain to able to detect signal transitions in the millisecond range simply from looking at an LED! - it tells you nothing about any bounce that is happening.

What you need to do here is isolate a well proven debounced button routine and then use that at the higher level for your menu transitions. Trying to incoporate the handling of the debounce into the general menu handling structure is a recipe for disaster. The key thing is modular code.

Make one small building block, prove beyond all reasonable doubt that it works without error THEN built upon it. Don't try to implement everything in one go and expect it all to work. It won't and you'll have a hell of a job locating the areas/reasons why not.

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

Mr Clawson Sir,
I am sorry once again.

void blinky6(void)
{
// ---- LED_TPORT ----------- debugging LED-PB6
	delay1s();
	LED_TPORT ^= (1<<6);
	delay1s();
}

void delay1s(void)  // #include 
{
	uint8_t i;
	for(i=0;i<10;i++)
	{
		_delay_ms(10);
	}
}

Which can be seen by the eye. This is only for testing part. The debounce was to have been additionally taken care by the code suggested by Mr Dean. Incidently I have used the same switches in my earlier simple codes with

while(1)
  {
    sw_id=PINA;
    switch(sw_id)
    {
      case 0xfe:	// Switch 1
        PORTC=0xFE;	//  = ~0x01
        break;
      case 0xfd:	// Switch 2
        PORTC=0xFD;	//  = ~0x02
        break;
      case 0xfb:	// Switch 3
        PORTC=0xFB;	//  = ~0x04
        break;
      case 0xf7:	// Switch 4
        PORTC=0xF7;	//  = ~0x08
        break;
    }		
    _delay_us(50);	// Debouncing max 267 ?
  }

which worked fine repeatedly. Delay 50 micro-sec. My calculations for code under study gives debounce delay of about 7.8 milli-sec; hence I thought was okay.

Time = Interrupts   x   Timer Resolution
     = Interrupts   x   ( Prescale   /   Fcpu)
     =    122       x   (    64      /  1 000 000  )
     =  7.8 ms

Thanks for referring to Jack.G.Ganssles artical on "A Guide to Debouncing" Rev2, April 2007. This has added finer points to my understanding on the topic. Possibly as suggested, I may have to go back and startup again in parts.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Your delay1s() is a minomer, it is delay100ms() in fact but the point is that by putting that in your blinky() routine you are inadvertently providing debounce. But this won't be there when you remove the routine - a definite case of killing Schroedinger's Cat!

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

Apart from learning microcontrollers we also learn other things ! (Ofcourse pointers to our work).

India_AVR[/img]

Attachment(s): 

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Hopefully you understood the point? What Schroedinger was effectively saying was that "a watched system behaves differently" or rather that the behaviour of the system is unpredictable until you attempt to look at it.

Your adding delayed LED routines to your system to watch what was going on was actually affecting the behaviour of the system being watched.

Cliff

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

Dear Cliff Sir,

The delayed LEDs were added later with some hope that it could affect the debounce stabilisation also apart from seeing where the code was heading. Hopefully in this perticular case it was not expected to affect adversely. Basically the origianl problem continues identical with or without the delayed LEDs; ofcourse it may not happen always. But your observation is well taken, sometimes in over enthusiasm this could be overlooked.

Best Wishes,
India_AVR

PS : I will be out of town for 7 days.

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Hello,
Have been working further on the code and I find that the ISR is working correctly by checking with "Testing Displays" on LEDs [no delays for LEDs] as shown in code below

// Timer0 CTC Compare interrupt service routine	
ISR(TIMER0_COMP_vect)
{
	//if button UP pressed => "0"
	if (bit_is_clear(BT_PIN, UP))
	//LED_TPORT= ~0x10; // Testing Display
	{
		if (MN.menuNo "3"
	if (bit_is_clear(BT_PIN, DOWN))
	//LED_TPORT= ~0x80; // Testing Display
	{
		if (MN.menuNo==1)
		{ 
			LED_TPORT= ~0x81; // Testing Display
			MN.menuNo=pgm_read_byte(&MSTR2[0]);
			MN.subMenuNo=1;
		}
		else
		{
			LED_TPORT= ~0x82; // Testing Display
			MN.menuNo--;
		}
		LCD_LED_Pntr_ClrFlg();
		loop_until_bit_is_set(BT_PIN, DOWN);
	}
	
	//If Button RIGHT pressed => "2"
	if (bit_is_clear(BT_PIN, RIGHT))
	//LED_TPORT= ~0x40; // Testing Display
	{
		if (MN.subMenuNo "1"
	if (bit_is_clear(BT_PIN, LEFT))
	//LED_TPORT= ~0x20; // Testing Display
	{
		if (MN.subMenuNo==1)
		{ 
			LED_TPORT= ~0x21; // Testing Display
			MN.subMenuNo=pgm_read_byte(&MSTR2[MN.menuNo]);
		}
		else
		{
			LED_TPORT= ~0x22; // Testing Display
			MN.subMenuNo--;
		}
		LCD_LED_Pntr_ClrFlg();
		loop_until_bit_is_set(BT_PIN, LEFT);
	}
	
}

I am now working over the logic of the pointers. How do I "see" the "pointer-value" (not pointed-value), trying dummy = MN.menuNo; or dummy = MN.subMenuNo; does not work, so that I could check the "dummy" on LEDs where they are pointing; could be an issue with initialisation of the array ?

Many thanks in advance for some indications.

India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

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

Quote:
trying dummy = MN.menuNo; or dummy = MN.subMenuNo; does not work

If you want the address of the variable, you need:

dummy = &MN.menuNo;

Keep in mind that the address will not fit in an 8 bit variable.

Regards,
Steve A.

The Board helps those that help themselves.