Lab 2
Lab 2
Le Trong Nhan
Mục lục
Microcontroller Page 5
Page 6 HCMUT - Computer Engineering
CHƯƠNG 1
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.
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-
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.
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:
• 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:
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
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
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:
• 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.
6 /* Infinite loop */
7 /* USER CODE BEGIN WHILE */
8 while (1)
9 {
10 switch ( seven_segment_status ) {
11 case SEVEN_SEGMENT_0 :
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
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
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
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 }
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
3.3 Exercise 3
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
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
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
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 }
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.
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.
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.
Please change the TIMER_CYCLE to your timer interrupt period. In the manual
code above, it is 10ms.
3 timer_run () ;
4
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?
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;
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
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
Microcontroller Page 27
16 TimerRunDot () ;
17 TimerRunClock () ;
18 }
19
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 ) ;
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
Microcontroller Page 29
97
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) {
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
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
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 ,
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
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.
Report 1: Present the schematic of your system by capturing the screen in Proteus.
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 ) ;
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 ) ;
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
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) ;
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
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