Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

8051 chaser & questions

Status
Not open for further replies.

Torben

Well-Known Member
Hi all!

I've just completed my first microcontroller circuit, using an AT89C4051. It's a simple back-and-forth LED chaser, with a button to cycle through 6 preset speeds.

It works fine, but I do have some questions about it.

Quick notes first:

o LEDs are on P1.0-P1.7, each having a 220 ohm resistor to +5V.
o The button is on P3.2 (pin 6), used as external interrupt 0. It simply goes straight to ground.
o There is one more LED on P3.0, lit while the button's interrupt is ignoring bounces.

The code:

Code:
/* chaser1.c - time-configurable KITT-style LED chaser for 8051 - ltw 2007-04-14 */
/* main() based on keil blinky.c example code */

#include <Atmel/AT89x051.H>

#define MIN_WAIT_TIME 500
#define MAX_WAIT_TIME 40000
#define WAIT_INTERVAL 6000
#define BUTTON0_INT_WAIT 3

#define MAX_WAIT_IND 5

unsigned int led_wait_times[6] = {1000, 3000, 5000, 10000, 20000, 40000};
unsigned char volatile led_wait_ind;
unsigned int volatile button0_wait_time;

void button0(void) interrupt 0 {
	if (!button0_wait_time) {
		button0_wait_time = 1;

		P3 =~ 0x01; // light the "button lockout" LED

		if (led_wait_ind >= MAX_WAIT_IND) {
			led_wait_ind = 0;
		} else {
			led_wait_ind++;
		}
	}
}

void timer0(void) interrupt 1 {
	if (button0_wait_time >= BUTTON0_INT_WAIT) {
		button0_wait_time = 0;
		P3 = 0xFF;
	} 
	
	if (button0_wait_time) {
		button0_wait_time++;
	}
}

void wait(void) { 
	unsigned int i;
	for (i = 0; i < led_wait_times[led_wait_ind]; i++) {}
}

void init(void) {
	EA = 1;       // Global interrupt enable
	EX0 = 1;      // Enable external interrupt 0
	ET0 = 1;      // Enable timer interrupt 1
	TMOD = 0x01;  // Put timer0 into 16-bit mode
	TR0 = 1;      // Start timer0 running
	IT0 = 1;      // Edge-triggering instead of level-triggering

	P1 = 0xFF;    // Turn off all port 1 LEDs
	P3 = 0xFF;    // Turn off all port 3 LEDs

	led_wait_ind = 0;
	button0_wait_time = 0;
}

void main(void) {
	unsigned char j;   // will hold a bit mask for the display

	init();

	while (1) {
		for (j = 0x01; j < 0x80; j <<= 1)  {
			P1 =~ j;  // output complement to port 1 to light only one LED at a time
			wait();
		}

		for (j = 0x80; j > 0x01; j >>= 1)  {
			P1 =~ j;
			wait();
		}
	}
}

This all seems to work fine.

My questions:

1) On a couple of sites I have read pleas for designers to never hook buttons/switches to interrupts. What is the reason for this? Is it an electrical thing, or just that interrupts might be better left for other tasks? In this case I opted for the external interrupt because I didn't want the wait() routine to block keypresses--but I haven't actually done the math to check what the worst-case keypress wait time would be (say, using button polling on a free P3 pin).

2) Some switch configs I've seen on various sites use a resistor labeled as a current limiter. Am I endangering my microcontroller by not having a resistor there?

3) Any useful hints for this kind of thing? Meaning good links for "best practices" kind of ideas, or things I'm doing that set off alarm bells?


Thanks for any input!

Torben
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top