0% found this document useful (0 votes)
23 views42 pages

Lab 2

The document discusses using a timer interrupt to control LED scanning on a microcontroller. It provides an introduction to timer interrupts and describes how to configure a timer interrupt on STM32 microcontrollers using STM32CubeIDE. Exercises are presented for students to implement timer-based LED scanning applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views42 pages

Lab 2

The document discusses using a timer interrupt to control LED scanning on a microcontroller. It provides an introduction to timer interrupts and describes how to configure a timer interrupt on STM32 microcontrollers using STM32CubeIDE. Exercises are presented for students to implement timer-based LED scanning applications.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Dr.

Le Trong Nhan
Mục lục

Chapter 1. Timer Interrupt and LED Scanning 7


1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2 Timer Interrupt Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Exercise and Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1 Exercise 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Exercise 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Exercise 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4 Exercise 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.5 Exercise 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.6 Exercise 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.7 Exercise 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.8 Exercise 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.9 Exercise 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.10 Exercise 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.11 Link Github . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Microcontroller Page 5
Page 6 HCMUT - Computer Engineering
CHƯƠNG 1

Timer Interrupt and LED Scanning


1 Introduction

Timers are one of the most important features in modern micro-controllers. They
allow us to measure how long something takes to execute, create non-blocking
code, precisely control pin timing, and even run operating systems. In this manual,
how to configure a timer using STM32CubeIDE is presented how to use them to
flash an LED. Finally, students are proposed to finalize 10 exercises using timer
interrupt for applications based LED Scanning.

Hình 1.1: Four seven segment LED interface for a micro-controller

Design an interface for with multiple LED (seven segment or matrix) displays which
is to be controlled is depends on the number of input and output pins needed for
controlling all the LEDs in the given matrix display, the amount of current that
each pin can source and sink and the speed at which the micro-controller can
send out control signals. With all these specifications, interfacing can be done for
4 seven segment LEDs with a micro-controller is proposed in the figure above.

In the above diagram each seven segment display is having 8 internal LEDs, lead-
ing to the total number of LEDs is 32. However, not all the LEDs are required to
turn ON, but one of them is needed. Therefore, only 12 lines are needed to control
the whole 4 seven segment LEDs. By controlling with the micro-controller, we can
turn ON an LED during a same interval TS . Therfore, the period for controlling all
4 seven segment LEDs is 4TS . In other words, these LEDs are scanned at frequecy
f = 1/4TS . Finally, it is obviously that if the frequency is greater than 30Hz (e.g. f =
50Hz), it seems that all LEDs are turn ON at the same time.

In this manual, the timer interrupt is used to design the interval TS for LED scan-
ning. Unfortunately, the simulation on Proteus can not execute at high frequency,
the frequency f is set to a low value (e.g. 1Hz). In a real implementation, this fre-

Page 8 HCMUT - Computer Engineering


quency should be 50Hz.

Microcontroller Page 9
2 Timer Interrupt Setup

Step 1: Create a simple project, which LED connected to PA5. The manual can be
found in the first lab.

Step 2: Check the clock source of the system on the tab Clock Configuration (from
*.ioc file). In the default configuration, the internal clock source is used with 8MHz,
as shown in the figure bellow.

Hình 1.2: Default clock source for the system

Step 3: Configure the timer on the Parameter Settings, as follows:

Hình 1.3: Configure for Timer 2

Select the clock source for timer 2 to the Internal Clock. Finally, set the prescaller
and the counter to 7999 and 9, respectively. These values are explained as follows:

Page 10 HCMUT - Computer Engineering


• The target is to set an interrupt timer to 10ms

• The clock source is 8MHz, by setting the prescaller to 7999, the input clock
source to the timer is 8MHz/(7999+1) = 1000Hz.

• The interrupt is raised when the timer counter is counted from 0 to 9, mean-
ing that the frequency is divided by 10, which is 100Hz.

• The frequency of the timer interrupt is 100Hz, meaning that the period is
1/100Hz = 10ms.

Step 4: Enable the timer interrupt by switching to NIVC Settings tab, as follows:

Hình 1.4: Enable timer interrupt

Finally, save the configuration file to generate the source code.

Step 5: On the main() function, call the timer init function, as follows:
1 int main ( void )
2 {
3 HAL_Init () ;
4 SystemClock_Config () ;
5

6 MX_GPIO_Init () ;
7 MX_TIM2_Init () ;
8

9 /* USER CODE BEGIN 2 */


10 HAL_TIM_Base_Start_IT (& htim2 ) ;
11 /* USER CODE END 2 */ g3
12

13 while (1) {
14

15 }
16 }
Program 1.1: Init the timer interrupt in main

Please put the init function in a right place to avoid conflicts when code genera-
tion is executed (e.g. ioc file is updated).

Microcontroller Page 11
Step 6: Add the interrupt service routine function, this function is invoked every
10ms, as follows:
1 /* USER CODE BEGIN 4 */
2 void HA L_ TIM_PeriodElapsedCallback ( TIM_HandleTypeDef * htim )
{
3

4 }
5 /* USER CODE END 4 */
Program 1.2: Add an interrupt service routine

