2017年5月20日 星期六

8051 - Bluetooth Toy Car (繁)

警告與免責聲明:

如果您沒有任何基本電子知識,請不要嘗試這篇教學。作者對本教學所導致的任何損害概不負責。嘗試這篇教學風險自負。

底下將使用一顆STC89C52RC單晶片、一個HC-06 UART介面藍牙模組與一個L298N馬達驅動模組來打造一台藍牙遙控玩具車。此遙控車要搭配『Bluetooth Remote Toy』APP才能使用,如此一來,你就可以透過手機藍牙來控制玩具車。底下是遙控車的控制指令:

每個命令都是由一個Byte組成。如果您要停止某個動作,則在該動作指令和停止/關閉指令之間執行OR操作。例如,

  • 0x01000100(前進)| 0x00100000(停止)= 0x01100100,將發送到遙控車使它停止前進。
  • 0x01001000(大燈) | 0x00100000(關掉) = 0x01101000,將發送到遙控車使它關掉大燈。

紅色、綠色和藍色按鈕保留給那些想要執行額外操作的人。

控制功能 指令
紅色按鈕 0x01000001
綠色按鈕 0x01000010
藍色按鈕 0x01000011
前進 0x01000100
後退 0x01000101
右轉 0x01000110
左轉 0x01000111
大燈 0x01001000
尾燈 0x01001001
停止/關掉 0x00100000

購買這款玩具車後,我用8051電路替代了原本的RF電路。玩具車前後共兩顆直流馬達,前馬達用於控制方向(左/右),後馬達用於控制前進和後退。HC-06藍牙模組用於接收Android手機端傳來的指令。L298N H-bridge 模組可以讓您控制兩顆直流馬達的速度和方向。STC89C52RC單晶片用於控制整個系統。

L298N H-bridge模組

關於此模塊的更多詳細資訊,請閱讀這裡。我建議您在開始之前先閱讀一下。

接腳說明

  1. 前直流馬達 "+"
  2. 前直流馬達 "-"
  3. 12V跳線 - 對於本教程,請保留這跳線。
  4. 在這裡連接馬達電源電壓,並使用7 ~ 12V直流電壓驅動本教程的馬達。
  5. GND - 接地
  6. 5V輸出 - 如果您使用7 ~ 12V直流電壓驅動馬達,並且保留12V跳線,則該模組還可以為您的8051單晶片提供5V直流電壓。
  7. ENA - 前直流馬達啟用跳線(Enable Jumper)。對於本教程,請保留這跳線。如果要控制前直流馬達的速度,則必須將MCU的PWM輸出連接到ENA。對於STC89C52RC單晶片是沒有PWM輸出。但是如果需要,您可以使用timer在8051上實現PWM。
  8. IN1 - 前直流馬達的方向。
  9. IN2 - 前直流馬達的方向。
  10. IN3 - 後直流馬達的方向。
  11. IN4 - 後直流馬達的方向。
  12. ENB - 後直流馬達啟用跳線(Enable Jumper)。對於本教程,請保留這跳線。如果要控制後直流馬達的速度,則必須將MCU的PWM輸出連接到ENB。對於STC89C52RC單晶片是沒有PWM輸出。但是如果需要,您可以使用timer在8051上實現PWM。
  13. 後直流馬達 "+"
  14. 後直流馬達 "-"

前馬達真值表

ENB IN3 IN4 說明
0 N/A N/A Off
1 0 0 停止
1 0 1 反轉
1 1 0 正轉
1 1 1 剎住

後馬達真值表

ENA IN1 IN2 說明
0 N/A N/A Off
1 0 0 停止
1 0 1 反轉
1 1 0 正轉
1 1 1 剎住

為您的電源選擇合適的電壓是很重要,太低會導致性能下降,太高會損壞馬達,請確保電壓不超過馬達額定電壓。對於我的玩具車,我使用兩顆串聯連接的Panasonic NCR18650B 3.6 Volt 18650電池供電約7.2V。對於您的玩具車,請為您的電源選擇合適的電壓,這取決於您的馬達。

電路圖

底下是我完成的成品。

底下是用組合語言寫的,你可用C語言改寫。8051的組合語言沒有很難,語法也沒有很多,剛開始學8051可以考慮用組合語言撰寫,這樣會比較了解8051,但如果程式碼越來越大,又考慮可讀性與移植性,建議用C語言撰寫。至於8051的開發環境,可以參考這裡

