Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:lab:lab0xc0-2 [2020/03/22 14:00]
alexandru.predescu
pm:lab:lab0xc0-2 [2020/03/29 13:04] (current)
dumitru.tranca old revision restored (2020/03/27 17:14)
Line 1: Line 1:
 <​hidden>​ <​hidden>​
 +Formatul si observatii:
 +  * Conferinta globala pentru prezentare si call cu fiecare pentru feedback individual si verificare.
 +  * Daca dureaza mai mult de 2 ore, sau daca sunt deja mai multi care au terminat, se poate verifica direct pe channel ca sa mearga mai repede. (chiar daca se mai inspira unii de la altii, macar s-au chinuit 2 ore). La mine a durat luni aproape 3 ore chiar si asa.
 +  * Atentie la rezistente sa nu puna 10k pe LED-uri si sa se incurce ca nu lumineaza.
 +  * Save periodic la schema.
 +  * La ex 5, 6 sunt 2 variante, una mai simpla (un singur digit) cu 2p si una mai complicata (2 digiti cu multiplexare) cu 3p.
 +  * Total 10p/12p.
 +</​hidden>​
 +
 +/​*<​hidden>​*/​
 +
 +====== Laboratorul 0xC1: Interrupts and Timers. Build a 7-segment digital counter ======
  