Step 7: To run a LED Blinky demo using interrupt, a short manual is presented as
follows:
1 /* USER CODE BEGIN 4 */
2 int counter = 100;
3 void HA L_ TIM_PeriodElapsedCallback ( TIM_HandleTypeDef * htim )
{
4 counter - -;
5 if ( counter <= 0) {
6 counter = 100;
7 HAL_GPIO_TogglePin ( LED_RED_GPIO_Port , LED_RED_Pin ) ;
8 }
9 }
10 /* USER CODE END 4 */
Program 1.3: LED Blinky using timer interrupt

The HAL_TIM_PeriodElapsedCallback function is an infinite loop, which is in-


voked every cycle of the timer 2, in this case, is 10ms.

Page 12 HCMUT - Computer Engineering


3 Exercise and Report

3.1 Exercise 1

The first exercise show how to interface for multiple seven segment LEDs to STM32F103C6
micro-controller (MCU). Seven segment displays are common anode type, mean-
ing that the anode of all LEDs are tied together as a single terminal and cathodes
are left alone as individual pins.

In order to save the resource of the MCU, individual cathode pins from all the
seven segment LEDs are connected together, and connect to 7 pins of the MCU.
These pins are popular known as the signal pins. Meanwhile, the anode pin of
each seven segment LEDs are controlled under a power enabling circuit, for in-
stance, an PNP transistor. At a given time, only one seven segment LED is turned
on. However, if the delay is small enough, it seems that all LEDs are enabling.

Implement the circuit simulation in Proteus with two 7-SEGMENT LEDs as follow-
ing:

Hình 1.5: Simulation schematic in Proteus

Components used in the schematic are listed bellow:

• 7SEG-COM-ANODE (connected from PB0 to PB6)

• LED-RED

• PNP

• RES

• STM32F103C6

Microcontroller Page 13
Students are proposed to use the function display7SEG(int num) in the Lab 1 in
this exercise. Implement the source code in the interrupt callback function to dis-
play number "1" on the first seven segment and number "2" for second one. The
switching time between 2 LEDs is half of second.

Report 1: Capture your schematic from Proteus and show in the report.

Hình 1.6: Schematic for exercise 1

Report 2: Present your source code in the HAL_TIM_PeriodElapsedCallback func-


tion.

1 int counter = 50;


2 void HA L_ TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *
htim ) {
3 counter - -;
4 if ( counter <= 0) {
5 time_flag = 1;
6 }
7 }
Program 1.4: Source code in the HAL_TIM_PeriodElapsedCallback function

1 enum SevenSegmentState { SEVEN_SEGMENT_0 = 0 ,


SEVEN_SEGMENT_1 = 1};
2 enum SevenSegmentState seven_segment_status =
SEVEN_SEGMENT_0 ;
3 HAL_TIM_Base_Start_IT (& htim2 ) ;
4 /* USER CODE END 2 */
5

6 /* Infinite loop */
7 /* USER CODE BEGIN WHILE */
8 while (1)
9 {
10 switch ( seven_segment_status ) {
11 case SEVEN_SEGMENT_0 :

Page 14 HCMUT - Computer Engineering


12 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_RESET ) ;
13 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
14 display7SEG (1) ;
15

16 if ( time_flag == 1) {
17 time_flag = 0;
18 counter = 50;
19 seven_segment_status = SEVEN_SEGMENT_1 ;
20 }
21 break ;
22

23 case SEVEN_SEGMENT_1 :
24 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
25 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_RESET ) ;
26 display7SEG (2) ;
27

28 if ( time_flag == 1) {
29 time_flag = 0;
30 counter = 50;
31 seven_segment_status = SEVEN_SEGMENT_0 ;
32 }
33 break ;
34 }
35 /* USER CODE END WHILE */
36

37 /* USER CODE BEGIN 3 */


38 }
Program 1.5: Source code in while in main function

Short question: What is the frequency of the scanning process?

The frequency of the scanning process is 1Hz

3.2 Exercise 2

Extend to 4 seven segment LEDs and two LEDs (connected to PA4, labeled as DOT)
in the middle as following:
Blink the two LEDs every second. Meanwhile, number 3 is displayed on the third
seven segment and number 0 is displayed on the last one (to present 12 hour and
a half). The switching time for each seven segment LED is also a half of second
(500ms). Implement your code in the timer interrupt function.

Report 1: Capture your schematic from Proteus and show in the report.

Microcontroller Page 15
Hình 1.7 : Simulation schematic in Proteus

Hình 1.8: Schematic for exercise 2

Report 2: Present your source code in the HAL_TIM_PeriodElapsedCallback func-


tion.

1 int time_flag = 0;
2 int counter = 50;
3 int counter_dot = 50;
4 int time_flag_dot = 0;
5 /* USER CODE BEGIN 4 */
6 void HA L_ TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *
htim ) {
7 counter - -;
8 counter_dot - -;
9

10 if ( counter <= 0) {
11 time_flag = 1;
12 }
13

14 if ( counter_dot <= 0) {
15 time_flag_dot = 1;
16 }
17 }
Program 1.6: Source code in the HAL_TIM_PeriodElapsedCallback function

Page 16 HCMUT - Computer Engineering


1 enum SevenSegmentState { SEVEN_SEGMENT_0 = 0 ,
SEVEN_SEGMENT_1 = 1 , SEVEN_SEGMENT_2 = 2 ,
SEVEN_SEGMENT_3 = 3};
2 enum SevenSegmentState seven_segment_status =
SEVEN_SEGMENT_0 ;
3 enum DotState { OFF = 0 , ON = 1};
4 enum DotState dot_status = OFF ;
5 HAL_TIM_Base_Start_IT (& htim2 ) ;
6 /* USER CODE END 2 */
7

