Kamis, 18 Oktober 2012

Communication System Development using PIC16F84A Microcontroller using Proteus 8 and MpLAB

In this communication system project using Proteus 8 software a simple communication system is shown using two PIC16F84A microcontrollers which acts as a transmitter and receiver. Assembly code for the two microcontroller is provided and shown how these microcontroller communicate.

The basic communication is via a simple protocol which allows the two micro-controllers to communicate. The switches at the transmitter MC are used as input and converted to message and sent to the receiving microcontroller serially. The received message is then shown to light up the output leds at the receiver. In other words the state of the switches forms the message to be sent and the LED glow at the receiver forms the message received.

The Schematic for this communication system is shown below-

PIC16F84A microcontroller communication System using Protues 8

The components used are-
  • 9C04021A4700FLHF3(470 ohm resistor)
  • 9C08052A1002FKHFT(10k ohm resistor)
  • Button
  • Crystal
  • DIPSW_8
  • LED-BIBY
  • LED-BIBG
  • LED-BLUE
  • PIC16F84A(micro-controller)
 The schematic is shown above. Once the schematic is drawn, hex file are required for the micro-controller for the simulation. The two micro-controller should be loaded with hex code. The hex code are generated using the MpLAB IDE. Two MpLAB project are required to generate two hex code- one for transmitter microcontroller and one for receiver microcontroller.

To generate the hex code open the MpLAB and create a new project by clicking on the Project>Project Wizard.

hex code generation step using MpLAB
A new window will pop-up, click next. Then in the next window select PIC16F84A, then click next. In the language toolsuite option, select Microchip MPASM Toolsuite as shown-

hex code generation step using MpLAB
In the next window step 3, select a folder where you want to save the project and the name of the project.

Then the step 4 allows you to add files to the project. Add the following files-
  • C:\Program Files\Microchip\MPASM Suite\LKR\16f84a_g.lkr
  • C:\Program Files\Microchip\MPASM Suite\p16f84a.inc
  • C:\Program Files\Microchip\MPASM Suite\Template\Object\16F84ATEMO.ASM
The first file is a linker file, the second is the include file and the third is a assembly template. Once these are added, click next and then finish to finish up the project wizard.

For the transmitter microcontroller, open the 16F84ATEMO.asm template just created by double clicking on it and copy-paste the below assembly code for the transmitter.
hex code generation step using MpLAB
hex code generation step using MpLAB

Transmitter Microcontroller Source Code:
;=========================
; setup and configuration
;=========================
    processor 16f84A
    include      <p16f84A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;============================================================
;                        M A C R O S
;============================================================
; Macros to select the register banks
Bank0    MACRO            ; Select RAM bank 0
        bcf        STATUS,RP0
        ENDM

Bank1    MACRO            ; Select RAM bank 1
        bsf        STATUS,RP0
        ENDM
;=====================================================
;          constant definitions for pin wiring
;=====================================================
#define readySW  2  ;|
#define readyLED 3    ;| -- from wiring diagram
#define serialLN 0    ;|
;=====================================================
;            PIC register and flag equates
;=====================================================
c        equ        0        ; Carry flag
tmrOVF    equ        2        ; Timer overflow bit
;
;======================================================
;              variables in PIC RAM
;=====================================================
    cblock    0x0c    ; Start of block
    bitCount        ; Counter for 8 bits
    rcvReg            ; Data to send
    temp
    endc
;=========================================================
;                           program
;=========================================================
    org    0      ; start at address
    goto    main
; Space for interrupt handlers
    org    0x04

main:
    Bank1
; Port A bits 0 and 2 are input. All others are output
    movlw    b'00000101' ; port A setup
    movwf    TRISA
; Port B is all output
    movlw    b'00000000' ; port B setup
    MOVWF    TRISB
    Bank0
; Turn off all port B LEDs
    clrf    PORTB
; And receiver register
    clrf    rcvReg
; Prepare to set prescaler
    clrf    TMR0
    clrwdt
; Setup OPTION register for full timer speed
    movlw    b'11011000'
