MICROPROCESSOR PROJECT
Components provided are
- Nerdkit- ATMEGA 168 MICROPROCESSOR
- 4*3 KEYPAD
- MYLAR CONE SPEAKER
- LM386N-1 LOW VOLTAGE 1W AMPLIFIER IC (DATASHEET)
- 10KΩ POTENTIOMETER FOR VOLUME ADJUSTMENT
- Capacitor
a. Capacitor (473) 47 nF
b. Electrolytic Capacitors/Voltage: 220uF/25V - Resistors –2KΩ , 220 Ω , 100 Ω, 100 Ω
- 2 LED
software used is WinAVR-20100110 and code in assembler language.
SAMPLE PROGRAM CODE FOR INTERFACING WITH KEYPAD
uint8_t debg;
// PIN DEFINITIONS:
//
// PC0 — KEYPAD COL1 (left column)
// PC1 — KEYPAD COL2 (centre column)
// PC2 — KEYPAD COL3 (right column)
// PC3 — KEYPAD ROW1 (top row)
// PC4 — KEYPAD ROW2 (second row)
// PC5 — KEYPAD ROW3 (third row)
//
// NOTE: We have not connected bottom row
// because PC6 is being used as RESET input (tied high)
void keypad_init() {
// set ports to proper input and output
// enable pull up resistors for inputs
// Set the columns as ouput
// Set row pins to input mode
// Port C bit 0 and 1 and 2 as output (columns)
DDRC |= (1<<PC2) |(1<<PC1) |(1<<PC0) ;
DDRC &= ~(1<<PC3); // set PC3 as input
DDRC &= ~(1<<PC4); // set PC4 as input
DDRC &= ~(1<<PC5); // set PC5 as input
// turn on the internal resistors for the input pins
PORTC |= (1<<PC3); // turn on internal pull up resistor for PC3
PORTC |= (1<<PC4); // turn on internal pull up resistor for PC6
PORTC |= (1<<PC5); // turn on internal pull up resistor for PC7
// Set column output pins low, so input low if contact made
PORTC &= ~(1<<PC2 | 1<<PC1 | 1<<PC0 ); // set PC0, PC1 and PC2 low
} // END keypad_init
//
uint8_t keypressed() {
// checks to see if any key has been pressed
// sets columns to 0, and checks if any row goes low
// Returns a 1 (true) if a key has been pressed, 0 if not pressed
// Set column output pins low, so input low if contact made
uint8_t rowvl;
uint8_t kp;
PORTC &= ~(1<> 3);
rowvl&= (1<<PC2 | 1<<PC1 | 1<<PC0); // mask out other bits
kp = (rowvl != 7); // if 7, all high so no key
return kp;
}
//
char keypad_read(char lastchar) {
// read from keypad
// (assumes key has been pressed)
// returns keyval0..9
// takes in lastchar, and returns that if invalid read from keypad
uint8_t rowval;
char keych; // Initialise to $
keych = ‘$’;
PORTC |= ( (1<<PC2) | (1<<PC1)); // set other 2 high
PORTC &= ~(1<<PC0 ); // set PC0 low – check column 1
delay_us(10); // delay to allow signals to settle
// Read value from Pins on PortC
// Then shift right 3 to get pins3, 4 and 5 in first 3 bits
rowval= (PINC >> 3);
rowval&= (1<<PC2 | 1<<PC1 | 1<<PC0); // mask out other bits
switch(rowval) {
case 6: keych = ‘1’;
break;
case 5: keych = ‘4’;
break;
case 3: keych = ‘7’;
break;
default: keych = ‘$’;
break;
}
if (keych==’$’) { // if still not valid key
PORTC |= ( (1<<PC2) | (1<<PC0)); // set other 2 high
PORTC &= ~(1<<PC1 ); // set PC1 low – check column 2
delay_us(10); // delay to allow signals to settle
// Read value from Pins on PortC
rowval= (PINC >> 3);
rowval&= (1<<PC2 | 1<<PC1 | 1<<PC0); // mask out other bits
switch(rowval) {
case 6: keych = '2';
break;
case 5: keych = '5';
break;
case 3: keych = '8';
break;
default: keych = '$';
break;
}
}
if (keych==’$’) { // if still not valid key
PORTC |= ( (1<<PC1) | (1<<PC0)); // set other 2 high
PORTC &= ~(1<<PC2 ); // set PC2 low – check column 3
delay_us(10); // delay to allow signals to settle
// Read value from Pins on PortC
rowval= (PINC >> 3);
rowval&= (1<<PC2 | 1<<PC1 | 1<<PC0); // mask out other bits
switch(rowval) {
case 6: keych = '3';
break;
case 5: keych = '6';
break;
case 3: keych = '9';
break;
default: keych = '$';
break;
}
}
if (keych != ‘$’) { // if valid character
lastchar = keych; // update last char
}
return lastchar;
} // END keypad_read
//
void init_interrupts() {
// To set up the interrupts for the pin – PCINT1
// Enable the particular pin change interrupt – PC0
// Enable global interrupts
PCMSK0 = ( 1<<PCINT1 ) ;/* INSERT your own code here */ // Enable PCINT1 interrupt, and clear others
PCICR &= ~((1<<PCINT1) | (1<<PCINT2)) ;/* INSERT your own code here / // Disable PC Int 1 and PC Int 2
PCICR |= ( 1< INSERT your own code here */ // Enable PC Int 0
sei(); // Enable global interrupts
} // END init_interrupts
//
void init_switch_port() {
// Initialises Port B
// Turn GREEN LED ON and Red LED OFF
// Initialises Port B
DDRB &= ~(1<<PB1);
PORTB |= (1<<PB1);
DDRB |= (1<<PB3) | (1<<PB5);
PORTB |= (1<<PB3) |(1<<PB5); // PB1 set as input for switch
// PB3 and PB5 set as outputs for LEDs
PORTB &= ~(1<<PB3) ; // Turn GREEN LED ON and Red LED OFF
PORTB &= (1<<PB5) ;
} // END init_switch_port
//
ISR(PCINT0_vect) {
// This uses the predefined ISR function to create an ISR
// The compiler generates the initial and final code
// (including the RETI instruction)
// This will result in the following code being run when
// Interrupt PC0 (Pin change 0) happens
delay_ms(1); // delay to ‘debounce’ switch
PORTB ^= (1<<PB3) | (1<<PB5); // XOR bits 3 and 5 to toggle LEDs
} //End ISR PCINT0
//
int main() {
// variables declaration and initialisation
char keychar = ‘C’;
int8_t keynum;
debg = 0;
// start up the LCD
lcd_init();
lcd_home();
// initialise keypad, switch port
keypad_init();
init_switch_port();
// wait a bit then enable interrupts
delay_ms(1);
init_interrupts();
while(1) {
// continuously check keypad
// IF key is pressed then read and display character
if (keypressed()) {
keychar = keypad_read(keychar);
}
else {
//do nothing for now
}
lcd_home();
lcd_write_string(PSTR("Last Key pressed: "));
lcd_write_data(keychar);
lcd_write_string(PSTR(" "));
}
return 0;
}