8 /* Infinite loop */
9 /* USER CODE BEGIN WHILE */
10 while (1)
11 {
12 switch ( seven_segment_status ) {
13 case SEVEN_SEGMENT_0 :
14 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_RESET ) ;
15 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
16 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
17 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
18 display7SEG (1) ;
19

20 if ( time_flag == 1) {
21 time_flag = 0;
22 counter = 50;
23 seven_segment_status = SEVEN_SEGMENT_1 ;
24 }
25 break ;
26

27 case SEVEN_SEGMENT_1 :
28 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
29 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_RESET ) ;
30 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
31 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
32 display7SEG (2) ;
33

34 if ( time_flag == 1) {
35 time_flag = 0;
36 counter = 50;
37 seven_segment_status = SEVEN_SEGMENT_2 ;
38 }

Microcontroller Page 17
39 break ;
40

41 case SEVEN_SEGMENT_2 :
42 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
43 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
44 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_RESET ) ;
45 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
46 display7SEG (3) ;
47

48 if ( time_flag == 1) {
49 time_flag = 0;
50 counter = 50;
51 seven_segment_status = SEVEN_SEGMENT_3 ;
52 }
53 break ;
54

55 case SEVEN_SEGMENT_3 :
56 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
57 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
58 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
59 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_RESET ) ;
60 display7SEG (0) ;
61

62 if ( time_flag == 1) {
63 time_flag = 0;
64 counter = 50;
65 seven_segment_status = SEVEN_SEGMENT_0 ;
66 }
67 break ;
68 }
69

70 switch ( dot_status ) {
71 case OFF :
72 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_SET ) ;
73

74 if ( time_flag_dot == 1) {
75 time_flag_dot = 0;
76 counter_dot = 50;
77 dot_status = ON ;
78 }

Page 18 HCMUT - Computer Engineering


79 break ;
80

81 case ON :
82 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_RESET ) ;
83

84 if ( time_flag_dot == 1) {
85 time_flag_dot = 0;
86 counter_dot = 50;
87 dot_status = OFF ;
88 }
89 break ;
90 }
91

92

93 /* USER CODE END WHILE */


94

95 /* USER CODE BEGIN 3 */


96 }
Program 1.7: Source code in while in main function

Short question: What is the frequency of the scanning process?

The frequency of the scanning process is 0.50Hz

3.3 Exercise 3

Implement a function named update7SEG(int index). An array of 4 integer num-


bers are declared in this case. The code skeleton in this exercise is presented as
following:

Microcontroller Page 19
1 const int MAX_LED = 4;
2 int index_led = 0;
3 int led_buffer [4] = {1 , 2 , 3 , 4};
4 void update7SEG ( int index ) {
5 switch ( index ) {
6 case 0:
7 // Display the first 7 SEG with led_buffer [0]
8 break ;
9 case 1:
10 // Display the second 7 SEG with led_buffer [1]
11 break ;
12 case 2:
13 // Display the third 7 SEG with led_buffer [2]
14 break ;
15 case 3:
16 // Display the forth 7 SEG with led_buffer [3]
17 break ;
18 default :
19 break ;
20 }
21 }
Program 1.8: An example for your source code

This function should be invoked in the timer interrupt, e.g update7SEG(index_led++).


The variable index_led is updated to stay in a valid range, which is from 0 to 3.

Report 1: Present the source code of the update7SEG function.

1 void update7SEG ( int index ) {


2 switch ( index ) {
3 case 0:
4 // Display the first 7 SEG with led_buffer [0]
5 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_RESET ) ;
6 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
7 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
8 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
9 display7SEG ( led_buffer [0]) ;
10 break ;
11 case 1:
12 // Display the second 7 SEG with led_buffer [1]
13 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
14 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_RESET ) ;

Page 20 HCMUT - Computer Engineering


15 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
16 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
17 display7SEG ( led_buffer [1]) ;
18

19 break ;
20 case 2:
21 // Display the third 7 SEG with led_buffer [2]
22 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
23 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
24 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_RESET ) ;
25 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
26 display7SEG ( led_buffer [2]) ;
27 break ;
28 case 3:
29 // Display the forth 7 SEG with led_buffer [3]
30 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
31 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
32 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
33 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_RESET ) ;
34 display7SEG ( led_buffer [3]) ;
35 break ;
36 default :
37 break ;
38 }
39 }
Program 1.9: Source code of the update7SEG function

Report 2: Present the source code in the HAL_TIM_PeriodElapsedCallback.

1 /* USER CODE BEGIN 4 */


2 int time_flag = 0;
3 int counter = 50;
4 int counter_dot = 50;
5 int time_flag_dot = 0;
6 void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *
htim ) {
7 counter - -;
8 counter_dot - -;
9

Microcontroller Page 21
10 if ( counter <= 0) {
11 time_flag = 1;
12 }
13

14 if ( counter_dot <= 0) {
15 time_flag_dot = 1;
16 }
17 }
Program 1.10: Source code in the HAL_TIM_PeriodElapsedCallback function

1 enum DotState { OFF = 0 , ON = 1};


