Skip to content

Commit 9c8f1cb

Browse files
committed
Update of Tutorial 2
Basically Add thing in all .md
1 parent 46fef3a commit 9c8f1cb

File tree

6 files changed

+209
-46
lines changed

6 files changed

+209
-46
lines changed

tutorial-2-basic-io/02-GPIO.md

+25
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,31 @@ uint8_t btn1_state = !gpio_read(BTN1);
118118

119119
If one day your hardware groupmate accidentally swapped the wires of all LEDs, you can simply change the defines above. You don't need to read through your hundreds/thousands of lines of code and change every `gpio_set()` `gpio_reset()` and `gpio_read()` you wrote.
120120

121+
### Demo 1: Basic GPIO
122+
Before we start coding, please go to `main.h` and edit the line 133:\
123+
Change from `#define btn_read(btn) gpio_read(btn)` \
124+
To `#define btn_read(btn) !gpio_read(btn)`
125+
126+
127+
For example I would like to turn on the `LED2` when I press `BTN2`, what I can do would be :
128+
```c
129+
/*main.c*/
130+
while(1){
131+
if btn_read(BTN2){
132+
led_on(LED2);
133+
}
134+
else {
135+
led_off(LED2);
136+
}
137+
}
138+
```
139+
After you edit your code and you are waiting the board from your peers, you can first compile your code to see if there is any copilation error:\
140+
You can press the "Hammer" on the top bar of the interface
141+
![](./image/Compiler_hammer.png)
142+
And then your code will be compiled and you can check if there is any problem.
143+
144+
---
145+
121146
### Further Application: Pneumatic Valve
122147

123148
Another application you more likely to use for GPIO is pneumatic valves.

tutorial-2-basic-io/03-HAL-Clock.md

