Uploaded by HoΓ ng Nguyα»…n

CTC counter cal

advertisement
Tutorial 3
Timer/Counter with AVR Controller
Exercise 1 - Getting started with AVR Timer
In this task, we will get used to use Timer for blinking LEDs. For example, we will generate a square
wave with the frequency of 1000 Hz. You need to choose the Timer that is appropriate, in normal
counting mode and we will not use Interrupts.
A. Calculation
First of all, we need to perform a bit of calculation in advance to set the right Timer count for the
timer. Use the following formula for that purpose:
π‘‡π‘Žπ‘Ÿπ‘”π‘’π‘‘ π‘‡π‘–π‘šπ‘’π‘Ÿ πΆπ‘œπ‘’π‘›π‘‘ = (
1
1
/
) − 1
2 π‘₯ π‘‡π‘Žπ‘Ÿπ‘”π‘’π‘‘ π‘“π‘Ÿπ‘’π‘žπ‘’π‘’π‘›π‘π‘¦
π‘‡π‘–π‘šπ‘’π‘Ÿ πΆπ‘™π‘œπ‘π‘˜ πΉπ‘Ÿπ‘’π‘žπ‘’π‘’π‘›π‘π‘¦
For example, I am using the board with the external clock of 16Mhz, so I can get the timer count as
π‘‡π‘Žπ‘Ÿπ‘”π‘’π‘‘ π‘‡π‘–π‘šπ‘’π‘Ÿ πΆπ‘œπ‘’π‘›π‘‘ = (
1
1
16,000,000
/
) − 1=
− 1 = πŸ•, πŸ—πŸ—πŸ—
2 π‘₯ 1000 16,000,000
2,000
Atmega328p has couple timers:
o
o
TC0 – 8-bit timer (value counts from 0 to 28 − 1 = 255)
TC1 – 16-bit timer (value counts from 0 to 216 − 1 = 65,535)
With the timer count of 7,999, we cannot use the 8-bit timer but 16-bit timer instead.
B. Programming and Testing
1. Create a new project as done in the Tutorial 1 – name it Tut31_Arduino
2. For this part we don’t need to connect any LEDs to the board but instead we can use the
built-in LED of the board. This LED is connected to the Pin 13 of the header – and the Pin PB5
of the Atmega328p
EEET2505
Ref:
https://circuito.cdn.prismic.io/circuito/8e3a980f0f964cc539b4cbbba2654bb660db6f52_arduinouno-pinout-diagram.png
3. Type in the following code
#include <avr/io.h>
int main(void)
{
DDRB |= (1 << 5);
// Set LED connected PORT B, Pin 5 as output
TCCR1B |= (1 << CS10 ); // Set up timer1 (16 bit)
while (1)
{
// Check timer value in if statement , true when count matches 0.5ms (half
cycle)
if ( TCNT1 >= 7999)
{
PORTB ^= (1 << 5); // Toggle the LED
TCNT1 = 0; // Reset timer value
}
}
}
4. Build and download the code onto the Arduino Uno, you should see the LED seems to
turn ON all the time. This LED blinks quick than you can observe hence we need some
instruments to observe the frequency.
EEET2505
C. Measuring on Virtual Bench
Note – this step we cannot do for this Semester 2021B yet. I still leave them here so you can review
when you have chance.
1. Setup NI Virtual Bench
a. Connect cables (power + USB)
b. From My Computer -> Virtual Bench Drive
5.
EEET2505
Connect the Logic Analyser to the pin where PB5 is connected, the pin labelled 13 in the
header
a. Use the Schematic to support the connection.
b. Take two wires from the Logic Analyser – for example D0 and GND. Then plug to the
pin 13 (PORTB5) and GND)
c. The setup is as follows
6. Turn on Digital channel – Choose the pin that you want to observe (in my case is Digital 0)
If the result is not shown yet, you can click on Auto setup and then adjust the scale.
Then Adjust the scale by using your middle mouse by scrolling up and down until you receive a full
waveform
EEET2505
7. Read the measured frequency
a. Turn on measurement
b. Press the values that you wish to measure, for example Period, Duty cycle and
Frequency
c. Read the result
So, we have successfully generated a 1000hz signal with Timer 1 of the AVR. This confirm the results
from the code that was written earlier.
Note – if you are using the Oscilloscope, you can apply the process given in the supporting video on
Canvas to perform the measurement as done with the Virtual Bench above.
EEET2505
D. Analysis
For Timer to work, it is important for us to work with the two registers. In this part you will find
yourself need to learn how to read and use the information from Datasheet of the Microcontroller
since we will rely on it a lot.
1. The choice of Timer in this part. The 16-bit Timer 1 is chosen here. The microcontroller has
other Timers that you can choose.
YOU SHOULD ALSO GET FAMILIAR WITH THE Chapter about Timer 1 IN THE DATASHEET THAT
DESCRIBE THIS TIMER
2. First, we need to configure the Timer. Few things to highlight here first. In this section we
will use the Timer in its Normal Mode and with no prescaling at all
a. You are required to read through the Modes of Operation part. For example, Page
161 of the Datasheet
b. With that we need to set the register accordingly. Next you need to check out the
Register Description at 20.14. For timer you need to configure 2 Register: TCCR1A
(Timer/Counter1 Control Register A) and TTCR1B (Timer/Counter1 Control Register
B). With the configuration above you need to check out the Table of configuration
i. For Normal mode – we don’t need to set WGM10 and WGM11 (belong to
TTCR1A) and WGM12 and WGM13 (belong to TTCR1B)
ii. For Normal mode, we don’t have to set others bits belong to Compare
Output Mode in the TTCR1A
With i and ii -> we don’t have to set TTCR1A and they can have their default value after reset
as 0x00
EEET2505
iii. For the non-pre-scaling, according to the table we need to set the CS10 as 1
in the TTCR1A
With the above you then can set the TTCR1B
TCCR1B |= (1 << CS10 ); // Set up timer1 (16 bit)
3. Next, once we have done the configuration for the normal mode, we need to set the top
counter value via the counter value register TCNT1 (16-bit register combined from TCNT1H
and TCNT1L)
a. With the calculation earlier we can set the cap is at 7999 and use the conditional
condition in C to check this.
b. When the condition is met then the LED is toggle to indicate the timer is hit.
c. Finally, we need to reset the timer value.
if ( TCNT1 >= 7999)
{
PORTB ^= (1 << 5); // Toggle the LED
TCNT1 = 0; // Reset timer value
}
EEET2505
Exercise 2 - Prescaled Timers (Hardware Approach)
In the above task, we have used 16-bit timer TC1, which can hold a value in the range of 0 - 65535. In
case we need to create a larger delay time, we can use the timer's prescaler – the internal circuit to
divide the clock signals (by a power of two).
To learn this, we will generate a square wave with the frequency of 1Hz (period = 1s) in this task –
0.5ms for ON and 0.5ms for OFF
A. Calculation
The formula to calculate the Timer count now includes the Prescale value
π‘‡π‘Žπ‘Ÿπ‘”π‘’π‘‘ π‘‡π‘–π‘šπ‘’π‘Ÿ πΆπ‘œπ‘’π‘›π‘‘ = (
1
π‘ƒπ‘Ÿπ‘’π‘ π‘π‘Žπ‘™π‘’
/
) − 1
2 π‘₯ π‘‡π‘Žπ‘Ÿπ‘”π‘’π‘‘ π‘“π‘Ÿπ‘’π‘žπ‘’π‘’π‘›π‘π‘¦
π‘‡π‘–π‘šπ‘’π‘Ÿ πΆπ‘™π‘œπ‘π‘˜ πΉπ‘Ÿπ‘’π‘žπ‘’π‘’π‘›π‘π‘¦
With the target frequency of 1Hz, we can get the Timer Count value with different prescaler values
as below
Prescaler Value
1
Target Timer Count
Observation
16,000,000
−
2π‘₯1π‘₯1
The timer value is above the
range of a 16-bit counter (0 –
63,535)
1 = 7,999,999
8
999,999
64
124,999
256
31,249
This can be used since it is within
the range of 16-bit timer
1024
7811.5
Can be used but rounding can
cause the slight difference in the
time delay
From the table, it can be seen the Timer Count value affect our decision to choose the prescaler value.
From the table we can attempt to use the prescaler of 256 and use Timer Count of 31,249, which is in
the range of the 16-bit counter. We will try these two in the code.
In order to configure the Prescaler we need to configure the register Timer Counter TCCR1B. Three
bits we need to pay attention is CS10 to CS12 (as seen in the datasheet)
EEET2505
B. Programming and Testing
1. Edit the code above to reflect the change
#include <avr/io.h>
int main(void)
{
DDRB |= (1 << 5); // Set LED as output
//TCCR1B |= (1 << CS10 ); // Set up timer 1 (16 bit)
TCCR1B |= (1 << CS12 ); // Set up timer with the prescaler of 256
while (1)
{
// Check timer value in if statement , true when count matches 0.5s (half
cycle)
//if ( TCNT1 >= 7999)
if ( TCNT1 >= 31249)
// New Timer Count for Prescaled Timer.
{
PORTB ^= (1 << 5); // Toggle the LED
TCNT1 = 0; // Reset timer value
}
}
}
2. Build and download the code
3. Observe the LED
4. Measure the actual frequency using NI Virtual Bench
As seen, we have successfully generated a clock of 1 Hz
Note – for this long delay (to the Virtual Bench), you need to wait for the OSC to finish triggering and
you might not observe that many cycles of signal on the instruments.
EEET2505
C. Analysis
1. The code in this section is pretty similar to the above except two places
a. Where you need to set the set the TTCR1B to accommodate the Prescaler discussed
earlier.
TCCR1B |= (1 << CS12 ); // Set up timer with the prescaler of 256
b. Secondly, the Timer value is set according to the calculation above
if ( TCNT1 >= 31249)
EEET2505
// New Timer Count for Prescaled Timer.
Download