-This lab covers the basics for working with **External Interrupts**,​ **Pin Change Interrupts** and **Timers** on the Atmega324. You will use buttons ​to interact with your design ​and you will create your own display using the good old 7-segment display. You can check out the lab [[pm:​lab:​lab2|Laboratorul 2: Întreruperi,​ Timere]] and datasheet ​(({{:​pm:​doc8272.pdf|Datasheet ATmega324}}) for more information and references about timers and interrupts.+This lab covers the basics for working with **External Interrupts**,​ **Pin Change Interrupts** and **Timers** on the Atmega324. You will use timers and interrupts ​to create a digital counter ​and you will use buttons, LEDs and the good old 7-segment display ​to interact with your design in Proteus. You can check out the lab [[pm:​lab:​lab2|Laboratorul 2: Întreruperi,​ Timere]] and datasheet ({{:​pm:​doc8272.pdf|Datasheet ATmega324}}) for more information and references about timers and interrupts.
  
-====== Interrupts and Timers ​======+===== Interrupts and Timers =====
  
 ==== Interrupts ==== ==== Interrupts ====
Line 21: Line 33:
  
 <note tip> <note tip>
-External Interrupts and Pin Change Interrupts are both used to detect GPIO events. There are only 3 External Interrupts on the Atmega324 and they can be configured for edge detection (rising edge, falling edge), while Pin Change Interrupts are available for all the ports (and pins) to detect logic level changes.+External Interrupts and Pin Change Interrupts are both used to detect GPIO events. There are only 3 External Interrupts on the Atmega324 and they can be configured for edge detection (rising edge, falling edge) on pins PD2, PD3 and PB2, while Pin Change Interrupts are available for all the ports (and pins) to detect logic level changes ​(but require more overhead to detect the pin that triggered the interrupt).
 </​note>​ </​note>​
  
Line 64: Line 76:
     // disable global interrupts     // disable global interrupts
     cli();     cli();
- 
     // configure pin change interrupt vector     // configure pin change interrupt vector
     PCICR |= (1 << PCIE1); // enable the pin change interrupt, set PCIE1 to enable PCMSK1 scan     PCICR |= (1 << PCIE1); // enable the pin change interrupt, set PCIE1 to enable PCMSK1 scan
- 
     // enable pin change interrupt     // enable pin change interrupt
     PCMSK1 |= (1 << PCINT9); // Turns on PCINT9 (PB1)     PCMSK1 |= (1 << PCINT9); // Turns on PCINT9 (PB1)
- 
     // enable global interrupts     // enable global interrupts
     sei();     sei();
Line 78: Line 87:
 ISR(PCINT1_vect) ISR(PCINT1_vect)
 { {
-    // cod întrerupere de tip pin change +    // interrupt code
     if ((PINB & (1 << PB1)) == 0)     if ((PINB & (1 << PB1)) == 0)
     {     {
-        // întrerupere generată de pinul PB1+        // interrupt generated by PB1
     }     }
 } }
Line 90: Line 98:
 ==== Timers ==== ==== Timers ====
  
-Timers are used to count fixed time intervals without busy-waiting (delay). They are defined by the counter register //TCNT//, a prescaler and some interrupt vectors that can be defined to trigger when the counter reaches a given threshold (e.g //OCRnA//, //OCRnB//).+Timers are used to count fixed time intervals without busy-waiting (delay). They are defined by the counter register //TCNT//, a prescaler and some interrupt vectors that can be defined to trigger when the counter reaches a preset ​threshold (e.g //OCRnA//, //OCRnB//).
  
 Timers can be configured for multiple use cases: Timers can be configured for multiple use cases:
Line 118: Line 126:
  
 As we know, all the peripherals,​ including Timers are connected to the CPU by some registers for configuration and input-output:​ As we know, all the peripherals,​ including Timers are connected to the CPU by some registers for configuration and input-output:​
-  * TCCRn: In this register (used to configure the timer), there are 8 bits, but only last 3 bits CS02, CS01 and CS00 are used. These are CLOCK SELECT ​bits used to setup the prescaler.+  * TCCRn: In this register (used to configure the timer), there are 8 bits, but only last 3 bits CS02, CS01 and CS00 are used. These are ClockSelect ​bits used to setup the prescaler.
   * TCNTn: This is the timer counter register. ​   * TCNTn: This is the timer counter register. ​
   * TIMSKn: This register is used to enabled/​disable the Timer interrupts.   * TIMSKn: This register is used to enabled/​disable the Timer interrupts.
Line 157: Line 165:
 7-segment LED displays are used in many applications as front panel numeric indicators. The most common applications are calculators,​ digital clocks, microwave ovens, electronic lab equipment like function generators and frequency counters. It's also common to have 7-segment displays that have a dot that can be enabled after the digit. 7-segment LED displays are used in many applications as front panel numeric indicators. The most common applications are calculators,​ digital clocks, microwave ovens, electronic lab equipment like function generators and frequency counters. It's also common to have 7-segment displays that have a dot that can be enabled after the digit.
  
-{{:​pm:​lab:​lab2:​7segment_digit.png?​100|}}+{{ :​pm:​lab:​lab2:​7segment_digit.png?​100 |}}
  
 A 7-segment LED display is an arrangement of LED bars (a, b, c, d, e, f, g, dp) that can be powered individually to display digits (and some characters too). The configuration can be either common anode or common cathode: A 7-segment LED display is an arrangement of LED bars (a, b, c, d, e, f, g, dp) that can be powered individually to display digits (and some characters too). The configuration can be either common anode or common cathode:
-  * Common anode: the anodes (positive) side of all the LEDs are electrically connected at one pin and each LED cathode (negative) side has its own pin +  ​* **Common anode**: the anodes (positive) side of all the LEDs are electrically connected at one pin and each LED cathode (negative) side has its own pin 
-  * Common cathode: the cathodes (negative) side of all the LEDs are electrically connected at one pin and each LED anode (positive) side has its own pin+  ​* **Common cathode**: the cathodes (negative) side of all the LEDs are electrically connected at one pin and each LED anode (positive) side has its own pin
  
-{{:​pm:​lab:​lab2:​common_cathode.png?​400|}}+{{ :​pm:​lab:​lab2:​common_cathode.png?​400 |}}
  
-{{:​pm:​lab:​lab2:​common_anode.png?​400|}}+{{ :​pm:​lab:​lab2:​common_anode.png?​400 |}}
  
 <note tip> There are also variants with more than one digit integrated into the display component. Multiple digit displays are the reason why the cathodes (or anodes) are connected, so that the digits can be multiplexed and not use a whole bunch of pins to drive the display.</​note>​ <note tip> There are also variants with more than one digit integrated into the display component. Multiple digit displays are the reason why the cathodes (or anodes) are connected, so that the digits can be multiplexed and not use a whole bunch of pins to drive the display.</​note>​
  
-The following lookup table may be useful for programming a 7-segment display driver to show digits:+The following lookup table may be useful for programming a 7-segment display driver to show some numbers:
  
 ^ Digit ^ hex ^ a ^ b ^ c ^ d ^ e ^ f ^ g ^| ^ Digit ^ hex ^ a ^ b ^ c ^ d ^ e ^ f ^ g ^|
Line 182: Line 190:
 | 8 | 0x7f | 1 | 1 | 1 | 1 | 1 | 1 | 1 | | 8 | 0x7f | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
 | 9 | 0x7b | 1 | 1 | 1 | 1 | 0 | 1 | 1 | | 9 | 0x7b | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
-</​tabcaption>​+
  
  
Line 189: Line 197:
 {{ :​pm:​diverse:​carantina-proteus.jpg?​200 |}} {{ :​pm:​diverse:​carantina-proteus.jpg?​200 |}}
  
-1. Now we are dealing with timers, so accurate timing is important. In the previous lab, the microcontroller was configured to use the internal 8MHz oscillator on the Atmega for clock generation, with a clock divider (''​CLKDIV8''​ fuse bit) set by default, making for a 1MHz actual clock. However, if we want higher precision/​more speed we can use an external oscillator (crystal/​quartz) with frequencies up to 20MHz for the Atmega324. For this, we have to set the fuse bits as shown in the figure below. Fuse bits, also known as fuses or configuration bits are used to control certain operations. These are not normally changed during the execution of the program code. Right click on the microcontroller and select //Edit Component// to open the configuration editor and change the fuse bits to use external oscillator (''​CKSEL''​ Fuses) and disable the clock divider (clear '​CLKDIV8'​) fuse bit. Configure the clock speed at 12MHz (for convenience,​ to match the clock on the PM boards):+**1.** (1p) Now we are dealing with timers, so accurate timing is important. ​ 
 + 
 +In the previous lab, the microcontroller was configured ​(by default) ​to use the internal 8MHz oscillator on the Atmega for clock generation, with a clock divider (''​CLKDIV8''​ fuse bit) set by default, making for a 1MHz actual clock. However, if we want higher precision/​more speed we can use an external oscillator (crystal/​quartz) with frequencies up to 20MHz (with Vcc = 5V) for the Atmega324. ​ 
 + 
 +For this, we have to set the fuse bits as shown in the figure below. Right click on the microcontroller and select //Edit Component// to open the configuration editor and change the fuse bits to use external oscillator (''​CKSEL''​ Fuses) and disable the clock divider (clear '​CLKDIV8'​) fuse bit. Configure the clock speed at 12MHz (for convenience,​ to match the clock on the PM boards ​and use the same Makefile): 
 + 
 +<note tip> 
 +Fuse bits, also known as fuses or configuration bits are used to control certain operations. These are not normally changed during the execution of the program code. 
 +</​note>​
  
 {{ :​pm:​lab:​lab2:​config_ext_osc.png?​400 |}} {{ :​pm:​lab:​lab2:​config_ext_osc.png?​400 |}}
  
-2. Add a quartz crystal from the parts list and connect it to the ''​XTAL1''​ and ''​XTAL2''​ pins on the Atmega324. Right click on the crystal to open the configuration editor and set the frequency to 12MHz.+**2.** (1p) Add a quartz crystal from the parts list and connect it to the ''​XTAL1''​ and ''​XTAL2''​ pins on the Atmega324. Right click on the crystal to open the configuration editor and set the frequency to 12MHz. Note: for physical designs, you need additional 22pF capacitors on each pin (with the other sides connected to GND).
  
-3. Connect a push button to ''​PD3''​ and a generic LED to ''​PD4''​. Pick a resistor for the LED to draw less than 10mA. The LED will show the state (enabled/​disabled) of the 7-segment digital counter that we'll build next. When the user pushes the button, the program will enable/​disable the counter instantly (use interrupts on ''​PD3''​ and the PCINT ISR on ''​PORTD''​ to detect the button transition).+**3.** (2p) Connect a push button to ''​PD3''​ and a generic LED to ''​PD4''​. Pick a resistor for the LED to draw less than 10mA. The LED will show the state (enabled/​disabled) of the 7-segment digital counter that we'll build next. When the user pushes the button, the program will enable/​disable the counter instantly (use interrupts on ''​PD3''​ and the PCINT ISR on ''​PORTD''​ to detect the button transition).
  
-{{ :​pm:​lab:​lab2:​schematic.png?​400 |}}+{{ :​pm:​lab:​lab2:​schematic.png?​600 |}}
  
-4. Configure Timer1 to generate interrupts every second. Now, use a software counter (aka. variable) to count seconds ([0..9for 5.1 and [0..99for 5.2). Remember to use the ''​volatile''​ keyword (e.g. volatile uint8_t counter;) for variables that you use in interrupts. Also, try to use standard types from ''​stdlib.h''​ (e.g. int8_t, uint8_t, uint16_t, uint32_t). Now, add another LED to ''​PD2''​ to check if the counter is working. Make the LED toggle on each timer interrupt. Watch the LED blinking. What is the frequency of the LED blinking?+**4.** (2p) Configure Timer1 to generate interrupts every second. Now, use a software counter (aka. variable) to count seconds (0-9 for 5.1 and 0-99 for 5.2). Now, add another LED to ''​PD2''​ to check if the counter is working. Make the LED toggle on each timer interrupt. Watch the LED blinking. What is the frequency of the LED blinking?
  
-5.1. (entry level) Start by connecting a single 7-segment digit to the microcontroller. Pick a 7-segment common cathode display and place it on the schematic. Connect the anodes to ''​PORTA'' ​[0..6] through a resistor network (single resistors work tooand the cathode to groundWrite a program ​to count seconds ​from 0 to 9 and then start over.+<note tip> 
 +Remember ​to use the ''​volatile'' ​keyword (e.gvolatile uint8_t counter;for variables that you use in interruptsAlso, try to use standard types from ''​stdlib.h''/''​stdint.h''​ (e.g. int8_t, uint8_t, uint16_t, uint32_t). 
 +</​note>​
  
-5.2. (master of segments) The 7-segment display has to show numbers from 00 to 99. Pick a 7-segment common cathode display and place two of them on the schematic. Each digit will share the anodes that are connected to ''​PORTA'' ​[0..6through a resistor network (single resistors work too). The cathodes will be used to switch the digits on/off fast enough so that the POV (persistance of vision) effect will give you the impression that both digits are visible at the same time. This way, you can make 7-segment displays with more digits that also draw less power and use less pins on the microcontroller. Pick a transistor (2n2222A is a good choice for switching) and place two of them to drive the cathodes. Connect the base of each transistor to a microcontroller pin with a resistor of 1k in between. Let's use ''​PA7''​ and ''​PC2''​. Write a program ​to count seconds from 0 to 99 and then start over.+**5.** (2p/3p) Place and connect the components on the schematic for building the 7-segment display 
 + 
 +    * **Entry Level.** Start by connecting a single 7-segment digit to the microcontroller. Pick a 7-segment common cathode display and place it on the schematic. Connect the anodes to ''​PORTA''​ 0..6 through a resistor network ​(single resistors work tooand the cathode to ground. Write a program that counts seconds from 0 to 9 and then starts over. 
 +    * **Master of Segments.** ​The 7-segment display has to show numbers from 00 to 99. Pick a 7-segment common cathode display and place two of them on the schematic. Each digit will share the anodes that are connected to ''​PORTA''​ 0..6 through a resistor network (single resistors work too). Pick a transistor (//2n2222A// is a good choice for switching) and place two of them to drive the cathodes. Connect the base of each transistor to a microcontroller pin with a resistor of 1k in between. Let's use ''​PA7''​ and ''​PC2''​. Write a program ​that counts ​seconds from 0 to 99 and then starts ​over. 
 + 
 +<note tip> 
 +The common cathodes will be used to switch the digits on/off fast enough so that the POV (persistance of vision) effect will give you the impression that both digits are visible at the same time. This way, you can make 7-segment displays with more digits that also draw less power and use less pins on the microcontroller. 
 +</​note>​
  
 Check out the 7-segment display counter in action: Check out the 7-segment display counter in action:
Line 211: Line 236:
 {{ :​pm:​lab:​lab2:​schematic_digit_2.png?​400 |}} {{ :​pm:​lab:​lab2:​schematic_digit_2.png?​400 |}}
  
-6. In the main loop, get the digits from the counter (variable) and use them to drive the two 7-segment displays. ​Remember to mask the ''​PA7''​ pin when writing the binary combination on ''​PORTA''​ as that pin is being used for another task (enabling the digits). Light up the segments as shown in the truth table and show each of the two digits with a small delay between them. You can actually use the //​_delay_ms//​ function in the main loop and this will not affect your timing (counting is done in interrupts). Note: In simulation, you will have to use at least 100 ms and you won't be able to see them both at the same time.+**6.** (2p/​3p) ​In the main loop, get the digits from the counter (variable) and use them to drive the two 7-segment displays. ​Power the segments as shown in the truth table and show each of the two digits with a small delay between them. You can actually use the //​_delay_ms//​ function in the main loop and this will not affect your timing (counting is done with timer interrupts). Note: In simulation, you will have to use at least 100 ms and you won't be able to see them both at the same time. 
 + 
 +<note tip> 
 +Remember to mask the ''​PA7''​ pin when writing the binary combination of segments on ''​PORTA''​ as that pin is being used for another task (enabling the digits) 
 +</​note>​
  
 ---- ----
 +<​hidden>​
 +  * Solutie laborator: {{:​pm:​diverse:​carantina-lab0xc1-sol.zip|}}
 +</​hidden>​
 +  * Schema: {{:​pm:​diverse:​schematic-0xc1.zip|}}
  
   * Lab archive: {{:​pm:​diverse:​carantina-lab0xc1.zip|}}   * Lab archive: {{:​pm:​diverse:​carantina-lab0xc1.zip|}}
Line 219: Line 252:
   * Author:​[[alexandru.predescu@cs.pub.ro | Alexandru Predescu]]   * Author:​[[alexandru.predescu@cs.pub.ro | Alexandru Predescu]]
  
-</​hidden>​+/*</​hidden>​*/
pm/lab/lab0xc0-2.1584878419.txt.gz · Last modified: 2020/03/22 14:00 by alexandru.predescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0