|
前面做到了多任务点灯,今天用按键检测来控制LED灯的闪烁。 这里用到freertos的信号量来做控制: - /*3 o, Z4 r5 E- f
- 程序: Binary Semaphore 是一种信号机制9 O j V/ n7 G5 S; s" r6 c
- 一个任务(生产者)发出信号。另外一个任务(消费者)接受信号- P* _- _0 i( M6 i! }
- 公众号:孤独的二进制( q$ d* P! N2 [# X
' a2 A) {- _. ^5 k0 O( k- 语法:
4 _) O/ z x- B' G! A0 W - SemaphoreHandle_t xHandler; 创建Handler
e0 D5 ~# A; M" k* {' A, b - xHandler = xSemaphoreCreateBinary(); 创建一个二进制信号量 返回NULL,或者handler8 h( S/ M, w. x9 c7 P# c0 J
- xSemaphoreGive(xHandler); 生产者+1
, K) }3 ^% t6 B6 ? e5 N, X0 t - xSemaphoreTake(xHanlder, timeout); 消费者-1 返回pdPASS, 或者pdFAIL
1 T" O* C" R' ~ y+ p- f/ h
1 W0 L8 ]3 `4 _0 T- 二进制信号量可以想成就是一个整数 0 或者 1
9 ]% B) Y/ ^* z5 A. F' U% j0 n - Give就是+1
7 L r5 h# ^6 @3 R2 g0 q) b - Take就是-13 |* U6 J9 k* h' e% v, S6 T% Z
' g( S/ ?% H2 V3 Y' @0 K- Take的时候如果这个整数是0的话,就等待一直到timeout
6 }0 Z) V9 D# e/ Q7 L- c' m - */
复制代码思路是:1个是周期任务闪灯,另一人任务是接收到信号量才产生灯的转换。如果不按按键就保持原来的状态,如果检测按键按下,测周期闪灯。 程序如下: - #include <Arduino.h>6 Z2 G# n5 a/ n1 H
- #include <STM32FreeRTOS.h>) K6 `# D: a/ h. D
# }( |2 l5 {7 ~- SemaphoreHandle_t xSemaLED = NULL;//创建信号量Handler
9 ` `" H7 n9 u7 f- _7 r - TickType_t timeOut = 1000; //用于获取信号的Timeout 1 C3 t, A' l: B9 g, Y+ R
5 w. B( K5 L/ E6 o- typedef struct {4 O# {/ W9 z P' h9 E3 A
- byte pin;
# }8 v* i! M: E+ a6 k - int delayTime;9 C( _% G6 z# _2 Y$ }- I# s3 ^& |
- } LEDFLASH;
7 v0 p/ M) R% b# V2 S1 p& Q2 g$ q$ M
: A) V2 d3 ~; y3 d6 N" g1 R, Z- void ledFlash(void *pt){2 m$ i7 n% y+ Q$ D4 ^1 l4 [
- LEDFLASH *ptLedFlash = (LEDFLASH *)pt;
; } |0 u8 u- j9 a9 Z" D - byte pin = ptLedFlash->pin;8 S% X( x$ q8 U% E( x" Y3 R
- int delayTime = ptLedFlash->delayTime;
8 c% O9 O7 e o
. K ^( z/ w- s' d- pinMode(pin,OUTPUT);8 ~/ U; u7 e+ P! m3 V' o f
- while(1){' ] g+ _0 u' K. R5 n* t* k! ]
- //Serial.println("led1 flash");1 J7 G* a$ p% k
- digitalWrite(pin,!digitalRead(pin));* l9 f; |4 `1 i# O$ P
- vTaskDelay(delayTime);8 N/ u( b6 o2 D+ u1 @, w0 r& }9 M, W
-
+ D& j: o+ s. ]- l, e, y - }! S% H/ ?( A6 L& U( [
- }
. g# E( o e/ c+ c4 _6 s4 P b3 G& a - void ledFlash2(void *pt){
/ e* C4 t2 B% U& Y" h' m0 j - byte pin = PC7;9 ?, Y/ b+ A; f1 v1 m+ a3 U% Z4 t
- int delayTime = 500;) d5 w+ _4 J; W: \* r
- pinMode(pin,OUTPUT);0 a8 W' G6 B) b j: x3 Y
- while(1){ s P; O! y4 o
- if(xSemaphoreTake(xSemaLED,timeOut) == pdTRUE)' L3 S4 x' o" n! L, M# ^6 D
- {0 J2 m, u/ M( M, N
- digitalWrite(pin,!digitalRead(pin));0 Q/ D& U; x$ ?- |6 v- f
- vTaskDelay(delayTime);
4 ]# _3 d, l/ f1 K2 v; Z - }
8 o6 N+ f/ ]$ X; o6 `& H% z -
- s# j3 b/ J& Y$ ]6 l) n - }
" B+ Q& f1 @! a5 |# y: M3 U - }
0 D5 E1 A5 w; f - 5 T0 X' O9 |# v @2 ?, G$ ]
- void readBtn(void *pt)0 E' w# c: R$ z' m( F% ~4 T6 h5 W
- {
1 J* b* C) H, z$ v6 Q% J4 D8 a - byte pin = PC13;
* d6 f7 R2 I" F( w - pinMode(pin, INPUT_PULLDOWN);
! A- Y. r' y) k9 K( j - while(1)' F8 T w- `+ F
- { @6 Q2 s, z$ h* @' o9 G; R
- if(digitalRead(pin) == HIGH){
6 i3 a3 T( V+ J+ H) } A - xSemaphoreGive(xSemaLED);9 c6 n$ {$ g3 s0 B3 d/ ~% F
- vTaskDelay(120);
/ d2 x" ]) H3 G D* T - }# d: |% A [5 ~
- }
1 S# c1 P1 A" s6 @. B8 r - }
0 M. M3 W, n+ H% v0 r - LEDFLASH led1,led2;
- D5 }' J2 A5 f' [ - + Z: S+ J0 \1 x, O, P& I
- void setup() {
0 H( B4 P, M$ M: D/ L2 o - Serial.begin(115200);
6 M: H3 v, S& P2 ] - led1.pin = PB7;
3 @ O# b) ]. K W8 M; u5 A! p1 ? - led1.delayTime = 200;
/ h; ^8 _- y* T/ _ M - led2.pin = PC7;4 x, K8 i! U, a9 V
- led2.delayTime = 500;& h. j7 F/ s6 N# s9 I8 n
- TaskHandle_t myTask1,butTask;) y+ C2 g z/ E' \ y& a
- xSemaLED = xSemaphoreCreateBinary(); //创建二进制信号量
! V: L0 j; h0 T" u$ n R5 m - if(xTaskCreate(ledFlash,
6 _1 X! Q" b: V; m( v- r# a - "FLASH LED",
- u* I1 q% w( j- ` - 1024,: V& O% |8 c; q- v) _9 G
- (void *)&led1," ^% M$ A6 f5 P* P/ L
- 6,. U* l4 m& N" Z9 v0 ?) b- I! G
- NULL) == pdPASS)
5 d8 e) p! @: H+ |+ q - Serial.println("led1,flash task Created.");) F2 J4 m, L) }( [. p
- + p2 V/ M( o& ~" U8 s% x- y
- if (xTaskCreate(ledFlash2,+ V6 h. j9 @$ W" U: u* ^% R
- "Flash LED.",$ K5 {" O8 A V# j# c
- 1024,5 e" z U0 c) J. d
- NULL,# Z) X& C# t" G9 H. a
- 6,
* [ r1 d8 i& n( ` B - NULL) == pdPASS)7 ]/ W. {8 ?! ~2 Z+ {# O
- Serial.println("led2 flash task Created.");+ b: |8 q% B& S% r; y# k
-
) e. a) h5 d& | - if (xTaskCreate(readBtn,
2 |/ `- p6 J! ? - "Read Button",
# B+ f# O) T9 B) O- ~ - 1024,
2 p$ Q; @+ M" P - NULL,( D4 x7 E9 Z; ~/ M
- 1,' p# @3 ]: q) Z1 C* d z% V% S" K5 _
- &butTask)== pdPASS), v# V1 A, l& O9 Y6 g
- Serial.println("Create Read Button Semaphore.");
. Q- i7 J9 J9 Y7 g -
- h& x; W3 @! e) A' Z - vTaskStartScheduler();2 V# P) @# o% b8 M* a- _! I
- }2 x+ w% a- o7 M5 s0 O
7 m! b9 F: Y4 v- L" b4 U- void loop() {5 d3 A1 ~7 ^5 Q' s
- // put your main code here, to run repeatedly:
) R, Y5 S3 }0 P - }
复制代码实验现象见视频。
`8 ]7 }* X6 _0 L3 G4 n( U
出处:社区用户:lugl发布 8 O; I. z3 y% {/ R. l. ]
|