程式碼

STOP    BIT     20H
TURN    BIT     21H
R_ON    BIT     22H
G_ON    BIT     23H
B_ON    BIT     24H
B_STP   BIT     25H
KP_MV   BIT     26H
        ORG     00H
        AJMP    START
        ORG     23H             ;Serial interrupt vector address
        AJMP    SERIAL_ROUTINE
        ORG     2BH             ;Timer2 interrupt vector address
        AJMP    TIMER2_ROUTINE
START:
        ACALL   INIT
        ACALL   INIT_SERIAL
        ACALL   INIT_TIMER2
LOOP:
        ACALL   DELAY
        JNB     B_ON, STOP_BLUE_LED
        JB      TURN, TURN_AROUND
        MOV     P2, A
        RL      A
        CJNE    A, #01111111B, SET_TURN_RIGHT
        SETB    TURN
        AJMP    LOOP
SET_TURN_RIGHT:
        AJMP    LOOP
TURN_AROUND:
        MOV     P2, A
        RR      A
        CJNE    A, #11111110B, SET_TURN_LEFT
        CLR     TURN
        AJMP    LOOP
SET_TURN_LEFT:
        AJMP    LOOP
STOP_BLUE_LED:
        JNB     B_STP, RESET_DONE
        CLR     B_STP
        MOV     A, #11111110B
        CLR     TURN
        MOV     P2, #255
RESET_DONE:
        AJMP    LOOP

;--------------------
; Delay
;--------------------
DELAY:  MOV     R6, #100
DLY1:   MOV     R7, #255
DLY2:   DJNZ    R7, DLY2
        DJNZ    R6, DLY1
        RET

;--------------------
; Initialize variables
;--------------------
INIT:
        MOV     SP, #60H
        CLR     STOP
        CLR     TURN
        CLR     R_ON
        CLR     G_ON
        CLR     B_ON
        CLR     B_STP
        MOV     A, #11111110B
        MOV     P0, #0
        MOV     P1, #00110000B
        MOV     P2, #255
        MOV     R5, #15
        RET

;--------------------
; Initialize serial
;
; TCON Register:
;  7   6   5   4   3   2   1   0
; TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
;
; TMOD Register:
;   7     6    5   4    3     2    1   0
; GATE1 C/T1# M11 M01 GATE0 C/T0# M10 M00
;
; SCON Register:
;  7   6   5   4   3   2  1  0
; SM0 SM1 SM2 REN TB8 RB8 TI RI
;--------------------
INIT_SERIAL:
        MOV     SCON, #50H      ;Mode 1: 8-bit UART
        MOV     TMOD, #20H      ;Timer and reload mode
        MOV     TH1, #0FDH      ;Baud rate 9600bps
        MOV     TL0, #0FDH      ;Baud rate 9600bps
        SETB    TR1             ;Timer1 runs
        SETB    PS              ;High interrupt priority
        SETB    ES              ;Enable serial interrupt
        RET

;---------------------------------------------------
; Initialize timer2
;
; T2CON Register:
;  7   6    5    4     3    2   1     0
; TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RL2
;
; 1 second = 11.0592MHZ / 12 = 921600 = 61440 * 15
; TH2 = (65536-61440)/256 = 16 = 10H
; TL2 = (65536-61440)%256 = 0 = 00H
;
; 0.5 second = 30720 * 15
; TH2 = (65536-30720)/256 = 136 = 88H
; TL2 = (65536-30720)%256 = 0 = 00H
;
; 0.25 second = 15360 * 15
; TH2 = (65536-15360)/256 = 196 = C4H
; TL2 = (65536-15360)%256 = 0 = 00H
;
; IE Register:
; 7  6  5  4   3    2   1   0
; EA - ET2 ES ET1  EX1 ET0 EX0
;---------------------------------------------------
INIT_TIMER2:
        CLR     EXF2            ;Reset flag
        CLR     TCLK            ;Disable baud rate generator
        CLR     RCLK            ;Disable baud rate generator
        CLR     EXEN2           ;Ignore events on T2EX
        MOV     TH2, #0C4H
        MOV     RCAP2H, #0C4H
        MOV     TL2, #00H
        MOV     RCAP2L, #00H
        CLR     CT2             ;Timer mode
        CLR     CPRL2           ;Reload mode
        CLR     PT2             ;Low interrupt priority
        SETB    ET2             ;Enable timer2 interrupt
        SETB    EA              ;Global interrupts enable
        SETB    TR2             ;Timer2 run
        RET