2 enum DotState dot_status = OFF ;
3 HAL_TIM_Base_Start_IT (& htim2 ) ;
4 /* USER CODE END 2 */
5

6 /* Infinite loop */
7 /* USER CODE BEGIN WHILE */
8 while (1)
9 {
10 if ( time_flag == 1) {
11 update7SEG ( index_led ++) ;
12 time_flag = 0;
13 if ( index_led > 3) index_led = 0;
14 counter = 50;
15 }
16

17 switch ( dot_status ) {
18 case OFF :
19 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_SET ) ;
20

21 if ( time_flag_dot == 1) {
22 time_flag_dot = 0;
23 counter_dot = 50;
24 dot_status = ON ;
25 }
26 break ;
27

28 case ON :
29 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_RESET ) ;
30

31 if ( time_flag_dot == 1) {
32 time_flag_dot = 0;
33 counter_dot = 50;
34 dot_status = OFF ;
35 }
36 break ;
37 }

Page 22 HCMUT - Computer Engineering


38 /* USER CODE END WHILE */
39

40 /* USER CODE BEGIN 3 */


41 }
Program 1.11: Source code in while in main function

Students are proposed to change the values in the led_buffer array for unit test
this function, which is used afterward.

3.4 Exercise 4

Change the period of invoking update7SEG function in order to set the frequency
of 4 seven segment LEDs to 1Hz. The DOT is still blinking every second.

Report 1: Present the source code in the HAL_TIM_PeriodElapsedCallback.

1 int time_flag = 0;
2 int counter = 25;
3 int counter_dot = 50;
4 int time_flag_dot = 0;
5 void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *
htim ) {
6 counter - -;
7 counter_dot - -;
8

9 if ( counter <= 0) {
10 time_flag = 1;
11 }
12

13 if ( counter_dot <= 0) {
14 time_flag_dot = 1;
15 }
16 }
Program 1.12: Source code in the HAL_TIM_PeriodElapsedCallback function

3.5 Exercise 5

Implement a digital clock with hour and minute information displayed by 2 seven
segment LEDs. The code skeleton in the main function is presented as follows:
1 int hour = 15 , minute = 8 , second = 50;
2

3 while (1) {
4 second ++;
5 if ( second >= 60) {
6 second = 0;

Microcontroller Page 23
7 minute ++;
8 }
9 if ( minute >= 60) {
10 minute = 0;
11 hour ++;
12 }
13 if ( hour >=24) {
14 hour = 0;
15 }
16 updateClockBuffer () ;
17 HAL_Delay (1000) ;
18 }
Program 1.13: An example for your source code

The function updateClockBuffer will generate values for the array led_buffer ac-
cording to the values of hour and minute. In the case these values are 1 digit num-
ber, digit 0 is added.

Report 1: Present the source code in the updateClockBuffer function.


1 int led_buffer [4] = {1 , 2 , 3 , 4};
2 int hour = 15 , minute = 8 , second = 50;
3 void updateClockBuffer () {
4 // led_buffer [4] = {1 , 2 , 3 , 4};
5 led_buffer [0] = hour / 10;
6 led_buffer [1] = hour % 10;
7 led_buffer [2] = minute / 10;
8 led_buffer [3] = minute % 10;
9 }
Program 1.14: Source code in the updateClockBuffer function

3.6 Exercise 6

The main target from this exercise to reduce the complexity (or reduce code pro-
cessing) in the timer interrupt. The time consumed in the interrupt can lead to the
nested interrupt issue, which can crash the whole system. A simple solution can
disable the timer whenever the interrupt occurs, the enable it again. However, the
real-time processing is not guaranteed anymore.

In this exercise, a software timer is created and its counter is count down every
timer interrupt is raised (every 10ms). By using this timer, the Hal_Delay(1000)
in the main function is removed. In a MCU system, non-blocking delay is better
than blocking delay. The details to create a software timer are presented bellow.
The source code is added to your current program, do not delete the source code
you have on Exercise 5.

Step 1: Declare variables and functions for a software timer, as following:

Page 24 HCMUT - Computer Engineering


1 /* USER CODE BEGIN 0 */
2 int timer0_counter = 0;
3 int timer0_flag = 0;
4 int TIMER_CYCLE = 10;
5 void setTimer0 ( int duration ) {
6 timer0_counter = duration / TIMER_CYCLE ;
7 timer0_flag = 0;
8 }
9 void timer_run () {
10 if ( timer0_counter > 0) {
11 timer0_counter - -;
12 if ( timer0_counter == 0) timer0_flag = 1;
13 }
14 }
15 /* USER CODE END 0 */
Program 1.15: Software timer based timer interrupt

Please change the TIMER_CYCLE to your timer interrupt period. In the manual
code above, it is 10ms.

Step 2: The timer_run() is invoked in the timer interrupt as following:


1 void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef * htim )
{
2

3 timer_run () ;
4

5 // YOUR OTHER CODE


6 }
Program 1.16: Software timer based timer interrupt

Step 3: Use the timer in the main function by invoked setTimer0 function, then
check for its flag (timer0_flag). An example to blink an LED connected to PA5 using
software timer is shown as follows:
1 setTimer0 (1000) ;
2 while (1) {
3 if ( timer0_flag == 1) {
4 HAL_GPIO_TogglePin ( LED_RED_GPIO_Port , LED_RED_Pin ) ;
5 setTimer0 (2000) ;
6 }
7 }
Program 1.17: Software timer is used in main fuction to blink the LED

