#include <avr/io.h> #include <util/delay.h> /* Button click with software debounce */ int main(void) { DDRB |= 1 << PINB0; // set PINB0 as output PORTB ^= 1 << PINB0; // xor toggling only PORTB0 DDRB |= 1 << PINB2; // set PINB2 as output DDRB &= ~(1 << PINB1); // set PINB1 as input PORTB |= 1 << PINB1; // pull PINB1 high int press = 0; int pressed_cf=0; int released_cf=0; while(1) // infinite loop { if(bit_is_clear(PINB,1)) { if (pressed_cf++ > 500) { if (press == 0 ) { PORTB ^= 1 << PINB0; PORTB ^= 1 << PINB2; press = 1; } pressed_cf = 0; } } else { if(released_cf++ > 500) { press=0; released_cf=0; } } } }
Code
An AVR external interrupt example
#include<avr/io.h> #include<avr/interrupt.h> // interrupt header file #include<util/delay.h> /** External Interrupt Program */ // Interrupt service Routine for INTO ISR(INT0_vect) { //_delay_ms(50); // Software Debounce delay PORTB ^= 1<<PINB0; _delay_ms(50); } int main (void) { DDRB |= 1<< PINB0 | 1<< PINB2; // setn PINB0 and PINB1 as output PORTB &= ~(1<< PINB0 | 1<< PINB2); DDRD &= ~(1<<PIND2); // PIND2 set as input.. This is the INT0 pin to which button is connected PORTD |= 1 << PIND2; // push PIND2 to high - internal pull up resisitor- short when button is pressed GIMSK = 1<<INT0; // enable interrupt on INTO pinD2 MCUCR = 1<<ISC01 | 1 << ISC00; // Trigger INTO on rising edge // enable global interrupts sei(); while(1) { PORTB ^= 1 << PINB2; _delay_ms(50); } }
Another example for the OpenM128 AVR development board here, we will look at the onboard buttons and LEDs again.
As stated in a previous article the development board has 8 LEDS and also 4 buttons available, in this example we will flash different sequences on the LEDs. Here are the pinouts of the LEDs and buttons from the schematic
These are the LEDs and as I stated you can see that these connect to PortA
Now for the 4 buttons, in this case you can see the buttons are connected to PD6, PD7, PE6 and PE7
Parts List
The programmer is a bit more expensive but it works seamlessly with Atmel Studio
Name | Link |
OpenM128 Development Evaluation Board | ATmega128 AVR Development Evaluation Board Kit = OpenM128 Standard |
AVRISP MKII | AT AVRISP mkII AVR ISP MK2 ISP2 downloader |
Atmel Studio code
In this example the 4 buttons will set different values to PortA as you can see below
[codesyntax lang=”cpp”]
#include <avr/io.h> #include <util/delay.h> void key_press(void) { PIND &=0xC0; switch((PIND&0xC0)) { case 0x80: while((PIND&0xC0)==0x40);PORTA =0xAA;break; case 0x40: while((PIND&0xC0)==0x80);PORTA =0x55;break; } PINE &=0xC0; switch((PINE&0xC0)) { case 0x80: while((PINE&0xC0)==0x40);PORTA =0x00;break; case 0x40: while((PINE&0xC0)==0x80);PORTA =0xFF;break; } } int main(void) { DDRD =0X00; DDRE =0X00; PORTD = 0xff; PORTE = 0xff; DDRA = 0xff; PORTA = 0x55; while(1) { key_press(); } }
[/codesyntax]
Programming
This time I used AtmelStudio and the USB AVRISP XPII and it worked perfectly
In this example we simply flashed the LEDs on a Waveshare OpenM128 AVR development board – I am trying to test out and use a variety of AVR related boards that I have, this is a very nice compact development board with LEDs, buttons, joystick and also a wide variety of connectors for LCDs, I2C, UART, PWM and various ports.
The board comes with a wide range of code that can be downloaded and there also a wide range of useful adaptor boards that can be plugged in to the board
This is a picture of the board, the LEDs are all connected to PortA on this board
Parts List
Name | Link |
OPenM128 AVR board | ATmega128 AVR Development Evaluation Board Kit = OpenM128 Standard |
USBASP programmer | 1LOT New USBASP USBISP AVR Programmer USB ISP USB ASP ATMEGA8 ATMEGA128 Support Win7 64 |
MikroC for AVR |
MIKROC Code
Just simple examples using MIkroC to flash the LEDs on the board
[codesyntax lang=”cpp”]
void main() { DDRA = 0xFF; // set direction to be output PORTA = 0x00; // turn OFF the PORTA leds while (1) { PORTA = 0x00; Delay_ms(1000); PORTA = 0xff; Delay_ms(1000); } }
[/codesyntax]
And here is another one
[codesyntax lang=”cpp”]
char counter; void wait() { Delay_ms(100); } void main() { DDRA = 0xFF; // set direction to be output PORTA = 0x00; // turn OFF the PORTA leds while (1) { for (counter=0; counter<8; counter++) { PORTA |= 1 << counter; wait(); } counter = 0; while (counter<8) { PORTA &= ~(1 << counter); wait(); counter++; } } }
[/codesyntax]
Atmel Studio Code
[codesyntax lang=”cpp”]
#include <avr/io.h> #include <util/delay.h> void delay_ms_test(unsigned char ms) { unsigned char i; i++; if (i%2==1) PORTA=0x00; } void delay_ms(unsigned int ms) { for(volatile unsigned int i=0;i<ms;i++); } int main(void) { DDRA=0xFF; PORTA=0x00; while(1) { // delay_ms(1000); PORTA=0x00; delay_ms(50000); PORTA=0xff; delay_ms(50000); } }
[/codesyntax]
Programming
I used AVRpal.net and connected a USBASP programmer, I had to use Zadig to install the necessary driver on Windows 10. I have managed to get this combination working but after a reboot the programmer stopped working so I will write a guide for Windows 10 later. I have several programmers such as a USB Tiny ISP, USB ASP and a USB AVRISP MK11.
The combination of getting these programmers working is a pain on Windows 10 so far
Links
In this example we connect a piezo buzzer to PB0 of our Attiny13a. We use mikroC pro for AVR which has a built in sound library to play a tone
Schematic
Code
As stated earlier we use mikroC pro for AVR, this contains a sound library.
[codesyntax lang=”c”]
void main() { DDRB = 0x00; // Configure PORTB as input Sound_Init(&PORTB,0); // Initialize sound pin while (1) { // endless loop Sound_Play(659, 250); // delay_ms(2000); } }
[/codesyntax]