;-----------------------------------
; Timer2 interrupt service routine
;
; This is very important for the toy
; car to stop all actions when the
; bluetooth signal of your toy car
; is out of range, and no command
; is received after (0.25 * 2) second.
;
;-----------------------------------
TIMER2_ROUTINE:
        PUSH    ACC             ;Save ACC register on the stack
        DJNZ    R5, CONTINUE    ;Continue timer if it is less then 1 second
        JB      KP_MV, NO_CLEAR
        CLR     P1.0            ;Stop forward
        CLR     P1.1            ;Stop backward
        CLR     P1.2            ;Stop right
        CLR     P1.3            ;Stop left
NO_CLEAR:
        CLR     KP_MV
        MOV     R5, #15         ;Recount 0.25 second
CONTINUE:
        CLR     TF2             ;Reset interrupt flag
        POP     ACC             ;Restore ACC
        RETI

;----------------------------------------
; Serial port interrupt service routine
;----------------------------------------
SERIAL_ROUTINE:
        PUSH    ACC
        SETB    KP_MV
        MOV     A, SBUF
        JNB     A.5, RED_BUTTON
        SETB    STOP
        CLR     A.5
RED_BUTTON:
        CJNE    A, #01000001B, GREEN_BUTTON
        JB      STOP, STOP_RED_BUTTON
        SETB    R_ON
        LJMP    EXIT
STOP_RED_BUTTON:
        CLR     R_ON
        CLR     STOP
        LJMP    EXIT
GREEN_BUTTON:
        CJNE    A, #01000010B, BLUE_BUTTON
        JB      STOP, STOP_GREEN_BUTTON
        SETB    G_ON
        SJMP    EXIT
STOP_GREEN_BUTTON:
        CLR     G_ON
        CLR     STOP
        SJMP    EXIT
BLUE_BUTTON:
        CJNE    A, #01000011B, FORWARD
        JB      STOP, STOP_BLUE_BUTTON
        SETB    B_ON
        SJMP    EXIT
STOP_BLUE_BUTTON:
        CLR     B_ON
        CLR     STOP
        SETB    B_STP
        SJMP    EXIT
FORWARD:
        CJNE    A, #01000100B, BACKWARD
        JB      STOP, STOP_FORWARD
        SETB    P1.0
        SJMP    EXIT
STOP_FORWARD:
        CLR     P1.0
        CLR     STOP
        SJMP    EXIT
BACKWARD:
        CJNE    A, #01000101B, RIGHT
        JB      STOP, STOP_BACKWARD
        SETB    P1.1
        SJMP    EXIT
STOP_BACKWARD:
        CLR     P1.1
        CLR     STOP
        SJMP    EXIT
RIGHT:
        CJNE    A, #01000110B, LEFT
        JB      STOP, STOP_RIGHT
        SETB    P1.2
        SJMP    EXIT
STOP_RIGHT:
        CLR     P1.2
        CLR     STOP
        SJMP    EXIT
LEFT:
        CJNE    A, #01000111B, CAR_FRONT_LIGHT
        JB      STOP, STOP_LEFT
        SETB    P1.3
        SJMP    EXIT
STOP_LEFT:
        CLR     P1.3
        CLR     STOP
        SJMP    EXIT
CAR_FRONT_LIGHT:
        CJNE    A, #01001000B, CAR_REAR_LIGHT
        JB      STOP, STOP_FRONT_LIGHT
        CLR     P1.4
        SJMP    EXIT
STOP_FRONT_LIGHT:
        SETB    P1.4
        CLR     STOP
        SJMP    EXIT
CAR_REAR_LIGHT:
        CJNE    A, #01001001B, EXIT
        JB      STOP, STOP_REAR_LIGHT
        CLR     P1.5
        SJMP    EXIT
STOP_REAR_LIGHT:
        SETB    P1.5
        CLR     STOP
EXIT:
        CLR     RI
        POP     ACC
        RETI
        END

Demo

警告與免責聲明:

如果您沒有任何基本電子知識,請不要嘗試這篇教學。作者對本教學所導致的任何損害概不負責。嘗試這篇教學風險自負。

沒有留言: