Counter Variable not counting?(and other problems) ATmega168

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Original post wrote:
Hello fellow Freaks! I've seen to be having a lot of issues with my ATmega168 lately .
First off, the first bit of code below was created in the intent that every time the first bit of PINB (PIN0)

goes low, it's supposed to increment a counter variable by one, and print it out via usart. The "firstTime" and

"secondTime" variables are used so that it is supposed to only increments the variable once, instead of

incrementing the variable when PINB is low. Anyways, the issue I'm having is that when PINB (or the switch) pulls

the pin low, it increments the counter variable once, and then resets it once it is out of the loop. I've tried a

simple "for" loop that prints out the counter every time it's incremented, and that seems to work... but this

doesn't! Any ideas here? Here's the code for this issue:

CODE0

The second issue I'm having is that my compiler (WinAVR gcc) will not recognize type "bool". I've tried including

and have tried using the c++ and g++ compilers, but still doesn't recognize it. Under the gcc

compliler, here is the error I am receiving: "error: 'bool' undeclared (first use in this function)".
The last issue I am having is of trying to use external interrupts. My original block of code (up there^) was

sort of a way to bypass what I have been trying to do with external interrupts. I've looked at a few examples on

the internet (and avrlib) and haven't had any luck in trying to get it to work. Here's the block of code I have

tried to use to work with external interrupts:

CODE1

Any help would be GREATLY appreciated!

Matt Myers

As the forum currently has some problems with posting code into messages I'd suggest you add any relevant .c files as attachments. If using "Quick reply" first click [Preview] then you'll see the upload attachment button.

I'm guessing your first problem could well be FAQ#1

As for the second - if you want "bitvars" you are far better off typecasting a bitfield over GPIOR0 which will give you 8 fast access bit variables.

Cliff

EDIT: this was an attempt to get the "original author" changed but sadly it didn't help

Last Edited: Tue. May 12, 2009 - 11:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the help, Cliff. Clever signature by the way! I'd like to try and delete my previous posts, but it seem's as though I can't do that either :(

[cliff: I deleted them for you - it should have been possible - each post your "own" (or all of them if you have mod. rights like I do ;-)) should have a small [X] at the bottom right]

Attachment(s): 

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

A quick look at EXTINTProblem.c showed you are using the GCC ISR() vector INT0_vect with the depreciated SIGNAL() function. SIGNAL() should use the vector SIG_INTERRUPT1, not INT0_vect. In fact new program code should use ISR() for interrupts anyway.

There are probably more up to date resources, but for a quick reference try this link:
http://www.nongnu.org/avr-libc/u...

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

Mike,

That won't be a problem the _vect and SIG_ names are synonyms and you can "mix and match". From the first post I thought that one was going to show an inability to use "bool" but I don't see that being used anywhere in the program.

Having now seen it I *think* the first may be a contact bounce issue but it's difficult to verify without similar hardware.

Cliff

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

Then I take it there is no difference between using SIGNAL() or ISR(), except the depreciated SIGNAL() may disappear from a future GCC release?

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

Ah, I see them now! Thanks for doing that. As far as

Quote:
typecasting a bitfield over GPIOR0
is there a more simple way of doing this? I was hoping that it would count like any ordinary counter. If not, how would I create a variable using the GPIOR, if that is possible? Also, I am using a photo transistor as the "switch", so there shouldn't be any issues with the bouncing of contacts (at least I wouldn't think).

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

I know I'm a bear of very little brain and easily confused but you just succeeded.

