← Projects Liad Levy / Engineering
פרויקט גמר · מיקרו-מחשבים

דילר בינגו על מיקרו-בקר

Microcontroller Bingo Dealer — קוד C משובץ על בקר KEIL MCBSTR9

2024 · בקר KEIL MCBSTR9 · שפת C
Embedded C KEIL MCBSTR9 STR9 ADC LCD GPIO / LEDs
לוח הפיתוח KEIL MCBSTR9 עם צג LCD, כפתורים ופוטנציומטר
לוח הפיתוח KEIL MCBSTR9 — צג LCD, כפתורים, פוטנציומטר ונוריות LED.
תקציר

בפרויקט זה כתבנו קטע קוד בשפת C המדמה דילר במשחק בינגו. תחילה תופיע הודעת פתיחה עם שם המשחק והוראות להמשך. השחקנים מתבקשים להפעיל את המשחק על ידי לחיצה על הכפתור הראשון, וכעת יתחילו להיות מוצגים על המסך בזה אחר זה קלפים שונים המדמים "שליפה" מתוך חפיסת קלפים רגילה.

01 רקע לבחירה

הרעיון נולד ממשחק בינגו משפחתי: בכל סבב, מי שתורו להיות הדילר "הפסיד" את ההשתתפות במשחק — במקום להתרכז בשליפה המהירה של הקלף שהוכרז, הוא היה עסוק בהכרזה על הקלפים ובסידורם. כדי שיהיה לכולם נוח, קל וכיף יותר לשחק, החלטתי לבנות דילר אוטומטי שיבצע את העבודה הזו.

בחרנו בפרויקט זה מכיוון שהוא משלב אתגר של כתיבת קוד ותכנון לוגיקה לשימוש בכפתורים ובפוטנציומטר לבקרת מהירות ריצת נוריות LED — תוך שימוש בבקר KEIL ו-LCD לצורך אינטראקציה עם המשתמש.

סביבת הפיתוח — מחשב נייד עם סביבת הפיתוח, חיווט הבקר וצג LCD
סביבת הפיתוח — בדיקות חומרה וחיווט הבקר.

02 מהלך המשחק

את מהירות ה"שליפה" ניתן לשנות על ידי הזזת הפוטנציומטר. את המשחק ניתן להשהות ולהפעיל בשנית על ידי לחיצה על כפתור ההפעלה (הראשון).

הכפתור השני מסמן ניצחון — ברגע שנלחץ תופיע הודעה מתאימה ומיד בזה אחר זה יוצגו הקלפים "שנשלפו" עד כה על מנת לוודא ניצחון. בסיום ריצת הקלפים תופיע הודעה על המסך, ולתחילת משחק חדש ניתן ללחוץ על הכפתור השלישי. בכל זמן המשחק ישנו חיווי ויזואלי בצורת נורות ה-LED שרצות או מהבהבות בהתאם לשלבים במשחק.

03 רקע תיאורטי

בקרים (Microcontrollers) הם יחידות חישוביות זעירות הכוללות מעבד, זיכרון ואמצעי קלט/פלט, ומשמשים במגוון רחב של יישומים. הבקר איתו עבדנו הוא בקר של חברת KEIL מסוג MCBSTR9, המהווה אחד מהבקרים הנפוצים המשמשים ללמידה ולפיתוח בפרויקטים קטנים. באמצעות שימוש בכפתורים ובפוטנציומטר באמצעות קריאה אנלוגית, ניתן לשלוט במשתנים בתוכנית בזמן אמת, כמו מהירות ריצת הנוריות ומשך זמן ההשהיה בפרויקט זה.

בנוסף לכך, השימוש ב-ADC (Analog-to-Digital Converter) מאפשר לבקר לקרוא ערכים אנלוגיים מהפוטנציומטר ולהמיר אותם לערכים דיגיטליים שהבקר יכול לעבד. זה מאפשר לנו לקבל ערך מתמשך מהפוטנציומטר ולהשתמש בו לשליטה על פונקציות שונות בקוד לבחירתנו.