;   1  1  0  1  1  0  0  0 <= OPTION bits
;   |  |  |  |  |  |__|__|_____ PS2-PS0 (prescaler bits)
;   |  |  |  |  |               Values for Timer0
;   |  |  |  |  |              *000 = 1:2   001 = 1:4
;   |  |  |  |  |               010 = 1:8   011 = 1:16
;   |  |  |  |  |               100 = 1:32  101 = 1:64
;   |  |  |  |  |               110 = 1:128 111 = 1:256
;   |  |  |  |  |______________ PSA (prescaler assign)
;   |  |  |  |                 *1 = to WDT
;   |  |  |  |                  0 = to Timer0
;   |  |  |  |_________________ TOSE (Timer0 edge select)
;   |  |  |                     0 = increment on low-to-high
;   |  |  |                    *1 = increment in high-to-low
;   |  |  |____________________ TOCS (TMR0 clock source)
;   |  |                       *0 = internal clock
;   |  |                        1 = RA4/TOCKI bit source
;   |  |_______________________ INTEDG (Edge select)
;   |                           0 = falling edge
;   |                          *1 = raising edge
;   |__________________________ RBPU pullups
;                               0 = enabled
;                              *1 = dissabled
    option
; Dissable interrupts
    bcf        INTCON,5   ; Timer0 overflow dissabled
    bcf        INTCON,7   ; Global interupts dissabled
;=========================
;  wait for READY switch
;     to be pressed
;=========================
ready2rcv:
    btfsc    PORTA,readySW    ; Test switch
    goto    ready2rcv        ; loop
; Turn ON the ready-to-receive LED
    bsf        PORTA,readyLED
;===========================
;        receiving
;===========================
    call    rcvData        ; Call serial input procedure
;===========================
;       data received
;===========================
; Turn ready to receive LED off
    bcf        PORTA,readyLED
; Display received data
    movf    rcvReg,w    ; Byte received to w
    movwf    PORTB        ; display in port B
;===========================
;      wait forever
;===========================
endloop:
    goto    endloop
;============================================================
;               procedure to receive serial data
;============================================================
; ON ENTRY:
;         local variable dataReg is used to store 8-bit value
;         received through port (labeled serialLN)
; OPERATION:
;      1. The timer at register TMR0 is set to run at
;         maximum clock speed, that is, 256 clock beats.
;         The timer overflow flag in the INTCON register
;         is set when the timer cycles from 0xff to 0x00.
;      2. When the START signal is received, the code
;         waits for 128 timer beats so as to read data in
;         the middle of the send period.
;      3. Each bit (start, data, and stop bits) is read
;         at intervals of 256 timer beats.
;      4. The procedure tests the timer ofverflow flag
;         (tmrOVF) to determine when the timer cycle has
;         ended, that is when 256 clock beats have passed.

;------------------------------------------------------------
rcvData:
    clrf    TMR0    ; Reset timer
    movlw    0x08    ; Initialize bit counter
    movwf    bitCount
;=========================
;   wait for START bit
;=========================
startWait:
    btfsc    PORTA,0        ; Is port A0 low?
    goto    startWait    ; No. Wait for mark
;=========================
;  offset 128 clock beats
;=========================
; At this point the receiver has found the falling
; edge of the start bit. It must now wait 128 timer
; beats to synchronize in the middle of the sender's
; data rate, as follows:
;             |<========= falling edge of START bit
;             |
;             |-----|<====== 128 clock beats offset
;   ----------.     |     .---------
;             |           |  <== SIGNAL
;              -----------
;             |<-- 256 -->|
;
    movlw    0x80        ; 128 clock beats offset
    movwf    TMR0        ; to TMR0 counter
    bcf        INTCON,tmrOVF    ; Clear overflow flag
offsetWait:
    btfss    INTCON,tmrOVF   ; timer overflow?
    goto    offsetWait        ; wait until
    btfsc    PORTA,0            ; Test start bit for error
    goto    offsetWait        ; Recycle if a false start
;==========================
;      receive data
;==========================
    clrf    TMR0        ; Restart timer
    bcf        INTCON,tmrOVF    ; Clear overflow flag
; Wait for 256 timer cycles for first/next data bit
bitWait:
    btfss    INTCON,tmrOVF  ; Timer cycle end?
    goto    bitWait            ; Keep waiting
