You are on page 1of 6

TRƯỜNG ĐHBK TP.

HCM ĐỀ THI HỌC KỲ 2 / 2019-2020


KHOA ĐIỆN-ĐIỆN TỬ MÔN: LẬP TRÌNH NHÚNG
BỘ MÔN KỸ THUẬT ĐIỆN TỬ Thời gian: 80 phút

(SV được sử dụng tài liệu, không sử dụng laptop, máy vi tính)

Câu 1: (2đ)

a) Viết chương trình C int findpos(char *mystr, char mycharacter) trả về vị trí đầu tiên
xuất hiện ký tự mycharacter trong chuỗi mystr. Nếu không tìm được thì trả về giá trị -1.

VD: findpos(“abca”,’a’) = 0.
ĐA:

Int findpos(char *mystr, char mycharacter)


{
Int i = 0;
Char *p = mystr;
While (*p != 0)
{
If (*p == mycharacter) return I;
Else
{
P++;
I++;
}
}
Return -1;
}

Câu 2: (3đ)

Viết chương trình cho TIVA C thực hiện công việc sau:
Sau khi reset, tất cả LED đều tắt
1) Nhấn SW1, Led R sáng. Nhả SW1, LED R vẫn sáng
2) Nhấn lại SW1, Led R tắt, LED G sáng. Nhả SW1, LED G vẫn sáng.
3) Nhấn lại SW1, Led G tắt, LED B sáng. Nhả SW1, LED B vẫn sáng.
4) Nhấn lại SW1, Led R sáng, LED B tắt. Nhả SW1, LED R vẫn sáng. Quá trình lặp lại từ bước 1.
a) Vẽ máy trạng thái cho hệ thống
b) Viết module state.h và state.c để thực hiện các khai báo và các hàm cần thiết
c) Viết module main.c thực hiện yêu cầu
Cho trước các hàm:
void initSystem(void) để khởi động clock hệ thống và cấu hình các chân GPIO
int readSW1(void) đọc trạng thái SW1. Nếu giá trị trả về là 0 nghĩa là SW được nhấn, bằng 1 là
SW được nhả.
Void ledControl(int Lednum, int Val). Lednum bằng 0, 1, 2 tương ứng Led R, G, B. Val bằng 0 là tắt
LED, bằng 1 là bật LED.

VD: Lệnh ledControl(0,1) sẽ bật led R

ĐA:
a)

b)State.h:

#ifndef STATE_H_
#define STATE_H_

void initState(void);
void StateMachineUpdate(void);

#endif

State.c:

#define PRESSED 0
#define RELEASED 1
typedef enum {S_RESET=0,S1, S2, S3, S4, S5, S6} State_t;

static ledRState_t State ;


void initState(void)
{
State = S_RESET;
}
void StateMachineUpdate(void)
{
switch (State)
{
case S_RESET:
if (readSW1() == PRESSED)
{
State = S1;

}
break;
case S1:
if (readSW1() == RELEASED)
{
State = S2;
}
break;
case S2:
if (readSW1() == PRESSED)
{
State = S3;
}
break;
case S3:
if (readSW1() == RELEASED)
{
State = S4;
}
break;
case S4:
if (readSW1() == PRESSED)
{
State = S5;
}
break;
case S5:
if (readSW1() == RELEASED)
{
State = S6;
}
break;
case S6:
if (readSW1() == PRESSED)
{
State = S1;
}
break;
}
switch (State)
{
case S_RESET:
ledControl(0,0);
ledControl(1,0);
ledControl(2,0);
break;
case S1:
ledControl(2,0); //turn off led Blue
ledControl(0,1); //turn on led red
break;
case S3:
ledControl(0,0); //turn off led Red
ledControl(1,1); //turn on led green
break;
case S5:
ledControl(1,0); //turn off led green
ledControl(2,1); //turn on led blue
break;
}
}
Câu 3: (2 đ)
Cho đoạn chương trình sau. Hàm void delay(int ms) tạo trễ với đơn vị là ms. Hàm char button()
đọc về giá trị của 4 nút nhấn tương ứng với 4 bit thấp. Giả sử hàm button() đọc về giá trị 0x01
nghĩa là SW0 được nhấn, các SW1-3 được nhả. (1 là nhấn, 0 là nhả, bit 0 ứng với SW0).

Coi như thời gian thực hiện lệnh buttons() và các lệnh khác là không đáng kể, trừ lệnh delay.

void f1(void) { delay(1000); }


void f2(void) { delay(2000); }
void f3(void) { delay(3000); }
void f4(void) { delay(4000); }
void main (void) {
while (1) {
if (buttons() & 0x01) f1();
if (buttons() & 0x02 ) f2();
if (buttons() & 0x04 ) f3();
if (buttons() & 0x08 ) f4();
delay(1000);
}}
a) Giả sử ban đầu không có phím nào nhấn. Để chắc chắn hàm f4() được thực thi ta phải
nhấn và giữ SW3 trong thời gian ít nhất là bao nhiêu? Giải thích
Vì chưa có phím nào nhấn nên chương trình sẽ không thực hiện bất kỳ hàm f nào. Vì vậy
trường hợp xấu nhất là ta bắt đầu nhấn phím khi chương trình vừa bắt đầu thực hiện hàm
delay(1000). Để hàm f4() được thực hiện ta phải giữ phím trong ít nhất 1s.

b) Tại một thời điểm bất kỳ, ta phải nhấn và giữ SW1 trong ít nhất là bao lâu để chắc chắn
hàm f2() được thực thi? Giải thích.
Trong thời điểm bất kỳ, trường hợp xấu nhất là các SW khác đều được nhấn và ta bắt đầu
nhấn SW2 ngay tại thời điểm hàm f3() bắt đầu thực hiện. Để f2() được thực hiện ta phải
giũ phím trong 3+4+1+1=9s

Câu 4: (3đ)
Cho chương trình sau:

int counter = 15;


void T1(void) {
while (1) {
xSemaphoreTake(sem1, portMAX_DELAY );
// sem1 sẽ được GIVE trong ngắt của sự kiện 1
f(1);
}}
void T2(void) {
while (1) {
xSemaphoreTake(sem2, portMAX_DELAY );
// sem2 sẽ được GIVE trong ngắt của sự kiện 2
f(-1);
}}
void f(int i) {
delay(10); // delay 10 ms
counter = counter + i ; // modify some global counter
printf("counter is %d\n", counter) ; // print result
}

a) Hàm f có phải là hàm re-entrance hay không? Giải thích. (Hàm re-entrance là hàm có thể
được bị ngắt giữa chừng khi đang thực hiện trong một task và được gọi lại trong task khác
mà không hoạt động sai)
Hàm này không phải hàm re-entrance vì có sử dụng biến toàn cục.

b) Task T1 có độ ưu tiên cao hơn task T2.


Giả sử ngắt của sự kiện 2 xảy ra trước, sau đó 3 ms sự kiện 1 xảy ra. Chương trình sẽ xuất
các dòng thông báo như thế nào ra màn hình? Giải thích.

Khi ngắt của sự kiện 2 xảy ra trước, Tast T2 lấy được semaphore và thực hiện f(-1). Khi
đang thực hiện hàm delay(10) thì ngắt sự kiện 1 xảy ra, khi đó task T1 gọi hàm f(1), và sẽ
in ra màn hình dòng:
counter is 16
Sau đó, T1 lấy semaphore và bị Block trở lại, T2 chạy tiếp hàm
delay(10) trong f(-1), lúc này counter đã có giá trị 16. Vì vây,
hàm printf sẽ xuất dòng thông báo

counter is 15

You might also like