• 方案介紹
    • 一、項(xiàng)目介紹
    • 二、系統(tǒng)設(shè)計(jì)
    • 三、源代碼
  • 附件下載
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

基于STC89C52單片機(jī)的遙控器設(shè)計(jì)

04/25 08:48
448
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

更多詳細(xì)資料請(qǐng)聯(lián)系.docx

共1個(gè)文件

一、項(xiàng)目介紹

隨著科技的不斷發(fā)展,紅外遙控器已經(jīng)成為我們?nèi)粘I钪衅毡槭褂玫囊环N電子設(shè)備。它能夠給我們帶來(lái)便捷和舒適,減少人工操作的繁瑣性。然而,在實(shí)際應(yīng)用中,有時(shí)候我們可能需要制作一個(gè)自己的紅外遙控器,以便于更好地滿足個(gè)性化需求。這樣的需求可能來(lái)自于家庭影音設(shè)備的控制、智能家居系統(tǒng)的控制,或者其他自動(dòng)化控制方案等。

本項(xiàng)目的目標(biāo)是設(shè)計(jì)一個(gè)簡(jiǎn)單且易于實(shí)現(xiàn)的單片機(jī)紅外遙控器,使用戶能夠自己定制并控制各種電子設(shè)備。通過使用鍵盤矩陣和紅外發(fā)射二極管,用戶只需按下相應(yīng)的按鍵即可發(fā)送紅外信號(hào),從而實(shí)現(xiàn)對(duì)電子設(shè)備的控制。此外,為了方便用戶知道當(dāng)前按下的鍵值,我們還添加了數(shù)碼管顯示的功能,使用戶可以直觀地看到自己所按下按鍵的值。

通過這個(gè)項(xiàng)目,可以學(xué)習(xí)到單片機(jī)的基本原理和應(yīng)用、鍵盤矩陣和紅外遙控的工作原理、數(shù)碼管的驅(qū)動(dòng)方式等知識(shí)。并且,還可以根據(jù)自己的需求進(jìn)行各種擴(kuò)展和改進(jìn),如增加更多按鍵、添加更多的電子設(shè)備控制功能等。

image-20230707174010048

二、系統(tǒng)設(shè)計(jì)

2.1 硬件設(shè)計(jì)

【1】主控芯片

選擇STC89C52作為主控芯片,該芯片具有強(qiáng)大的功能和廣泛的應(yīng)用,可以滿足本設(shè)計(jì)的需求。

【2】鍵盤設(shè)計(jì)

采用4x4矩陣鍵盤作為輸入設(shè)備,通過行列掃描的方式讀取用戶按鍵情況。每個(gè)鍵對(duì)應(yīng)一個(gè)唯一的鍵值,模擬電視機(jī)遙控板的鍵值。

【3】紅外線發(fā)送設(shè)計(jì)

使用紅外線發(fā)射二極管,根據(jù)NEC協(xié)議發(fā)送控制碼。NEC協(xié)議是一種常用的紅外遙控協(xié)議,它定義了紅外信號(hào)的幀結(jié)構(gòu)和通信規(guī)則。

【4】數(shù)碼管顯示設(shè)計(jì)

使用4位數(shù)碼管進(jìn)行鍵值數(shù)值的顯示。將鍵值轉(zhuǎn)換為對(duì)應(yīng)的數(shù)碼管段碼,通過依次設(shè)置4位數(shù)碼管的段選信號(hào)和位選信號(hào),顯示對(duì)應(yīng)的鍵值數(shù)值。

2.2 軟件設(shè)計(jì)

【1】 鍵盤掃描與鍵值獲取

通過設(shè)置行和列的IO口狀態(tài),循環(huán)掃描鍵盤,當(dāng)有鍵被按下時(shí),獲取對(duì)應(yīng)的鍵值。

【2】紅外控制碼發(fā)送

根據(jù)NEC協(xié)議的要求,生成控制碼的高低電平序列,并通過紅外發(fā)射二極管發(fā)送出去。