Report 1: if in line 1 of the code above is miss, what happens after that and why?

If in line 1 of the code above is miss, the code in if (timer0_flag == 1) will be exe-
cuted immediately. Because when timer interrupt is raised, it set timer0_flag = 1
immediately as timer0_counter = 0.

Microcontroller Page 25
Report 2: if in line 1 of the code above is changed to setTimer0(1), what happens
after that and why?

If in line 1 of the code above is changed to setTimer0(1), the code in if (timer0_flag


== 1) will be executed immediately. Because when timer interrupt is raised, it set
timer0_flag = 1 immediately as timer0_counter = 0. The setTimer0 function before
while calculate timer0_counter = duration / TIMER_CYCLE = 0.
Report 3: if in line 1 of the code above is changed to setTimer0(10), what is changed
compared to 2 first questions and why?

If in line 1 of the code above is changed to setTimer0(10), the code in if (timer0_flag


== 1) will be executed after 10ms. Because when timer interrupt is raised, it change
timer0_counter from 1 to 0 and after that set timer0_flag = 1. The setTimer0 func-
tion before while calculate timer0_counter = duration / TIMER_CYCLE = 1.

3.7 Exercise 7

Upgrade the source code in Exercise 5 (update values for hour, minute and sec-
ond) by using the software timer and remove the HAL_Delay function at the end.
Moreover, the DOT (connected to PA4) of the digital clock is also moved to main
function.

Report 1: Present your source code in the while loop on main function.
1 while (1)
2 {
3

4 if ( time_flag == 1) {
5 updateClockBuffer () ;
6 update7SEG ( index_led ++) ;
7 if ( index_led > 3) index_led = 0;
8 setTimer (250) ;
9

10 }
11

12 if ( time_flag_clock == 1) {
13 second ++;
14 if ( second >= 60) {
15 second = 0;
16 minute ++;
17 }
18 if ( minute >= 60) {
19 minute = 0;
20 hour ++;
21 }
22 if ( hour >=24) {
23 hour = 0;

Page 26 HCMUT - Computer Engineering


24 }
25 updateClockBuffer () ;
26 setTimerClock (1000) ;
27 }
28

29 switch ( dot_status ) {
30 case OFF :
31 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_SET ) ;
32

33 if ( time_flag_dot == 1) {
34 setTimerDot (500) ;
35 dot_status = ON ;
36 }
37 break ;
38

39 case ON :
40 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_RESET ) ;
41

42 if ( time_flag_dot == 1) {
43 setTimerDot (500) ;
44 dot_status = OFF ;
45 }
46 break ;
47 }
48

49 /* USER CODE END WHILE */


50

51 /* USER CODE BEGIN 3 */


52 }
Program 1.18: Source code in while in main function

1 int time_flag = 0;
2 int counter = 25;
3 int counter_dot = 50;
4 int counter_clock = 100;
5 int time_flag_dot = 0;
6 int time_flag_clock = 100;
7

8 const int MAX_LED = 4;


9 int index_led = 0;
10 int led_buffer [4] = {1 , 5 , 0 , 8};
11 int hour = 15 , minute = 8 , second = 50;
12 int TIMER_CYCLE = 10;
13

14 void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *


htim ) {
15 TimerRun () ;

Microcontroller Page 27
16 TimerRunDot () ;
17 TimerRunClock () ;
18 }
19

20 void update7SEG ( int index ) {


21 switch ( index ) {
22 case 0:
23 // Display the first 7 SEG with led_buffer [0]
24 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_RESET ) ;
25 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
26 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
27 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
28 display7SEG ( led_buffer [0]) ;
29 break ;
30 case 1:
31 // Display the second 7 SEG with led_buffer [1]
32 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
33 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_RESET ) ;
34 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
35 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
36 display7SEG ( led_buffer [1]) ;
37

38 break ;
39 case 2:
40 // Display the third 7 SEG with led_buffer [2]
41 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
42 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
43 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_RESET ) ;
44 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
45 display7SEG ( led_buffer [2]) ;
46 break ;
47 case 3:
48 // Display the forth 7 SEG with led_buffer [3]
49 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
50 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;

Page 28 HCMUT - Computer Engineering


51 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
52 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_RESET ) ;
53 display7SEG ( led_buffer [3]) ;
54 break ;
55 default :
56 break ;
57 }
58 }
59

60 void display7SEG ( int num ) {


61 /*
62 * list display number to display in bit
63 * 0 = > 0 b1000000 = > 0 x40
64 * 1 = > 0 b1111001 = > 0 x79
65 * 2 = > 0 b0100100 = > 0 x24
66 * 3 = > 0 b0110000 = > 0 x30
67 * 4 = > 0 b0011001 = > 0 x19
68 * 5 = > 0 b0010010 = > 0 x12
69 * 6 = > 0 b0000010 = > 0 x02
70 * 7 = > 0 b1111000 = > 0 x78
71 * 8 = > 0 b0000000 = > 0 x00
72 * 9 = > 0 b0010000 = > 0 x10
73 */
74 int number_in_bit [10] ={0 x40 , 0 x79 , 0 x24 , 0 x30 , 0 x19 , 0
x12 , 0 x02 , 0 x78 , 0 x00 , 0 x10 };
75 // write to ODR register to change sate all pin in port B
76 GPIOB - > ODR = number_in_bit [ num ];
77 }
78

