Está en la página 1de 10

INSTITUTO POLITÉCNICO NACIONAL

Escuela Superior de Ingeniería Mecánica y Eléctrica


Unidad Zacatenco

Ingeniería en Comunicaciones y Electrónica

Sistemas en Tiempo Real

Práctica 3. Transferencia de datos entre PC y


RPI-Pico usando FreeRTOS

Profesor:
GARCIA ESPINOSA LUIS ANTONIO

Presenta:
Mendoza Trejo Luis Alfredo
1) Código Fuente.
2) /******************************************************************************
3) * Archivo: read_gpio.c
4) *
5) * Descripcion:
6) * Programa que muestra la lectura de un puerto GPIO a través de una tarea.
7) * Este programa fue probado en la tarjeta raspberry Pi Pico.
8) *
9) * Autor: Luis Alfredo Mendoza Trejo
10) *
11) * Revison: 0.1
12) * Rev 0.0 (18/05/23): Creado
13) *
14) * Notas:
15) * 1. Editar el archivo "FreeRTOSConfig.h" con la siguiente línea:
16) *
17) * configUSE_MUTEXES 1
18) *
19) * Asignacion de pines de entrada
20) *---------------------------------------------------------------------------
21) * variable: x(0) x(1) x(2) x(3) x(4) x(5)
22) * pin: 1 2 4 5 6 7
23) * GPIO: 0 1 2 3 4 5
24) * --------------------------------------------------------------------------
25) *
26) * Asignación de pines de salida
27) *---------------------------------------------------------------------------
28) * variable: y(0) y(1) y(2) y(3) y(4)
29) * pin: NA 27 26 25 24
30) * GPIO 25 21 20 19 18
31) * --------------------------------------------------------------------------
32) * ***************************************************************************/
33) #include <FreeRTOS.h>
34) #include <semphr.h> // contiene definiciones para usar semaforos
35) #include <task.h>
36) #include <stdio.h>
37) #include "pico/stdlib.h"
38)
39) // Arreglo de puertos GPIO de entrada (General Port)
40) char usrInput;
41) uint input[] = {
42) 0,
43) 1,
44) 1,
45) 2,
46) 3,
47) 4,
48) 5
49) };
50)
51) // Arreglo de puertos GPIO de salida
52) uint output[]= {
53) 25,
54) 21,
55) 20,
56) 19,
57) 18
58)
59) };
60)
61) uint semiperiod[]= {
62) 100,
63) 200,
64) 300,
65) 400,
66) 500,
67) 600
68) };
69)
70) bool level[]= {
71) 0,
72) 0,
73) 1,
74) 0,
75) 0
76)
77) };
78)
79) void read(void*);
80) void write(void*);
81) void conexion(void*);
82) void offall(void*);
83)
84) SemaphoreHandle_t mutex[]= {
85) NULL,
86) NULL,
87) NULL,
88) NULL,
89) NULL,
90) NULL,
91) NULL
92)
93)
94) };
95)
96) int main(){
97)
98) uint id;
99) stdio_init_all();
100)
101)
102) for(id=0;id<5;id++) {
103)
104) mutex[id]=xSemaphoreCreateMutex();
105)
106) if(mutex[id]!= NULL) {
107) xTaskCreate(read, "ch1_read_Task", 128, (void *)id, 3, NULL);
108) xTaskCreate(write, "ch1_write_Task", 128, (void *)id, 3, NULL);
109)
110)
111) }
112) }
113)
114) mutex[5]=xSemaphoreCreateMutex();
115) if(mutex[5]!= NULL) {
116) xTaskCreate(conexion, "serial", 512, (void *)5, 1, NULL);}
117)
118) mutex[6]=xSemaphoreCreateMutex();
119) if(mutex[6]!= NULL) {
120) xTaskCreate(offall, "off_all", 128, (void *)6, 2, NULL);}
121)
122)
123)
124) vTaskStartScheduler();
125)
126) while(true){};
127) }
128)
129) void read(void* arg) {
130)
131) uint ch = (uint)arg;
132) TickType_t xTimeAtWhichMutexWasTaken;
133)
134) TickType_t xDelay = 100/ portTICK_PERIOD_MS;
135) while(true) {
136) xSemaphoreTake(mutex[ch], portMAX_DELAY);
137) xTimeAtWhichMutexWasTaken = xTaskGetTickCount();
138)
139) vTaskDelay(xDelay);
140)
141) xSemaphoreGive(mutex[ch]);
142)
143) // Lineas agregadas para garantizar el cambio entre tareas
144) // con la misma prioridad si se usa el algoritmo de planificación
145) // pre-empt (con preferencia por prioridad con valor más bajo).
146) // Adelanta el cambio de tarea si el algoritmo de planifcación
147) // usado es el Round Robin (time slicing).
148) if( xTaskGetTickCount() != xTimeAtWhichMutexWasTaken ) {
149) taskYIELD();
150) }
151) }
152) }
153)
154) void write(void* arg) {
155) uint ch = (uint)arg;
156) TickType_t xTimeAtWhichMutexWasTaken;
157) TickType_t xDelay = semiperiod[ch] / portTICK_PERIOD_MS;
158) gpio_init(output[ch]);
159) gpio_set_dir(output[ch], GPIO_OUT);
160)
161) while(true) {
162) xSemaphoreTake(mutex[ch], portMAX_DELAY);
163) xTimeAtWhichMutexWasTaken = xTaskGetTickCount();
164)
165)
166) if(level[ch]!=0)
167)
168) {
169) gpio_put(output[ch],level[ch]);
170) vTaskDelay(xDelay);
171) gpio_put(output[ch],0);
172) vTaskDelay(xDelay);
173)
174) }
175)
176) xSemaphoreGive(mutex[ch]);
177)
178) if( xTaskGetTickCount() != xTimeAtWhichMutexWasTaken ) {
179) taskYIELD();
180) }
181) }
182) }
183)
184) void conexion(void* arg)
185) {
186)
187) uint ch = (uint)arg;
188) TickType_t xTimeAtWhichMutexWasTaken;
189)
190) while(true) {
191) xSemaphoreTake(mutex[ch], portMAX_DELAY);
192) xTimeAtWhichMutexWasTaken = xTaskGetTickCount();
193)
194) printf("\nEnciende o Apagar led | 1 al 5");
195) usrInput = getchar();
196)
197)
198) switch (usrInput) {
199) case '1':
200) switch (level[0])
201) { case 0:
202) level[0]=1;
203) printf("\nLED 1 turned on");
204) break;
205) case 1:
206) level[0]=0;
207) printf("\nLED 1 turned off");
208) break;
209) }
210)
211) break;
212) case '2':
213) switch (level[1])
214) { case 0:
215) level[1]=1;
216) printf("\nLED 2 turned on");
217) break;
218) case 1:
219) level[1]=0;
220) printf("\nLED 2 turned off");
221) break;
222) }
223)
224)
225) break;
226) case '3':
227) switch (level[2])
228) { case 0:
229) level[2]=1;
230) printf("\nLED 3 turned on");
231) break;
232) case 1:
233) level[2]=0;
234) printf("\nLED 3 turned off");
235) break;
236) }
237)
238)
239) break;
240) case '4':
241) switch (level[3])
242) { case 0:
243) level[3]=1;
244) printf("\nLED 4 turned on");
245) break;
246) case 1:
247) level[3]=0;
248) printf("\nLED 4 turned off");
249) break;
250)
251) }
252)
253)
254) break;
255) case '5':
256) switch (level[4])
257) { case 0:
258) level[4]=1;
259) printf("\nLED 5 turned on");
260) break;
261) case 1:
262) level[4]=0;
263) printf("\nLED 5 turned off");
264) break;
265)
266) }
267) break;
268)
269)
270) default:
271) printf("\nInvalid input value");
272) break;
273) } // end switch
274)
275) xSemaphoreGive(mutex[ch]);
276) if( xTaskGetTickCount() != xTimeAtWhichMutexWasTaken ) {
277) taskYIELD();
278) }
279) }
280) }
281)
282) void offall(void* arg) {
283)
284) uint ch = (uint)arg;
285) TickType_t xTimeAtWhichMutexWasTaken;
286) TickType_t xDelay = semiperiod[ch] / portTICK_PERIOD_MS;
287) gpio_init(input[0]);
288) gpio_set_dir(input[0], GPIO_IN);
289)
290) while(true) {
291) xSemaphoreTake(mutex[ch], portMAX_DELAY);
292) xTimeAtWhichMutexWasTaken = xTaskGetTickCount();
293)
294) vTaskDelay(xDelay);
295)
296) if(gpio_get(input[0])!=0)
297) {
298) printf("\nLa RPI-Pico se reiniciará si se oprime la tecla 'z' o 'c' para
cancelar.");
299) usrInput = getchar();
300) switch (usrInput)
301) { case 'z':
302) printf("\nRestarting");
303) level[0]=0;
304) level[1]=0;
305) level[2]=0;
306) level[3]=0;
307) level[4]=0;
308) break;
309)
310) case 'c':
311) printf("\nCancelado");
312) break;
313)
314) default:
315) printf("\nInvalid input");
316) break;
317)
318) }
319)
320)
321) }
322)
323) xSemaphoreGive(mutex[ch]);
324) if( xTaskGetTickCount() != xTimeAtWhichMutexWasTaken ) {
325) taskYIELD();
326) }
327) }
328) }
329)
2) Diagrama esquemático.

3) Fotos del circuito


Conexión Serial:

También podría gustarte