三、源代碼

#include <reg51.h>

// 定義鍵盤矩陣的行和列
sbit ROW1 = P0^0;
sbit ROW2 = P0^1;
sbit ROW3 = P0^2;
sbit ROW4 = P0^3;
sbit COL1 = P0^4;
sbit COL2 = P0^5;
sbit COL3 = P0^6;
sbit COL4 = P0^7;

// 定義紅外發(fā)射二極管的IO口
sbit IR_LED = P2^0;

// 定義數(shù)碼管的IO口
sbit DIGIT1 = P1^0;
sbit DIGIT2 = P1^1;
sbit DIGIT3 = P1^2;
sbit DIGIT4 = P1^3;
sbit SEG_A = P1^4;   // 數(shù)碼管段A
sbit SEG_B = P1^5;   // 數(shù)碼管段B
sbit SEG_C = P1^6;   // 數(shù)碼管段C
sbit SEG_D = P1^7;   // 數(shù)碼管段D

// 定義按鍵值對(duì)應(yīng)的控制碼
unsigned char keyTable[4][4] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

// 函數(shù)聲明
void delay(unsigned int time);
unsigned char scanKeyboard(void);
void sendIRCode(unsigned char code);
void displayValueOn7Segment(unsigned char value);

void main()
{
    unsigned char keyValue;
    
    while (1)
    {
        // 掃描鍵盤,獲取鍵值
        keyValue = scanKeyboard();
        
        if (keyValue != '?')  // 按鍵按下
        {
            // 發(fā)送紅外控制碼
            sendIRCode(keyValue);
            
            // 數(shù)碼管顯示鍵值
            displayValueOn7Segment(keyValue);
        }
    }
}

// 延時(shí)函數(shù)
void delay(unsigned int time)
{
    unsigned int i, j;
    for (i = 0; i < time; i++)
    {
        for (j = 0; j < 1000; j++);
    }
}

// 掃描鍵盤并獲取鍵值
unsigned char scanKeyboard(void)
{
    unsigned char row, col;
    
    ROW1 = 0; ROW2 = 1; ROW3 = 1; ROW4 = 1;   // 第1行置低,其余行置高
    if (COL1 == 0) { delay(10); while (COL1 == 0); return keyTable[0][0]; }
    if (COL2 == 0) { delay(10); while (COL2 == 0); return keyTable[0][1]; }
    if (COL3 == 0) { delay(10); while (COL3 == 0); return keyTable[0][2]; }
    if (COL4 == 0) { delay(10); while (COL4 == 0); return keyTable[0][3]; }
    
    ROW1 = 1; ROW2 = 0; ROW3 = 1; ROW4 = 1;   // 第2行置低,其余行置高
    if (COL1 == 0) { delay(10); while (COL1 == 0); return keyTable[1][0]; }
    if (COL2 == 0) { delay(10); while (COL2 == 0); return keyTable[1][1]; }
    if (COL3 == 0) { delay(10); while (COL3 == 0); return keyTable[1][2]; }
    if (COL4 == 0) { delay(10); while (COL4 == 0); return keyTable[1][3]; }
    
    ROW1 = 1; ROW2 = 1; ROW3 = 0; ROW4 = 1;   // 第3行置低,其余行置高
    if (COL1 == 0) { delay(10); while (COL1 == 0); return keyTable[2][0]; }
    if (COL2 == 0) { delay(10); while (COL2 == 0); return keyTable[2][1]; }
    if (COL3 == 0) { delay(10); while (COL3 == 0); return keyTable[2][2]; }
    if (COL4 == 0) { delay(10); while (COL4 == 0); return keyTable[2][3]; }
    
    ROW1 = 1; ROW2 = 1; ROW3 = 1; ROW4 = 0;   // 第4行置低,其余行置高
    if (COL1 == 0) { delay(10); while (COL1 == 0); return keyTable[3][0]; }
    if (COL2 == 0) { delay(10); while (COL2 == 0); return keyTable[3][1]; }
    if (COL3 == 0) { delay(10); while (COL3 == 0); return keyTable[3][2]; }
    if (COL4 == 0) { delay(10); while (COL4 == 0); return keyTable[3][3]; }
    
    return '?';   // 未按鍵返回空字符
}