I *thought* you had two issues here. One was to do with a counter not behaving as expected in countervarproblem.c and I *thought* the other was a problem using "bool" from in the second program (except I don't see that?).

My suggestion about bitfields was that, assuming you make it work:

#include 

bool bitvar = true;

is HUGELY inefficent as the compiler will use at least 8 bits and possibly 16 bits to hold the state of "bitvar" and to set it, clear it and read it's state will take long-winded RAM accessing code. Meanwhile something like:

typedef struct 
{ 
  unsigned char bit0:1; 
  unsigned char bit1:1; 
  unsigned char bit2:1; 
  unsigned char bit3:1; 
  unsigned char bit4:1; 
  unsigned char bit5:1; 
  unsigned char bit6:1; 
  unsigned char bit7:1; 
}io_reg; 

#define BIT_buffer_status		((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit0 
#define BIT_recv_error		((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit1 
#define BIT_active			((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit2 
#define BIT_use_sample1		((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit3 

#define BIT_byte_count		((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit4 
#define BIT_receive_132		((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit5 
#define BIT_wait_uart_low	((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit6 
#define BIT_RS232_calibrated	((volatile io_reg*)_SFR_MEM_ADDR(GPIOR0))->bit7

creates you 8 variables (I happen to choose to prefix each name with BIT_ just to remind me they are 0/1 variables and that they'll have fast access). As they are cast onto the mega48/88/168's "GPIOR0" register which is an 8 bit register dedicated for your own use that is reachable with the very fast/tight SBI/CBI opcodes the resultant code when these variables are read/written is VERY efficient.

So my point was simply that on an 8 bit microcontroller (when using GCC) don't even bother with stdbool.h but use the above construct and use the hell out of GPIOR0 - that's exactly why Atmel put it there for you!

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

Ha, I actually have 3 issues here! I'm sorry for the confusion! I am a little confusing when trying to explain stuff. The three problems are:
1. Counter variable does not update itself
2. Boolean type variable does not work (I can ignore this one for now)
3. Issues with external interrupts working.

My main 2 problems are the 1 and 3. As far as my external interrupt code goes, does it look fine as it is? I've compared it to several examples on the internet, and so I thought it looked valid. Thanks for the help so far!

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

OK then if we concentrate on (3):

(a) what is the actual interrupt source? Please don't say "a button" as using a button (or anything subject to mechanical contact bounce) on an ext-int for any purpose other than waking from sleep is a VeryBadIdea(tm). Read Ganssle - http://www.ganssle.com/debouncin... - to understand why.

(b) having said that you needn't worry immediately as your code has broken the second cardinal rule of embedded programming - you have a HUGE delay in an ISR (so bounce would be finished by the second interrupt). Putting delays into ISRs or, in fact, anything that takes more than microseconds is a VeryBadIdea(tm) as it blocks the service of any other interrupts in the system. Far better to acknowledge that the interrupt has occurred by simply setting a volatile flag and then act on this (at your leisure) in main(). As you current main() has nothing but a while(1) it's a perfect candidate for having the ISR work moved into it.

(c) as it stands your program is a bit of a "do nothing" anyway. You start by setting PC5 as an output but don't change its state - so it will default to 0. The only "work" the program later does is that, when the int occurs, you CBI the same bit - so nothing actually happens - what were you expecting?

Also why the use of outp() and cbi()/sbi() ? They are as old as the hills and totally un-necessary in this day and age. The same goes for SIGNAL(), its been deprecate in favour of ISR() (though curiously you HAVE adopted the new vector naming nomenclature)

(d) if it was me I'd leave any sei() until ALL the hardware initialisation has been completed - it's too easy to ass some later init stuff that initialises an int source unware that I is already set and the first interrupt triggers while half configured.

Cliff

PS Sorry to ask this but you wouldn't consider registering under a new ID would you? - it's just your username is throwing out the entire layout of the AVR Forum thread list!

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

Actually, the sbi(), cbi() and outb() functions are new to me. What should I be using? I'm a beginner at all of this, and this being the reason why I've had such a headache trying to figure out how this thing works. My whole point to the EXTINT program was to test the external interrupt. I had no idea that it was bad to use such a long delay in an ISR, but now that you have explained it, it makes sense.

Quote:

Also, I am using a photo transistor as the "switch", so there shouldn't be any issues with the bouncing of contacts (at least I wouldn't think)

I'm not using a mechanical switch, but a photo transistor (sorry to mistake it as a switch).

Can I change my username while under this account, or will I have to reregister?

Please excuse me for not knowing even the bare minimum use of an AVR. I have only recently begun playing with these amazing devices, and have really grown an interest in them.
Thanks for the help thus far.

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

Hey again, this is the former mattthemicrocontrollerman. Do I need to initialize any other registers to use the External Interrupts, other than the ones in the control register and the mask register?
Thanks

mattheu,

Can I ask one further favour? That you let this thread "die" (so it moves off the first page) and we continue this discussion in a new thread? As you'll have noticed it's the long name that is disturbing the width of the middle column on the AVR Forum thread list.

If you start a new thread I'll lock this one so it can never be resurrected and brought back to the front page.

Cliff

PS I'm now going to lock this thread as it's fallen off the front page. Can we continue any further discussion in a new thread?

Topic locked