79 void updateClockBuffer () {
80 // led_buffer [4] = {1 , 2 , 3 , 4};
81 led_buffer [0] = hour / 10;
82 led_buffer [1] = hour % 10;
83 led_buffer [2] = minute / 10;
84 led_buffer [3] = minute % 10;
85 }
86

87 void setTimer ( int duration ) {


88 counter = duration / TIMER_CYCLE ;
89 time_flag = 0;
90 }
91 void TimerRun () {
92 if ( counter > 0) counter - -;
93 if ( counter <= 0) {
94 time_flag = 1;
95 }
96 }

Microcontroller Page 29
97

98 void setTimerDot ( int duration ) {


99 counter_dot = duration / TIMER_CYCLE ;
100 time_flag_dot = 0;
101 }
102 void TimerRunDot () {
103 if ( counter_dot > 0) counter_dot - -;
104 if ( counter_dot <= 0) {
105 time_flag_dot = 1;
106 }
107 }
108

109 void setTimerClock ( int duration ) {


110 counter_clock = duration / TIMER_CYCLE ;
111 time_flag_clock = 0;
112 }
113 void TimerRunClock () {
114 if ( counter_clock > 0) counter_clock - -;
115 if ( counter_clock <= 0) {
116 time_flag_clock = 1;
117 }
118 }
119 /* USER CODE END 4 */
Program 1.19: Source code in other functions

3.8 Exercise 8

Move also the update7SEG() function from the interrupt timer to the main. Finally,
the timer interrupt only used to handle software timers. All processing (or complex
computations) is move to an infinite loop on the main function, optimizing the
complexity of the interrupt handler function.

Report 1: Present your source code in the the main function. In the case more extra
functions are used (e.g. the second software timer), present them in the report as
well.
1 while (1)
2 {
3

4 if ( time_flag == 1) {
5 updateClockBuffer () ;
6 update7SEG ( index_led ++) ;
7 if ( index_led > 3) index_led = 0;
8 setTimer (250) ;
9

10 }
11

12 if ( time_flag_clock == 1) {

Page 30 HCMUT - Computer Engineering


13 second ++;
14 if ( second >= 60) {
15 second = 0;
16 minute ++;
17 }
18 if ( minute >= 60) {
19 minute = 0;
20 hour ++;
21 }
22 if ( hour >=24) {
23 hour = 0;
24 }
25 updateClockBuffer () ;
26 setTimerClock (1000) ;
27 }
28

29 switch ( dot_status ) {
30 case OFF :
31 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_SET ) ;
32

33 if ( time_flag_dot == 1) {
34 setTimerDot (500) ;
35 dot_status = ON ;
36 }
37 break ;
38

39 case ON :
40 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_RESET ) ;
41

42 if ( time_flag_dot == 1) {
43 setTimerDot (500) ;
44 dot_status = OFF ;
45 }
46 break ;
47 }
48

49 /* USER CODE END WHILE */


50

51 /* USER CODE BEGIN 3 */


52 }
Program 1.20: Source code in while in main function

1 int time_flag = 0;
2 int counter = 25;
3 int counter_dot = 50;
4 int counter_clock = 100;
5 int time_flag_dot = 0;

Microcontroller Page 31
6 int time_flag_clock = 100;
7

8 const int MAX_LED = 4;


9 int index_led = 0;
10 int led_buffer [4] = {1 , 5 , 0 , 8};
11 int hour = 15 , minute = 8 , second = 50;
12 int TIMER_CYCLE = 10;
13

14 void HA L_ TIM_PeriodElapsedCallback ( TIM_HandleTypeDef *


htim ) {
15 TimerRun () ;
16 TimerRunDot () ;
17 TimerRunClock () ;
18 }
19

20 void update7SEG ( int index ) {


21 switch ( index ) {
22 case 0:
23 // Display the first 7 SEG with led_buffer [0]
24 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_RESET ) ;
25 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
26 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
27 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
28 display7SEG ( led_buffer [0]) ;
29 break ;
30 case 1:
31 // Display the second 7 SEG with led_buffer [1]
32 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
33 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_RESET ) ;
34 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
35 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
36 display7SEG ( led_buffer [1]) ;
37

38 break ;
39 case 2:
40 // Display the third 7 SEG with led_buffer [2]
41 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
42 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
43 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,

Page 32 HCMUT - Computer Engineering


GPIO_PIN_RESET ) ;
44 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_SET ) ;
45 display7SEG ( led_buffer [2]) ;
46 break ;
47 case 3:
48 // Display the forth 7 SEG with led_buffer [3]
49 HAL_GPIO_WritePin ( EN0_GPIO_Port , EN0_Pin ,
GPIO_PIN_SET ) ;
50 HAL_GPIO_WritePin ( EN1_GPIO_Port , EN1_Pin ,
GPIO_PIN_SET ) ;
51 HAL_GPIO_WritePin ( EN2_GPIO_Port , EN2_Pin ,
GPIO_PIN_SET ) ;
52 HAL_GPIO_WritePin ( EN3_GPIO_Port , EN3_Pin ,
GPIO_PIN_RESET ) ;
53 display7SEG ( led_buffer [3]) ;
54 break ;
55 default :
56 break ;
57 }
58 }
59