// 發(fā)送紅外控制碼
void sendIRCode(unsigned char code)
{
    // 根據(jù)NEC協(xié)議生成紅外控制碼的高低電平序列
    // 將紅外控制碼通過紅外發(fā)射二極管發(fā)送出去

    unsigned int i;
    unsigned int startHighTime = 9000;   // 紅外協(xié)議起始高電平時(shí)間(μs)
    unsigned int startLowTime = 4500;    // 紅外協(xié)議起始低電平時(shí)間(μs)
    unsigned int bitHighTime = 560;      // 紅外協(xié)議數(shù)據(jù)位高電平時(shí)間(μs)
    unsigned int bit0LowTime = 560;      // 紅外協(xié)議數(shù)據(jù)位0低電平時(shí)間(μs)
    unsigned int bit1LowTime = 1690;     // 紅外協(xié)議數(shù)據(jù)位1低電平時(shí)間(μs)

    // 發(fā)送起始高電平
    IR_LED = 1;
    delayMicroseconds(startHighTime);

    // 發(fā)送起始低電平
    IR_LED = 0;
    delayMicroseconds(startLowTime);

    // 逐位發(fā)送數(shù)據(jù)位
    for (i = 0; i < 8; i++)
    {
        if (code & 0x01)  // 當(dāng)前位為1
        {
            IR_LED = 1;
            delayMicroseconds(bitHighTime);

            IR_LED = 0;
            delayMicroseconds(bit1LowTime);
        }
        else  // 當(dāng)前位為0
        {
            IR_LED = 1;
            delayMicroseconds(bitHighTime);

            IR_LED = 0;
            delayMicroseconds(bit0LowTime);
        }

        code >>= 1;  // 移位獲取下一位
    }
}

// 數(shù)碼管顯示鍵值
void displayValueOn7Segment(unsigned char value)
{
    unsigned char digitCode[10] =
    {
        0x3F,   // 顯示數(shù)字0
        0x06,   // 顯示數(shù)字1
        0x5B,   // 顯示數(shù)字2
        0x4F,   // 顯示數(shù)字3
        0x66,   // 顯示數(shù)字4
        0x6D,   // 顯示數(shù)字5
        0x7D,   // 顯示數(shù)字6
        0x07,   // 顯示數(shù)字7
        0x7F,   // 顯示數(shù)字8
        0x6F    // 顯示數(shù)字9
    };

    unsigned char digit1, digit2, digit3, digit4;

    digit1 = digitCode[value / 1000];
    digit2 = (digitCode[value / 100]) & 0x7F; // 去掉小數(shù)點(diǎn)
    digit3 = (digitCode[value / 10]) & 0x7F;  // 去掉小數(shù)點(diǎn)
    digit4 = (digitCode[value % 10]);

    // 設(shè)置位選并顯示數(shù)碼管的段碼
    DIGIT1 = 0; DIGIT2 = 1; DIGIT3 = 1; DIGIT4 = 1;
    P1 = digit1;

    delay(5);  // 延時(shí)一段時(shí)間,使數(shù)碼管顯示較穩(wěn)定

    DIGIT1 = 1; DIGIT2 = 0; DIGIT3 = 1; DIGIT4 = 1;
    P1 = digit2;

    delay(5);

    DIGIT1 = 1; DIGIT2 = 1; DIGIT3 = 0; DIGIT4 = 1;
    P1 = digit3;

    delay(5);

    DIGIT1 = 1; DIGIT2 = 1; DIGIT3 = 1; DIGIT4 = 0;
    P1 = digit4;

    delay(5);
}
  • 更多詳細(xì)資料請(qǐng)聯(lián)系.docx
    下載

相關(guān)推薦