740 likes | 1.36k Views
The Use of Microcontrollers. Using ATMEL’s ATmega168 as an example. Programming a Microcontroller What’s Needed?. $7.50. $34.00. Computer Software Write Code Simulate AVR Studio 4 Port Serial Parallel USB. Programmer Development Board JTAG/ICE ISP Programmer Bit-Bang ADAFruit
E N D
The Use of Microcontrollers Using ATMEL’s ATmega168 as an example
Programming a MicrocontrollerWhat’s Needed? $7.50 $34.00 • Computer • Software • Write Code • Simulate • AVR Studio 4 • Port • Serial • Parallel • USB • Programmer • Development Board • JTAG/ICE • ISP • Programmer • Bit-Bang • ADAFruit • ISP • AVRISP Mk II • Microcontroller • Connection • DIP • SOIC • QFN • Capability • ADC/DAC • PWM • USB
Why Atmel’s AVR Microcontroller? • RISC architecture with mostly fixed-length instruction, load-store memory access, and 32 general-purpose registers. • A two-stage instruction pipeline that speeds up execution. • Majority of instructions take one clock cycle • Up to 20-MHz clock operation • Wide variety of on-chip peripherals, including digital I/O, ADC, EEPROM, Timer, UART, RTC timer, pulse width modulator (PWM), etc • Internal program and data memory • In-system programmable • Available in 8-pin to 64-pin package size to suit wide variety of applications • Up to 12 times performance speedup over conventional CISC controllers. • Wide operating voltage from 2.7 V to 6.0 V. • A simple architecture offers a small learning curve to the uninitated.
ATmega168 Pins PDIP (ADC5/SCL/PCINT13) 1 28 PC5 PC6 (ADC4/SDA/PCINT12) 2 (PCINT16/RXT) 27 PC4 PD0 (ADC3/PCINT11) 3 (PCINT17/TXD) 26 PC3 PD1 (ADC2/PCINT10) 4 (PCINT18/INT0) 25 PC2 PD2 (ADC1/PCINT9) 5 (PCINT19/OC2B/INT1) 24 PC1 PD3 (ADC0/PCINT8) 6 (PCINT20/XCK/T0) 23 PC0 PD4 7 22 GND VCC 8 21 AREF GND 9 (PCINT6/XTAL1/TOSC1) 20 AVCC PB6 (SCK/PCINT5) 10 (PCINT7/XTAL2/TOSC2) 19 PB5 PB7 (MISO/PCINT4) 11 (PCINT21/OC0B/T1) 18 PB4 PD5 (MOSI/OC2A/PCINT3) 12 (PCINT22/OC0A/AIN0) 17 PB3 PD6 13 (PCINT23/AIN1) 16 PB2 PD7 (OC1A/PCINT1) 14 PCINT0/CLK0/ICP1) 15 PB1 PB0
Memory • Flash Code Memory • 16-bit words starting at 0x0000 • Size dependent on AVR microcontroller • Non-volatile • Read-only memory (writing is external to code) • Data Memory • General Purpose Registers • 32 8-bit registers • I/O Registers • Two 8-bit registers for each I/O line • SRAM • 8-bit memory with size dependent on AVR microcontroller • EEPROM Memory • Typically reserved for variables that must retain their value in the event of a shutdown (e.g., system calibration data unique to each board) • Slow speed writing (1 millisecond for 1 byte of memory) • Limited number of write cycles
AVR Risk Architecture • The Register File • 32 8-bit registers
I/O Memory Registers • EEDR: EEPROM Data Register • EECR: EEPROM Control Register • PORTB: PortB Data Register • DDRB: PortB Data Direction Register • PINB: Input Pins on PortB • PORTD: PortD Data Register • DDRD: PortD Data Direction Register • PIND: Input Pins on PortD • SPI I/O Data Register • SPI Status Register • SPI Control Register • UART I/O Data Register • UART Status Register • UART Control Register • UART Baud Rate Register • ACSR: Analog Comparator Control and Status Register • SREG: Status Register • SP: Stack Pointer Register • GIMSK: General Interrupt Mask Register • GIFR: General Interrupt Flag Register • MCUCR: MCU General Control Register • MCUSR: MCU Status Register • TCNTO: Timer/Counter 0 Register • TCCR0A: Timer/Counter 0 Control Register A • TCCR0B: Timer/Counter 0 Control Register B • OCR0A: Timer/Counter 0 Output Compare Register A • OCR0B: Timer/Counter 0 Output Compare Register B • TIMSK0: Timer/Counter 0 Interrupt Mask Register • TIFR0: Timer/Counter 0 Interrupt Flag Register • EEAR: EEPROM Address Register
Port Registers PORTB: PortB Data Register DDRB: PortB Data Direction Register PINB: Input Pins on PortB Similar for Ports C and D.
Parallel I/O Ports • Most general-purpose I/O devices • Each I/O Port has 3 associated registers • DDRx (where “x” is A, B, C…) • Data Direction Register Port x • Determines which bits of the port are input and which are output DDRB = 0x02; /* sets the second lowest of port B to output” */ • PORTx • Port Driver Register PORTB = 0x02; /* sets the second bit of port B and clears the others */ • PINx • Port Pins Registers • Returns the status of all 8 port B pins. unsigned int x; x = PINB; /* Places the status of port B into variable x */
Input/Output Ports • All ports initially set to input • Must declare all output pins using DDRx (Data Direction Registry Port x) • The default for input port pins is floating. Can supply a pull-up resistor by writing logic 1 to the corresponding bit of the port driver register DDRA = 0xC0; /* upper 2 bits are output, lower 6 bits are input*/ PORTA = 0x03; /enable internal pull-ups on lowest 2 bits*/ • Port pins in output mode are typically capable of sinking 20 mA, but source much less.
5V 5V 5V PORTBx set to 0 PORTBx set to 0 5V 5V 5V PORTBx set to 1 PORTBx set to 1 Output PortSink vs Source • When does the LED light for the Sink? Source? • Which gives the brighter light? Sink Source
To Drive an LED #include <avr/io.h> #include <avr/delay.h> int main(void) { DDRB = (1<<DDRB4); PORTB = (1<<PORTB4); while(1) { _delay_ms( 3000); PORTB = 0b00000000; _delay_ms( 3000); PORTB = 0b00010000; } } VCC VCC VCC (PCINT4/XTAL2) PB4 GND Is LED on when PB4 is zero or one? *To find definitions like PORTB4, open the m168def.inc file underC:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes
m168def.inc ;***************************************************************************** ; Bit Definitions ;***************************************************************************** ; - Port B - .equ PORTB7 = 7 ; PORTB .equ PORTB6 = 6 .equ PORTB5 = 5 .equ PORTB4 = 4 .equ PORTB3 = 3 .equ PORTB2 = 2 .equ PORTB1 = 1 .equ PORTB0 = 0 .equ DDB7 = 7 ; DDRB .equ DDB6 = 6 .equ DDB5 = 5 .equ DDB4 = 4 .equ DDB3 = 3 .equ DDB2 = 2 .equ DDB1 = 1 .equ DDB0 = 0 .equ PINB7 = 7 ; PINB .equ PINB6 = 6 .equ PINB5 = 5 .equ PINB4 = 4 .equ PINB3 = 3 .equ PINB2 = 2 .equ PINB1 = 1 .equ PINB0 = 0 ;**********TIMER_COUNTER_0************ ;TCCR0A: .equ COM0A1 =7 .equ COM0A0 =6 .equ COM0B1 =5 .equ COM0B0 =4 .equ WGM01 =1 .equ WGM00 =0 ;***** SPECIFY DEVICE ****************************************************** .device ATmega168 ;***** MEMORY MAPPED I/O REGISTER DEFINITIONS (&FF-$60) ******************** .equ TCNT1H =$85 .equ TCNT1L =$84 .equ TCCR1C =$82 .equ TCCR1B =$81 .equ TCCR1A =$80 .equ DIDR1 =$7F .equ DIDR0 =$7E .equ TIMSK1 =$6F .equ TIMSK0 =$6E .equ PCMSK2 =$6D .equ PCMSK1 =$6C .equ PCMSK0 =$6B ;***** I/O REGISTER DEFINITIONS ($3F-$00) ********************************** .equ SREG =$3F .equ SPH =$3E .equ SPL =$3D .equ SPCR =$2c .equ GPIOR2 =$2B .equ GPIOR1 =$2A .equ OCR0B =$28 .equ OCR0A =$27 .equ TCNT0 =$26 .equ TCCR0B =$25 .equ TCCR0A =$24 .equ PORTD =$0B .equ DDRD =$0A .equ PIND =$09 .equ PORTC =$08 .equ DDRC =$07 .equ PINC =$06 .equ PORTB =$05 .equ DDRB =$04 .equ PINB =$03 *C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes
Limited Agenda for Microprocessor • External Interrupts • INT (Not covered) • PCINT (24 different interrupts) • Internal Interrupts • Timers / Counters (8-bit) • Timer (sec) • Pulse Width Modulation • Setup of Software / Hardware Tools
Interrupts • Interrupts vs Polling • Interrupts may lead to serious problems • Disable interrupts before reading variables • External Interrupts • External Interrupt Request (INT0) • Pin Change Interrupt (PCINT0) • Internal Interrupts
Key Registers: PCINT external interrupts • PCMSK# (were # is either 0, 1 or 2) • PCICR • SREG
ATmega168 Pins PDIP (PCINT13) 1 28 PC5 PC6 (PCINT12) 2 (PCINT16) 27 PC4 PD0 (PCINT11) 3 (PCINT17) 26 PC3 PD1 (PCINT10) 4 (PCINT18) 25 PC2 PD2 (PCINT9) 5 (PCINT19) 24 PC1 PD3 (PCINT8) 6 (PCINT20) 23 PC0 PD4 7 22 GND VCC 8 21 AREF GND 9 (PCINT6) 20 AVCC PB6 (PCINT5) 10 (PCINT7) 19 PB5 PB7 (PCINT4) 11 (PCINT21) 18 PB4 PD5 (PCINT3) 12 (PCINT22) 17 PB3 PD6 13 (PCINT23) 16 PB2 PD7 (PCINT1) 14 (PCINT0) 15 PB1 PB0
1. PCMSK# – Pin Change Mask Register # Bit 7 – 0: Pin Change Enable Mask • Each PCINT# bit selects whether pin change interrupt is enabled on the corresponding I/O pin. If PCINT# is cleared, the pin change interrupt on the corresponding I/O pin is disabled. If you decided to test for a change on Pin 2, the first thing to do is check the Pin Layout to determine what PCINT# corresponds to that pin – PCINT16 in this case. Checking the list of registers above, note that PCINT16 falls on the PCMSK2 register. Enabling a Pin Change interrupt on Pin 2 would consist of: PCMSK2 = 1<<PCINT16 ;
2. PCICR – Pin Change Interrupt Control Register Bit # – PCIE#: Pin Change Interrupt Enable # where (# is 2, 1, or 0) • Whet the PCIE# bit is set (one) and the I-bit in the Status Register (SEG) is set (one), pin change interrupt # is enabled. • Any change on any enabled pin will cause an interrupt. • The corresponding interrupt on Pin Change Interrupt Request is executed from the PCI1 interrupt Vector. • PCIE2 enables PCINT 23 .. 16 pins and are enabled individually by the PCMSK2 register • PCIE1 enables PCINT 14 .. 8 pins and are enabled individually by the PCMSK1 register • PCIE0 enables PCINT 7 .. 0 pins and are enabled individually by the PCMSK0 register Since you just set register PCMSK2, you now have to enable that register by setting PCIE2 to 1. PCICR = 1<<PCIE2;
3. SREG – AVR Status Register Bit 7 – I: Global Interrupt Enable • The Global Interrupt Enable bit must be set for the interrupts to be enabled. • The individual interrupt enable control is then performed in separate control registers. • If the Global Interrupt Enable Register is cleared, none of the interrupts are enabled independent of the individual interrupt enable settings. Finally, you must set the I bit in SREG enabling internal and external interrupts that have been set to operate. To stop all interrupts, just set SREG_I to 0. SREG = 1<<SREG_I ;
Enabling External Interrupts The following code enables interrupts on the PCINT16 pin (e.g., pin 2) SREG = 1<<SREG_I ; PCICR = 1<<PCIE2; PCMSK2 = 1<<PCINT16 ; What do you want to happen after an interrupt is detected?
Defining an Interrupt Routines ISR(PCINT2_vect) { ... // Code to handle the event. } Note that this routine is called whenever pins PCINT23..16 have logical changes. How do you determine which pin actually changed? (Harder than you would think!)
Example of External Interrupt #include <avr/io.h> #include <avr/interrupt.h> ISR( PCINT2_vect) /* Code to execute when external interrupt on PCINT23 .. 16 is triggered by a logic change*/ { PORTB = PORTB ^ 0x02; } int main(void) { // Setup for External Interrupt PCINT16 (uses pin 2 or PD0) SREG = ( 1<<SREG_I ); // Enables global interrupts PCICR = ( 1<<PCIE2 ); // Enables vector interrupts on PCINT23 .. 16 PCMSK2 = ( 1<<PCINT16 ); // Enables individual interrupt PCINT16 only DDRB = 1 << PORTB1; while(1) ; }
Timers/Counter • Most commonly used complex peripherals • Think of them as binary up-counters • In timing mode, count time periods • In counting mode, counting events or pulses • 8-bit and 16-bit Timers available • ATmega168 • Timer/Counter 0 • 8-bit Timer/Counter with Prescaler • Two PWM Channels • Timer/Counter 1 • 16-bit High Speed Timer/Counter with Separate Prescaler • 2 High Frequency PWM Outputs • Timer/Counter 2 • 8-bit Timer/Counter with Prescaler • Two PWM Channels
Top (0xFF) Timer/Counter Register n (TCNTn) Bottom (0x00) Normal Mode • High Frequency • Single Slope • Counter Counts only from Bottom to Top Trips Timer/Counter Overflow Flag
Key Registers to enable Timer • TCCR0A – Timer/Counter0 Control Register A • TCCR0B – Timer/Counter0 Control Register B • TIMSK0 – Timer/Counter Interrupt Mask Register • TIFR0 – Timer/Counter Interrupt Flag Register
1. TCCR0A Register • Bit 1-0 : Waveform Generation Mode • Combined with the WGM02 bit found in the TCCR0B Register, these bits control the counting sequence of the counter, the source of the maximum (TOP) counter value, and what type of waveform generation to be used. Set for Normal Mode (Note we still have to set WGM02 in the TCCR0B Register.) TCCR0A = (0<<WGM00);
2. TCCR0B Register • Bit 3 : Waveform Generation Mode • Use table from previous slide Setting for Phase Correct PWM TCCR0B = (0<<WGM02);
2. TCCR0B Register (Continued) • Bit 2:0 : Clock Select • These bits select the clock source to be used by the Timer/Counter Depends on the Frequency needed. We’ll choose no prescaler. TCCR0B = (0<<WGM02) | (1<<CS00);
3. TIMSK0 Register • Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable • When the TOIE0 bit is written to one, and the I-bit in the Status Register is set, the Timer/Counter0 Overflow interrupt is enabled. The corresponding interrupt is executed if an overflow in Timer/Counter0 occurs, i.e., when the TOV0 bit is set in the Timer/Counter 0 Interrupt Flag Register – TIFR0. Enabling Timer/Counter Overflow Interrupt TIMSK0= (1<<TOIE0);
4. TIFR0 Register • Bit 0 - TOV0: Timer/Counter0 Overflow Flag • The bit TOV0 is set when an overflow occurs in Timer/Counter0. TOV0 is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, TOV0 is cleared by writing a logic one to the flag. When the SREG I-bit, TOIE0, and TOV0 are set, the Timer/Counter0 Overflow interrupt is executed. • (The setting of this flag is dependent on the WGM02:0 bit settings. Refer to the previous table) Clear the Timer/Counter Overflow flag (e.g., initiate the overflow counter) TIFR0 = (1<<TOV0);
Internal Interrupt Timer/Counter0 Overflow Select avr-libc Reference Manual Choose Library Reference Identify Module to include in code Click on Module
Internal Interrupt (Continued) Find Correct InterruptVector ISR ( ?_vect) { //place code to be executed on this interrupt } Write Code to be executed upon theinterrupt
Top (0xFF) Timer/Counter Register n (TCNTn) OCROx Value Bottom (0x00) Period 4 5 6 7 1 2 3 Top (0xFF) TCNTn OCROx Value Bottom (0x00) Period 2 1 3 PWM Modes • Fast PWM Mode • High Frequency • Single Slope • Counter Counts only from Bottom to Top • Suited for power regulation, rectification, and DAC application • Phase Correct PWM Mode • Lower Frequency • Dual Slope • Counter Counts up the down • Suited for motor control applications
Phase Correct PWM Timer/Counter 0 (8-bit) • Set Frequency • Prescaler • Determine Bit Resolution • Set Duty Cycle • Determined by OCR0x
ATmega168 Pins PDIP 1 28 PC5 PC6 2 27 PC4 PD0 3 26 PC3 PD1 4 25 PC2 PD2 5 (OC2B) 24 PC1 PD3 6 23 PC0 PD4 7 22 GND VCC 8 21 AREF GND 9 20 AVCC PB6 10 19 PB5 PB7 11 (OC0B) 18 PB4 PD5 (OC2A) 12 (OC0A) 17 PB3 PD6 (OC1B) 13 16 PB2 PD7 (OC1A) 14 15 PB1 PB0
Key Registers to enable Phase Correct PWM • TCCR0A – Timer/Counter0 Control Register A • TCCR0B – Timer/Counter0 Control Register B • OCR0x – Output Compare Register x An 8-bit Register where x stands for either A or B. e.g., Timer 0 has Output onPD6 (Pin 12) for OC0A and PD5 (Pin 11) for OC0B We’ll use A for our example.
1. TCCR0A Register • Bit 7- 6 : Compare match Output A Mode • These bits control the Output Compare pin (OC0A) behavior. If one or both of the COM0A0:1 bits are set, the 0C0A output overrides the normal port functionality of the I/0 pin it is connected to. • Note, however, that the Data Direction Register (DDR) bit corresponding to the OC0A pin must be set to enable the output driver We’ll set COMOA to 3. TCCR0A = (3<<COMOA0);
1. TCCR0A Register (Continued) • Bit 1-0 : Waveform Generation Mode • Combined with the WGM02 bit found in the TCCR0B Register, these bits control the counting sequence of the counter, the source of the maximum (TOP) counter value, and what type of waveform generation to be used. Set for Phase Correct PWM (Note we still have to set WGM02 in the TCCR0B Register.) TCCR0A = (3<<COMOA0) | (1<<WGM00);
2. TCCR0B Register • Bit 3 : Waveform Generation Mode • Use table from previous slide Setting for Phase Correct PWM TCCR0B = (0<<WGM02);
2. TCCR0B Register (Continued) • Bit 2:0 : Clock Select • These bits select the clock source to be used by the Timer/Counter Depends on the Frequency needed. We’ll choose a prescaler of 8. TCCR0B = (0<<WGM02) | (2<<CS00);