ה-LCD (Liquid Crystal Display) משמש להצגת מידע למשתמש בזמן אמת. בפרויקט זה ה-LCD משמש להצגת הודעות פתיחה, קלפים ומצב המשחק. הנוריות (LEDs) משמשות לצורך מתן פידבק ויזואלי למשתמש — הן מופעלות הן בצורת הבהוב והן בצורת ריצוד בחלקים מסוימים של הקוד, כאשר מהירות הריצה שלהן משתנה בהתאם לערך הפוטנציומטר.

04 תרשים זרימה

להלן תרשים הזרימה של התוכנית — מאתחול המערכת, דרך קריאת הפוטנציומטר וערבוב החפיסה, ועד הלולאה הראשית המטפלת בהצגת הקלפים, בהשהיה ובמצב הניצחון.

תרשים זרימה גרפי של תוכנית דילר הבינגו
איור 1. תרשים הזרימה הגרפי של התוכנית.

תרשים זרימה מילולי

05 הקוד

התוכנית נכתבה בשפת C עבור בקר ה-MCBSTR9. קריאת הפוטנציומטר מתבצעת דרך ה-ADC בפונקציית measure(), המחזירה ערך 10-ביט (0x03FF) המשמש לקביעת זמני ההשהיה; הנוריות מהבהבות דרך blink_leds().

main.c · קריאת ADC ונוריות
float measure(void) {
    ADC->CR &= 0xFF7F;
    ADC->CR = 0x0002;
    ADC->CR |= 0x0001;
    delay_ms(100);
    while ((ADC->CR & 0x8000) == 0);
    return (ADC->DR0 & 0x03FF);
}

void blink_leds(int times, unsigned int delay) {
    int i;
    for (i = 0; i < times; i++) {
        LED = 0xFF;
        delay_ms(delay);
        LED = 0x00;
        delay_ms(delay);
    }
}

חפיסת 52 הקלפים מיוצגת כמערך אינדקסים ומעורבבת באלגוריתם Fisher–Yates; הצבע והערך של כל קלף נגזרים מהאינדקס (cardIndex % 13 לערך, cardIndex / 13 לצבע).

main.c · ערבוב החפיסה
void shuffle(int *deck, int size) {
    int i, j, temp;
    for (i = size - 1; i > 0; i--) {
        j = rand() % (i + 1);
        temp = deck[i];
        deck[i] = deck[j];
        deck[j] = temp;
    }
}

בלולאה הראשית הנוריות "רצות" הלוך ושוב באמצעות הזזת ביט (n << 1 / n >> 1) עם היפוך כיוון בקצוות (0x80, 0x01), ובכל מחזור נשלף הקלף הבא מהחפיסה ומוצג ב-LCD. הלולאה ממשיכה ומטפלת בכפתורי ההשהיה (SW1) והניצחון (SW2).

main.c · הלולאה הראשית
while (running) {
    vmax = measure();
    LED = n;
    delay_ms((unsigned int)vmax);
    if (direction == 1) {
        n = n << 1;
        if (n == 0x80) {
            direction = -1;
        }
    } else {
        n = n >> 1;
        if (n == 0x01) {
            direction = 1;
        }
    }
    set_cursor(0, 1);
    if (!paused) {
        cardIndex = deck[displayedIndex];
        displayedCards[displayedIndex++] = cardIndex;
        if (displayedIndex >= 52) {
            displayedIndex = 0;
        }
        sprintf(buffer, "%s of %s", values[cardIndex % 13], suits[cardIndex / 13]);
        lcd_print((const unsigned char*)buffer);
        delay_ms(1500);
        lcd_clear();
    }
}

06 המשך הפיתוח

כרגע ההכרזות מוצגות על צג LCD קטן בלבד. השלב הבא בתכנון הוא הוספת רמקול עם צ'יפ MP3 וטעינת קבצי קול שיכריזו בקול על הקלפים ועל הניצחון — כך שהמשחק יהיה נגיש וקל יותר לשימוש גם למבוגרים.