; Timer has counter 256 beats
    bcf        INTCON,tmrOVF    ; Reset overflow flag
    movf    PORTA,w            ; Read port A into w
    movwf    temp            ; Store value read
    rrf        temp,f            ; Rotate bit 0 into carry flag
    rlf        rcvReg,f           ; Rotate carry into rcvReg bit 0
    decfsz    bitCount,f        ; 8 bits received
    goto    bitWait            ; Next bit
; Wait for one time cycle at end of reception
markWait:
    btfss    INTCON,tmrOVF    ; timer overflow flag
    goto    markWait        ; keep waiting
;========================
;   end of reception
;========================
    return

;=========================================================
;                       end of program
;=========================================================
    end

Once copied click on Build All option to start compiling the assembly code. Once this is complete, it should show Build Succeeded as shown below-

hex code generation step using MpLAB

This create a transmit.hex (transmit is the project name here) in the MpLAB project folder. See below-

hex code generation step using MpLAB

Copy the transmit.hex file into your microcontroller proteus project folder. See example below-

hex code generation step using MpLAB


Now to burn the transmit.hex file to the transmitter microcontroller, go to the schematic and double click on the transmitter microcontroller to bring up its properties window. Then click on the folder icon and browse for the transmit.hex file and click ok to exit the window.

buring hex file in proteus 8

Now the transmitter microcontroller is ready for simulation.

Repeat the same steps for the receiver microcontroller by starting by creating a new MpLAB project, adding the same files, copying and pasting the receiver assembly code provided below, compiling and creating a receive.hex file and lastly uploading the hex file to the receiver microcontroller.

Receiver Microcontroller Source Code:

;=========================
; setup and configuration
;=========================
    processor 16f84A
    include      <p16f84A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;============================================================
;                        M A C R O S
;============================================================
; Macros to select the register banks
Bank0    MACRO            ; Select RAM bank 0
        bcf        STATUS,RP0
        ENDM

Bank1    MACRO            ; Select RAM bank 1
        bsf        STATUS,RP0
        ENDM
;=====================================================
;          constant definitions for pin wiring
;=====================================================
#define readySW  2  ;|
#define readyLED 3    ;| -- from wiring diagram
#define serialLN 0    ;|
;=====================================================
;            PIC register and flag equates
;=====================================================
c        equ        0        ; Carry flag
tmrOVF    equ        2        ; Timer overflow bit
;
;======================================================
;              variables in PIC RAM
;=====================================================
    cblock    0x0c    ; Start of block
    bitCount        ; Counter for 8 bits
    rcvReg            ; Data to send
    temp
    endc
;=========================================================
;                           program
;=========================================================
    org    0      ; start at address
    goto    main
; Space for interrupt handlers
    org    0x04

main:
    Bank1
; Port A bits 0 and 2 are input. All others are output
    movlw    b'00000101' ; port A setup
    movwf    TRISA
; Port B is all output
    movlw    b'00000000' ; port B setup
    MOVWF    TRISB
    Bank0
; Turn off all port B LEDs
    clrf    PORTB
; And receiver register
    clrf    rcvReg
; Prepare to set prescaler
    clrf    TMR0
    clrwdt
; Setup OPTION register for full timer speed
    movlw    b'11011000'
;   1  1  0  1  1  0  0  0 <= OPTION bits
;   |  |  |  |  |  |__|__|_____ PS2-PS0 (prescaler bits)
;   |  |  |  |  |               Values for Timer0
;   |  |  |  |  |              *000 = 1:2   001 = 1:4
;   |  |  |  |  |               010 = 1:8   011 = 1:16
;   |  |  |  |  |               100 = 1:32  101 = 1:64
;   |  |  |  |  |               110 = 1:128 111 = 1:256
;   |  |  |  |  |______________ PSA (prescaler assign)
;   |  |  |  |                 *1 = to WDT
;   |  |  |  |                  0 = to Timer0
;   |  |  |  |_________________ TOSE (Timer0 edge select)
;   |  |  |                     0 = increment on low-to-high
;   |  |  |                    *1 = increment in high-to-low
;   |  |  |____________________ TOCS (TMR0 clock source)
;   |  |                       *0 = internal clock
;   |  |                        1 = RA4/TOCKI bit source
;   |  |_______________________ INTEDG (Edge select)
;   |                           0 = falling edge
;   |                          *1 = raising edge
;   |__________________________ RBPU pullups
;                               0 = enabled
;                              *1 = dissabled
    option