+84-17
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ uint32_t ticks = HAL_GetTick();
1515
```
1616
1717
- In STM32, the MCU has introduced an application time base that increments every 1 ms. Using `HAL_GetTick()` returns the time base (in ms) since the mainboard was powered on.
18-
- You can think of the MCU as holding a stopwatch that starts when the MCU begins running, and `HAL_GetTick()` provides the current reading of this stopwatch.
18+
- You can think of the MCU as holding a stopwatch that starts when the MCU begins running, and `HAL_GetTick()` is ask the stopwatch what is the counting right now
1919
2020
```c
2121
void HAL_Delay(uint32_t Delay);
@@ -41,7 +41,7 @@ void HAL_Delay(uint32_t Delay);
4141
}
4242
```
4343
44-
- A LED turn on 100ms after u press the button:
44+
- A LED turn on 100ms after u first time press the `BTN1`:
4545
```c
4646
while (1) {
4747
static uint32_t last_ticks = 0;
@@ -50,13 +50,85 @@ void HAL_Delay(uint32_t Delay);
5050
BTN_Pressed = 1;
5151
last_ticks = HAL_GetTick();
5252
}
53-
if(BTN_Pressed && (HAL_GetTick() - last_ticks) >= 100){
53+
if(BTN_Pressed && (HAL_GetTick() - last_ticks) <= 100){
5454
led_on(LED1);
5555
}
56+
else if(BTN_Pressed){
57+
led_off(LED1);
58+
}
5659
}
57-
```
58-
59-
## Action that constantly repeat
60+
```
61+
62+
### Demo 2: Writing Code in a function
63+
While you might only need to write tens of code to finish different classwork and homework, in real life you would write thousands line of code , and so it is important for you to write your code in different functions.
64+
65+
In today tutorial, you should put all your code in the four function we give to you in `tutorial2_hw.c`, here I would provide you an example of how it works
66+
67+
1. Write what you want it to do every loop:
68+
- Assume the task is Flashing the `LED3` (toggle every 100ms) for 1 seconds after the `BTN2` is pressed
69+
```c
70+
/* tutorial2_hw.c*/
71+
void gpio_classwork(void) {
72+
/* Your code start here */
73+
// You should use static uint32_t here, as any variable that defined in main.c cannot call here unless you extern it
74+
static uint32_t last_ticks_btn = 0;
75+
static uint32_t last_ticks_led = 0;
76+
if (HAL_GetTick() - last_ticks_btn > 1000){
77+
// Current Cycle of Acttion that BTN1 is ended
78+
led_off(LED3)
79+
if (btn_read(BTN2)){
80+
last_ticks_btn = HAL_GetTick();
81+
}
82+
}
83+
else {
84+
// Inside the Flashing Cycle
85+
if (HAL_GetTick() - last_ticks_led > 100){
86+
led_toggle(LED3);
87+
last_ticks_led = HAL_GetTick();
88+
}
89+
}
90+
/* Your code end here */
91+
}
92+
```
93+
94+
2. After you have written your program in `tutorial2_hw.c`, you would like to call it in your main loop.
95+
- Before calling it, you need to have declared this function before the `main` function.
96+
- Normally we will do by include a corrsponding `.h` of that `.c`, but as we forogr to give you this.
97+
- So you can directly put the function prototype (function declaration) in the top of your `main.c`
98+
```c
99+
/* main.c */
100+
/* USER CODE BEGIN PFP */
101+
void gpio_classwork(void);
102+
/* USER CODE END PFP */
103+
```
104+
3. After you have done all these, you can directly call the function in your `main.c`:
105+
```c
106+
/* main.c::int main() */
107+
108+
/* USER CODE BEGIN WHILE */
109+
while(1){
110+
gpio_classwork();
111+
/* USER CODE END WHILE */
112+
113+
/* USER CODE BEGIN 3 */
114+
}
115+
/* USER CODE END 3 */
116+
```
117+
> Some of you may apply another `while` loop in your function for this purpose:
118+
> ```c
119+
> if (btn_read(BTN2)){
120+
> static uint32_t last_ticks_BTN = 0;
121+
> last_ticks_BTN = HAL_GetTick();
122+
> while (HAL_GetTick - last_ticks_BTN < 1000){
123+
> //Code for Toggle LED
124+
> }
125+
> }
126+
> ```
127+
> While the solution work fine under this single task context, it will create problem in a lot of way, consider this, your robot may have a lot of things to do at the same time, for example, Flashing LED and also control the pnematic valve at the same time. Using this code, you **cannot do anything** when you flashing the LED for 1 second, which is not perferable. \
128+
> This also the reason we tell you guys to never use `HAL_Delay()`
129+
130+
131+
<!-- ## Action that constantly repeat
60132
61133
### Program Structure:
62134
@@ -89,9 +161,9 @@ int main(void)
89161
```
90162

91163
- In the example above, we do something every 100 ms and another thing every 60 ms. Since they are only an if-statement, there won't be any while loops/ for loops that prevent the other tasks from doing their tasks.
92-
- This structure is easy and keep your MCU active all the time to do whatever you want it to do.
164+
- This structure is easy and keep your MCU active all the time to do whatever you want it to do. -->
93165

94-
### HAL_Delay
166+
<!-- ### HAL_Delay
95167
96168
Some of you may find that a `HAL_Delay()` function exists, and use it in your code like so:
97169
@@ -133,18 +205,13 @@ while((HAL_GetTick() - tickstart) < wait)
133205
}
134206
135207
````
136-
</details>
208+
</details> -->
137209

138210
## Classwork 1: GPIO and HAL
139211
To make our code more readable and make things more organized, we have provided separate functions for you to work in.
140-
You should write your code there in the respective functions and call the functions in the `main.c` \
141-
Remember to add the function prototype before you call it.
142-
```c
143-
/* tutorial2_hw.c */
144-
/* USER CODE BEGIN PFP */
145-
void gpio_classwork(void);
146-
/* USER CODE END PFP */
147-
````
212+
You should write your code there in the respective functions and call the functions in the `main.c`
213+
214+
> As we have included the function prototype of the `gpio_classwork()` in the previous demo, you don't need do that for this classwork.
148215
149216
- When `BTN1` is held, `LED1` should be on. **(@1)**
150217
- When `BTN2` is held, `LED1` should be flashing (toggle in 50ms).**(@1)**

tutorial-2-basic-io/04-TFT.md

+24-11
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ You may choose one of the following colours according to your own desire for the
8989
### **Example:**
9090