60 void display7SEG ( int num ) {


61 /*
62 * list display number to display in bit
63 * 0 = > 0 b1000000 = > 0 x40
64 * 1 = > 0 b1111001 = > 0 x79
65 * 2 = > 0 b0100100 = > 0 x24
66 * 3 = > 0 b0110000 = > 0 x30
67 * 4 = > 0 b0011001 = > 0 x19
68 * 5 = > 0 b0010010 = > 0 x12
69 * 6 = > 0 b0000010 = > 0 x02
70 * 7 = > 0 b1111000 = > 0 x78
71 * 8 = > 0 b0000000 = > 0 x00
72 * 9 = > 0 b0010000 = > 0 x10
73 */
74 int number_in_bit [10] ={0 x40 , 0 x79 , 0 x24 , 0 x30 , 0 x19 , 0
x12 , 0 x02 , 0 x78 , 0 x00 , 0 x10 };
75 // write to ODR register to change sate all pin in port
B
76 GPIOB - > ODR = number_in_bit [ num ];
77 }
78

79 void updateClockBuffer () {
80 // led_buffer [4] = {1 , 2 , 3 , 4};
81 led_buffer [0] = hour / 10;
82 led_buffer [1] = hour % 10;
83 led_buffer [2] = minute / 10;
84 led_buffer [3] = minute % 10;

Microcontroller Page 33
85 }
86

87 void setTimer ( int duration ) {


88 counter = duration / TIMER_CYCLE ;
89 time_flag = 0;
90 }
91 void TimerRun () {
92 if ( counter > 0) counter - -;
93 if ( counter <= 0) {
94 time_flag = 1;
95 }
96 }
97

98 void setTimerDot ( int duration ) {


99 counter_dot = duration / TIMER_CYCLE ;
100 time_flag_dot = 0;
101 }
102 void TimerRunDot () {
103 if ( counter_dot > 0) counter_dot - -;
104 if ( counter_dot <= 0) {
105 time_flag_dot = 1;
106 }
107 }
108

109 void setTimerClock ( int duration ) {


110 counter_clock = duration / TIMER_CYCLE ;
111 time_flag_clock = 0;
112 }
113 void TimerRunClock () {
114 if ( counter_clock > 0) counter_clock - -;
115 if ( counter_clock <= 0) {
116 time_flag_clock = 1;
117 }
118 }
119 /* USER CODE END 4 */
Program 1.21: Source code in other functions

3.9 Exercise 9

This is an extra works for this lab. A LED Matrix is added to the system. A reference
design is shown in figure bellow:
In this schematic, two new components are added, including the MATRIX-8X8-
RED and ULN2803, which is an NPN transistor array to enable the power supply
for a column of the LED matrix. Students can change the enable signal (from ENM0
to ENM7) if needed. Finally, the data signal (from ROW0 to ROW7) is connected to
PB8 to PB15.

Page 34 HCMUT - Computer Engineering


Hình 1.9: LED matrix is added to the simulation

Report 1: Present the schematic of your system by capturing the screen in Proteus.

Hình 1.10: Schematic for exercise 09

Report 2: Implement the function, updateLEDMatrix(int index), which is similarly


to 4 seven led segments.
1 const int MAX_LED_MATRIX = 8;
2 int index_led_matrix = 0;
3 uint8_t matrix_buffer [8] = {0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x05 , 0
x06 , 0 x07 , 0 x08 };
4 void updateLEDMatrix ( int index ) {
5 switch ( index ) {
6 case 0:
7 break ;
8 case 1:
9 break ;
10 case 2:
11 break ;
12 case 3:
13 break ;
14 case 4:
15 break ;
16 case 5:

Microcontroller Page 35
17 break ;
18 case 6:
19 break ;
20 case 7:
21 break ;
22 default :
23 break ;
24 }
25 }
Program 1.22: Function to display data on LED Matrix

Student are free to choose the invoking frequency of this function. However, this
function is supposed to invoked in main function. Finally, please update the ma-
trix_buffer to display character "A".
1 uint8_t matrix_buffer [8] = {0 xFF , 0 x03 , 0 x01 , 0 xCC , 0 xCC , 0
x01 , 0 x03 , 0 xFF };
2 void updateLedMatrix ( int index ) {
3

4 switch ( index ) {
5 case 0:
6 // Display the first 7 SEG with led_buffer [0]
7 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_RESET ) ;
8 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
9 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
10 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
11 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
12 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
13 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
14 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
15 displayMatrix (0) ;
16 break ;
17 case 1:
18 // Display the first 7 SEG with led_buffer [0]
19 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
20 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_RESET ) ;
21 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
22 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;

Page 36 HCMUT - Computer Engineering


23 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
24 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
25 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
26 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
27 displayMatrix (1) ;
28 break ;
29 case 2:
30 // Display the first 7 SEG with led_buffer [0]
31 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
32 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
33 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_RESET ) ;
34 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
35 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
36 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
37 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
38 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
39 displayMatrix (2) ;
40 break ;
41 case 3:
42 // Display the first 7 SEG with led_buffer [0]
43 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
44 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
45 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
46 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_RESET ) ;
47 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
48 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
49 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
50 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
51 displayMatrix (3) ;

Microcontroller Page 37
52 break ;
53 case 4:
54 // Display the first 7 SEG with led_buffer [0]
55 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
56 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
57 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
58 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
59 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_RESET ) ;
60 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
61 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
62 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
63 displayMatrix (4) ;
64 break ;
65 case 5:
66 // Display the first 7 SEG with led_buffer [0]
67 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
68 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
69 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
70 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
71 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
72 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_RESET ) ;
73 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
74 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
75 displayMatrix (5) ;
76 break ;
77 case 6:
78 // Display the first 7 SEG with led_buffer [0]
79 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
80 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
81 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;

Page 38 HCMUT - Computer Engineering


82 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
83 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
84 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
85 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_RESET ) ;
86 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_SET ) ;
87 displayMatrix (6) ;
88 break ;
89 case 7:
90 // Display the first 7 SEG with led_buffer [0]
91 HAL_GPIO_WritePin ( ENM0_GPIO_Port , ENM0_Pin ,
GPIO_PIN_SET ) ;
92 HAL_GPIO_WritePin ( ENM1_GPIO_Port , ENM1_Pin ,
GPIO_PIN_SET ) ;
93 HAL_GPIO_WritePin ( ENM2_GPIO_Port , ENM2_Pin ,
GPIO_PIN_SET ) ;
94 HAL_GPIO_WritePin ( ENM3_GPIO_Port , ENM3_Pin ,
GPIO_PIN_SET ) ;
95 HAL_GPIO_WritePin ( ENM4_GPIO_Port , ENM4_Pin ,
GPIO_PIN_SET ) ;
96 HAL_GPIO_WritePin ( ENM5_GPIO_Port , ENM5_Pin ,
GPIO_PIN_SET ) ;
97 HAL_GPIO_WritePin ( ENM6_GPIO_Port , ENM6_Pin ,
GPIO_PIN_SET ) ;
98 HAL_GPIO_WritePin ( ENM7_GPIO_Port , ENM7_Pin ,
GPIO_PIN_RESET ) ;
99 displayMatrix (7) ;
100 break ;
101 default :
102 break ;
103 }
104 }
Program 1.23: Source code in updateLEDMatrix function

2 void displayMatrix ( int num ) {


3 /*
4 * list display column to display in bit
5 * 0 = > 0 b11111111 = > 0 xFF
6 * 1 = > 0 b00000011 = > 0 x03
7 * 2 = > 0 b00000001 = > 0 x01
8 * 3 = > 0 b11001100 = > 0 xCC
9 * 4 = > 0 b11001100 = > 0 xCC
10 * 5 = > 0 b00000001 = > 0 x01
11 * 6 = > 0 b00000011 = > 0 x03

Microcontroller Page 39
12 * 7 = > 0 b11111111 = > 0 xFF
13

14 */
15 uint16_t upper_pin = GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
GPIO_PIN_14 | GPIO_PIN_15 ;
16 uint16_t upper_bit = matrix_buffer [ num ] << 8;
17 uint16_t lower_bit = GPIOB - > ODR & ~( upper_pin ) ;
18

19 // write to ODR register to change sate all pin in port


B
20 GPIOB - > ODR = lower_bit | upper_bit ;
21 }
Program 1.24: Source code in displayMatrix function

1 setTimer (250) ;
2 setTimerClock (1000) ;
3 setTimerDot (500) ;
4 setTimerLedMatrix (5) ;
5 /* USER CODE END 2 */
6

7 /* Infinite loop */
8 /* USER CODE BEGIN WHILE */
9 while (1)
10 {
11

12 if ( time_flag == 1) {
13 updateClockBuffer () ;
14 update7SEG ( index_led ++) ;
15 if ( index_led > 3) index_led = 0;
16 setTimer (250) ;
17

18 }
19

20 if ( time_flag_clock == 1) {
21 second ++;
22 if ( second >= 60) {
23 second = 0;
24 minute ++;
25 }
26 if ( minute >= 60) {
27 minute = 0;
28 hour ++;
29 }
30 if ( hour >=24) {
31 hour = 0;
32 }
33 updateClockBuffer () ;
34 setTimerClock (1000) ;

Page 40 HCMUT - Computer Engineering


35 }
36

37

38

39 switch ( dot_status ) {
40 case OFF :
41 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_SET ) ;
42

43 if ( time_flag_dot == 1) {
44 setTimerDot (500) ;
45 dot_status = ON ;
46 }
47 break ;
48

49 case ON :
50 HAL_GPIO_WritePin ( DOT_GPIO_Port , DOT_Pin ,
GPIO_PIN_RESET ) ;
51

52 if ( time_flag_dot == 1) {
53 setTimerDot (500) ;
54 dot_status = OFF ;
55 }
56 break ;
57 }
58

59

60 if ( time_flag_led_matrix == 1) {
61 updateLedMatrix ( index_led_matrix ++) ;
62 if ( index_led_matrix > 7) index_led_matrix = 0;
63 setTimerLedMatrix (5) ;
64 }
65

66 /* USER CODE END WHILE */


67

68 /* USER CODE BEGIN 3 */


69 }
Program 1.25: Source code in while in main fucntion

3.10 Exercise 10

Create an animation on LED matrix, for example, the character is shifted to the
left.
Report 1: Briefly describe your solution and present your source code in the re-
port.

Microcontroller Page 41
3.11 Link Github

https://github.com/minhgiang1234/lab2-vxl

Page 42 HCMUT - Computer Engineering

You might also like