; Dissable interrupts
    bcf        INTCON,5   ; Timer0 overflow dissabled
    bcf        INTCON,7   ; Global interupts dissabled
;=========================
;  wait for READY switch
;     to be pressed
;=========================
ready2rcv:
    btfsc    PORTA,readySW    ; Test switch
    goto    ready2rcv        ; loop
; Turn ON the ready-to-receive LED
    bsf        PORTA,readyLED
;===========================
;        receiving
;===========================
    call    rcvData        ; Call serial input procedure
;===========================
;       data received
;===========================
; Turn ready to receive LED off
    bcf        PORTA,readyLED
; Display received data
    movf    rcvReg,w    ; Byte received to w
    movwf    PORTB        ; display in port B
;===========================
;      wait forever
;===========================
endloop:
    goto    endloop
;============================================================
;               procedure to receive serial data
;============================================================
; ON ENTRY:
;         local variable dataReg is used to store 8-bit value
;         received through port (labeled serialLN)
; OPERATION:
;      1. The timer at register TMR0 is set to run at
;         maximum clock speed, that is, 256 clock beats.
;         The timer overflow flag in the INTCON register
;         is set when the timer cycles from 0xff to 0x00.
;      2. When the START signal is received, the code
;         waits for 128 timer beats so as to read data in
;         the middle of the send period.
;      3. Each bit (start, data, and stop bits) is read
;         at intervals of 256 timer beats.
;      4. The procedure tests the timer ofverflow flag
;         (tmrOVF) to determine when the timer cycle has
;         ended, that is when 256 clock beats have passed.

;------------------------------------------------------------
rcvData:
    clrf    TMR0    ; Reset timer
    movlw    0x08    ; Initialize bit counter
    movwf    bitCount
;=========================
;   wait for START bit
;=========================
startWait:
    btfsc    PORTA,0        ; Is port A0 low?
    goto    startWait    ; No. Wait for mark
;=========================
;  offset 128 clock beats
;=========================
; At this point the receiver has found the falling
; edge of the start bit. It must now wait 128 timer
; beats to synchronize in the middle of the sender's
; data rate, as follows:
;             |<========= falling edge of START bit
;             |
;             |-----|<====== 128 clock beats offset
;   ----------.     |     .---------
;             |           |  <== SIGNAL
;              -----------
;             |<-- 256 -->|
;
    movlw    0x80        ; 128 clock beats offset
    movwf    TMR0        ; to TMR0 counter
    bcf        INTCON,tmrOVF    ; Clear overflow flag
offsetWait:
    btfss    INTCON,tmrOVF   ; timer overflow?
    goto    offsetWait        ; wait until
    btfsc    PORTA,0            ; Test start bit for error
    goto    offsetWait        ; Recycle if a false start
;==========================
;      receive data
;==========================
    clrf    TMR0        ; Restart timer
    bcf        INTCON,tmrOVF    ; Clear overflow flag
; Wait for 256 timer cycles for first/next data bit
bitWait:
    btfss    INTCON,tmrOVF  ; Timer cycle end?
    goto    bitWait            ; Keep waiting
; Timer has counter 256 beats
    bcf        INTCON,tmrOVF    ; Reset overflow flag
    movf    PORTA,w            ; Read port A into w
    movwf    temp            ; Store value read
    rrf        temp,f            ; Rotate bit 0 into carry flag
    rlf        rcvReg,f           ; Rotate carry into rcvReg bit 0
    decfsz    bitCount,f        ; 8 bits received
    goto    bitWait            ; Next bit
; Wait for one time cycle at end of reception
markWait:
    btfss    INTCON,tmrOVF    ; timer overflow flag
    goto    markWait        ; keep waiting
;========================
;   end of reception
;========================
    return

;=========================================================
;                       end of program
;=========================================================
    end

    Tidak ada komentar:

    Posting Komentar