9191
```c
92+
void tft_init(TFT_ORIENTATION orientation, uint16_t bg_color, uint16_t text_color, uint16_t text_color_sp, uint16_t highlight_color);
9293
/*
9394
* Initialisation Example
9495
*
@@ -172,17 +173,29 @@ while(1){
172173
## Classwork 2: TFT
173174

174175
- Print the time elapsed with the format of `mm:ss:sssZ` where `sssZ` means millisecond. e.g. `00:23:109` **(@2)**
175-
- Print a 50px \* 50px square directly under the elapsed time where its color changes when 1 second passed.**(@2)**
176-
> Remember to add the function prototype before you call it.
177-
>
178-
> ```c
179-
> /* main.c */
180-
> /* USER CODE BEGIN PFP */
181-
> void tft_classwork(void);
182-
> /* USER CODE END PFP */
183-
> ```
184-
>
185-
> Hints: Making use of mod and integer division.
176+
- Toogle the highlight of the text you print every seconds, which means: **(@2)**
177+
- 1st second: print normal text
178+
- 2nd second: print hightlighted text
179+
- Recall1:
180+
```c
181+
tft_prints(0, 2, "{Hello World}");
182+
// This is a higlighted text
183+
```
184+
- Recall2: We define the colour of hightlight in `tft_init`:
185+
```c
186+
void tft_init(TFT_ORIENTATION orientation, uint16_t bg_color, uint16_t text_color, uint16_t text_color_sp, uint16_t highlight_color);
187+
```
188+
- 3rd second: print normal text
189+
> Remember to add the function prototype before you call it.
190+
>
191+
> ```c
192+
> /* main.c */
193+
> /* USER CODE BEGIN PFP */
194+
> void tft_classwork(void);
195+
> /* USER CODE END PFP */
196+
> ```
197+
>
198+
> Hints: Making use of mod and integer division.
186199
187200
---
188201

tutorial-2-basic-io/05-Setting-up-GPIO-Pin.md

+51-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
# Basic STM32 Configuration
44

5+
> Please be **noted** that we are domostrating how to set up a new
6+
GPIO **OUTPUT** pins for air cylinder, for your homework, you are working on a limit switch / Line Following sensors, that's is a **INOUT**, so the set up would be differ.
7+
58
Throughout your RDC journey, you will not need to configure all pinouts and function modules from scratch due to the many technical considerations involved. We have already provided you with a mostly completed configuration file called "SW Tutorial," which includes commonly used functionalities such as CAN, LED, TFT, and PWM.
69
However, you may still need to utilize some GPIO pins, and we cannot predict what and where you will connect to the board. Therefore, we will introduce some basic skills for setting up GPIO pins.
710

@@ -33,14 +36,58 @@ When you click the `.ioc` file, you will enter an interface similar to this:
3336
![](./image/PC0_Config.png)
3437
- Inside this configuration window, you can choose different settings for the GPIO pin. Ideally, you should not need to change anything from the default configuration for a `GPIO Output` pin.
3538
- You can (and should) also rename the pin with a meaningful name. As mentioned in `02-GPIO.md`, CubeMX will generate the appropriate macro based on the name you enter, so you should rename it here instead of manually writing a macro.
36-
4. **Save your configuration and Generate Code**: As mentioned, you need to save and generate code before you can make your change effective. In CubeMX under CubeIDE, you just need to save your change by click `Ctrl + S` ~~(mac ppl help yourself)~~ and click **YES** in the following Pop-up Windows.
39+
4. **Save your configuration and Generate Code**:\
40+
As mentioned, you need to save and generate code before you can make your change effective. In CubeMX under CubeIDE, you just need to save your change by click `Ctrl + S` ~~(mac ppl help yourself)~~ and click **YES** in the following Pop-up Windows.
3741
![](./image/Generate_Code.png)
42+
5. **Bug Fixing**:
43+
- Comment the `MX_SPI_Init()` in `main.c`, due to some compilated reason, we have init the SPI in `tft_init()` and so double init may possibiy lead to some issue, therefore please help yourself and comment out this line:
44+
```c
45+
/* main.c */
46+
/* Initialize all configured peripherals */
47+
MX_GPIO_Init();
48+
MX_DMA_Init();
49+
MX_CAN2_Init();
50+
// MX_SPI1_Init(); //Help us Comment out this line
51+
MX_USART1_UART_Init();
52+
MX_I2C2_Init();
53+
MX_CAN1_Init();
54+
MX_USART2_UART_Init();
55+
MX_TIM5_Init();
56+
```
57+
- As the `tft_update()` is accidently put outside the designed zone for some destribution, your `tft_update()`, Please add the `tft_update(1)` in your main `while` loop if you don't find it there
58+
59+
## How to use the pins
60+
61+
After you generate the code, STM CubeIDE suppose will lead you back to the `main.c` or may be some other `.c` / `.h` files, if you want to check whther your code is generated correctly, you can do this:
62+
63+
Go to your `main.h`, you shoould able to find this:
64+
```c
65+
#define {the pin name you put}_Pin GPIO_Pin_{the pin number}
66+
#define {the pin name you put}_GPIO_Port GPIO{The Pin Group}
67+
```
68+
For example I name my new pins as `Valve`, then in my `main.h` I find this:
69+
```c
70+
#define Valve_Pin GPIO_PIN_8
71+
#define Valve_GPIO_Port GPIOB
72+
```
73+
> Please check if you do anything wrong if you cannot find or ask our senior, please **DO NOT** manually add this if you cannot find this!
3874
39-
Once configured, you can call the GPIO Pin using the macros we defined earlier and control your Air Cylinder.
75+
After you confirm you have added this new pins, you can use it like how we use it before:
4076
41-
---
77+
```c
78+
// If it is a GPIO Output Pin, you can:
79+
gpio_set(Valve); // Set the pin to HIGH
80+
gpio_reset(Valve); // Reset the pin to LOW
81+
gpio_toggle(Valve); // Toogle the pin
4282
43-
### Extended Reading: GPIO Input Mode
83+
// If it is a GPIO Input Pin, you can:
84+
uint8_t state = gpio_read(Valve);
85+
```
86+
At the meantime, we are not encouraged to use the `btn_read()` or `led_on()` or `led_off()` as we have mentioned before, we have flip the value of 0 and 1 for led and btn due to the hardware design, and so it may work somehow counter initative if you use it here.
87+
88+
---
89+
> Here are some extended explanation about different mode of GPIO Input and Output, you can try understanding what is happening but no worries if you cannot understand all.
90+
# Extended Reading: GPIO Input Mode
4491
4592
- As we have mentioned, our GPIO only receive discrete 0/1 signal, so it is trivial enough when we have a GND / 3.3V(out TTL is set to be 3.3V) given to the port, but what if it is not connected to anything?
4693
- When it is not connected to anything, it is the case we say it is in a floating state, and it will lead to a unpredictable readings due to noise.

tutorial-2-basic-io/06-Homework.md

+25-14
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,31 @@
66

77
> Actually this originally is the third classwork but I doubt if I can go thru all the things so I make it as homework to make both u and my life easier.
88
9-
So while we have covered you with the Pneumatic Valve as an usage of external GPIO, we designed this homework to introduce you about Line Following Sensor. Line Following Sensors commonly have two 'bulb', one to emit infrared rays (so I may say that is an IR Sensor) and another one used to received how many rays have been reflected to recognize black and white surface.
10-
11-
In your RDC, one of the robot you need to make would to fully auto to get something and then come back, and for the ease of you guys, we have draw lines to guide you from the starting point towards the end. Thus this task is give you a very very very brief idea how can you utilize the line.
12-
13-
In the board for this homework, you should find two Line Following Sensor connected in **PA15** and **PB15** respectively, and denote **PA15** as Left Sensor and **PB15** as Right Sensor. In this Homework, you are suppose to simulate a Line Following Robot with only 2 sensors. The requirement are as follow:
14-
15-
- When both of your Line Following Sensor detect white, print `Go Straight!!!` (1)
16-
- When the Left Sensor detect black, print `Turn Left` (1)
17-
- When the Right Sensor detect black, print `Turn Right` (1)
18-
- When both Sensor detect black, print `Stop!` (1)
19-
20-
Please ask Seniors for board for this task specifically as we don't have enough Line Following Sensor right now. And if you don't have the Black Line with you, just use your hand the block the 'bulb' of the sensors.
21-
22-
Since we don't have enough Line Following Sensor, some of you might receive limit switches(it works like a button). We will treat Limit switch pressed = Line Following sensor detect black
9+
> While we oroinigally designed a simplifed ELEC 1100 Line follower, we are now simpily it and you can take a look of the original one here:
10+
> <details>
11+
> <Summary>Original Homework , No Need to Do now</Summary>
12+
> So while we have covered you with the Pneumatic Valve as an usage of external GPIO, we designed this homework to introduce you about Line Following Sensor. Line Following Sensors commonly have two 'bulb', one to emit infrared rays (so I may say that is an IR Sensor) and another one used to received how many rays have been reflected to recognize black and white surface.
13+
>
14+
> In your RDC, one of the robot you need to make would to fully auto to get something and then come back, and for the ease of you guys, we have draw lines to guide you from the starting point towards the end. Thus this task is give you a very very very brief idea how can you utilize the line.
15+
>
16+
> In the board for this homework, you should find two Line Following Sensor connected in **PA15** and **PB15** respectively, and denote **PA15** as Left Sensor and **PB15** as Right Sensor. In this Homework, you are suppose to simulate a Line Following Robot with only 2 sensors. The requirement are as follow:
17+
>
18+
>- When both of your Line Following Sensor detect white, print `Go Straight!!!` (1)
19+
>- When the Left Sensor detect black, print `Turn Left` (1)
20+
>- When the Right Sensor detect black, print `Turn Right` (1)
21+
>- When both Sensor detect black, print `Stop!` (1)
22+
>
23+
>Please ask Seniors for board for this task specifically as we don't have enough Line Following Sensor right now. And if you don't have the Black Line with you, just use your hand the block the 'bulb' of the sensors.
24+
>
25+
>Since we don't have enough Line Following Sensor, some of you might receive limit switches(it works like a button). We will treat Limit switch pressed = Line Following sensor detect black
26+
> </details>
27+
28+
29+
As the objective of this homework is to give you a try on setting up new GPIO Pins, therefore now you are required to set up a GPIO on the targeted pin that pluged in a limit switch (Please ask senior if you cannot understand what pin it is)
30+
31+
And you should print `Input Detected` when the switch is pressed and print nothing when it is not pressed.
32+
33+
You may refer to the last notes about how t set up GPIO Pins, keep in mind that the example there is setting up `GPIO Output` while here you are doing `GPIO_Input`
2334

2435
---
2536

23.7 KB
Loading

0 commit comments

Comments
 (0)