Senin, 15 Oktober 2012

Proteus Microcontroller Tutorial on LCD display

This tutorial is about the programming of PIC16F84A microcontroller and LCD driven by Hitachi HD44780 LCD controller for real time simulation to display character onto the display.

The way this whole works is that an assembly program is written and then burned into the PIC microcontroller and the program directs and control the smaller LCD hardware controller HD44780. That is HD44780 is in itself a primitive machine that has its own instruction set, memory, timing and display control circuit. In order to correctly control the LCD display it is necessary to have knowledge about the functions it supports, the initialization it requires such as font size, duty cycle, 8 or 4 pin interface width, diplay on/off, cursor on/off, character shift etc, ports and pins, the size and types of memory and working of the LCD controller.

The program starts by defining constants and variables required for routines and allocating memory space for text data to be displayed. The ports type(whether inputs or outputs) of the PIC microcontroller are defined. The next step is the initialization of the LCD, that is setting up the font size, the 8 or 4 interface width, display, cursor and shift of character. Then the last step is the generation of text and transfer of text to buffer in PIC microcontroller and then finally the transfer from buffer to the DDRAM of the LCD controller which is then displayed. This transfer and display requires sending commands to the controller.

The schematic diagram that shows the interfacing between the microcontroller and the LCD controller is shown below-

Proteus Microcontroller Tutorial on LCD display

The part that has been used here are-
  •  9C08052A1002FKHFT
  • BUTTON
  • CRYSTAL
  • ERA-3YEB101V
  • LM016L
  • PIC16F84A
 The source code is provided below. To use this source code, simply double click on the microcontroller and select edit firmware option. Then copy paste the below source code. Compile it by clicking on the build icon as shown in figure and you should see compiled successfully(perhaps with minor warning which can just be ignored).

Proteus Microcontroller Tutorial on LCD display

 To run the simulation, go back to the schematic and click on the Run icon.

Proteus Microcontroller Tutorial on LCD display
Source Code:; Processor: 16F84A
;
; Description:
; Program to exercises 8-bit PIC-to-LCD interface.
; Code assumes that LCD is driven by Hitachi HD44780
; controller and that the display supports two lines
; each one with 16 characters. The wiring and base
; address of each display line is stored in #define
; statements. These statements can be edited to
; accomodate a different set-up.
; Program uses delay loops for interface timing.
; WARNING:
; Code assumes 4Mhz clock. Delay routines must be
; edited for faster clock

; Displays: Minnesota State, Mankato
;
;===========================
;        switches
;===========================
; Switches used in __config directive:
;   _CP_ON          Code protection ON/OFF    
; * _CP_OFF     
; * _PWRTE_ON     Power-up timer ON/OFF
;   _PWRTE_OFF    
;   _WDT_ON       Watchdog timer ON/OFF 
; * _WDT_OFF      
;   _LP_OSC       Low power crystal occilator
; * _XT_OSC       External parallel resonator/crystal ocillator 
;   _HS_OSC       High speed crystal resonator (8 to 10 MHz)
;                 Resonator: Murate Erie CSA8.00MG = 8 MHz  
;   _RC_OSC       Resistor/capacitor ocillator (simplest, 20% error)
; |
; |_____ * indicates setup values

;=========================
; setup and configuration
;=========================
    processor 16f84A
    include      <p16f84A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;=====================================================
;                 constant definitions
;  for PIC-to-LCD pin wiring and LCD line addresses
;=====================================================
#define E_line 1       ;|
#define RS_line 2    ;| -- from wiring diagram
#define RW_line 3    ;|
; LCD line addresses (from LCD data sheet)
#define LCD_1 0x80    ; First LCD line constant
#define LCD_2 0xc0    ; Second LCD line constant
; Note: The constant that define the LCD display line
;       addresses have the high-order bit set in
;       order to faciliate the controller command
;
;=====================================================
;              variables in PIC RAM
;=====================================================
; Reserve 16 bytes for string buffer
    cblock    0x0c
    strData
    endc
; Leave 16 bytes and Continue with local variables
    cblock    0x1d        ; Start of block
    count1        ; Counter # 1
    count2        ; Counter # 2
    count3        ; Counter # 3
    pic_ad        ; Storage for start of text area
                ; (labeled strData) in PIC RAM
    J            ; counter J
    K            ; counter K
    index        ; Index into text table (also used
                ; for auxiliary storage)
    endc

;============================================================
;                           program
;============================================================
        org        0      ; start at address
        goto    main
; Space for interrupt handlers
    org        0x08

main:
    movlw    b'00000000' ; All lines to output
    tris    PORTA        ; in port A
    tris    PORTB        ; and port B
    movlw    b'00000000' ; All outputs ports low
    movwf    PORTA
    movwf    PORTB
; Wait and initialize HD44780
    call    delay_5ms        ; Allow LCD time to initialize itself
    call    initLCD        ; Then do forced initialization
    call    delay_5ms        ; (Wait probably not necessary)
; Store base address of text buffer in PIC RAM
    movlw    0x0c        ; Start address of text buffer
    movwf    pic_ad        ; to local variable
;======================
;   first LCD line
;======================
; Store 16 blanks in PIC RAM, starting at address stored
; in variable pic_ad
    call    blank16
; Call procedure to store ASCII characters for message
; in text buffer
    movlw    d'3'        ; Offset into buffer
    call    storeMN
; Set DDRAM address to start of first line
    call     line1
; Call procedure to display 16 characters in LCD
    call    display16
;========================
;   second LCD line
;========================
    call    delay_125mcs    ; Wait for termination
    call    blank16        ; Blank buffer
; Call procedure to store ASCII characters for message
; in text buffer
    movlw    d'1'        ; Offset into buffer
    call    storeUniv
    call    line2        ; DDRAM address of LCD line 2
    call    display16
;=======================
;       done!
;=======================
loopHere:
    goto    loopHere  ;done

;************************************************************
;                  INITIALIZE LCD PROCEDURE
;************************************************************
initLCD
; Initialization for Densitron LCD module as follows:
;    8-bit interface
;   2 display lines of 16 characters each
;   cursor on
;   left-to-right increment
;   cursor shift right
;   no display shift
;***********************|
;     COMMAND MODE      |
;***********************|
    bcf        PORTA,E_line    ; E line low
    bcf        PORTA,RS_line    ; RS line low for command
    bcf        PORTA,RW_line   ; Write mode
    call    delay_125mcs        ;delay 125 microseconds
;***********************|
;     FUNCTION SET      |
;***********************|
    movlw    0x38    ; 0 0 1 1 1 0 0 0 (FUNCTION SET)
                    ;     | | | |__ font select:
                    ;     | | |    1 = 5x10 in 1/8 or 1/11 dc
                    ;     | | |    0 = 1/16 dc
                    ;     | | |___ Duty cycle select
                    ;     | |      0 = 1/8 or 1/11
                    ;     | |      1 = 1/16 (multiple lines)
                    ;     | |___ Interface width
                    ;     |      0 = 4 bits
                    ;     |      1 = 8 bits
                    ;     |___ FUNCTION SET COMMAND
    movwf    PORTB    ;0011 1000
    call    pulseE    ;pulseE and delay

;***********************|
;    DISPLAY OFF        |
;***********************|
    movlw    0x08    ; 0 0 0 0 1 0 0 0 (DISPLAY ON/OFF)
                    ;         | | | |___ Blink character at cursor
                    ;         | | |      1 = on, 0 = off
                    ;         | | |___ Curson on/off
                    ;         | |      1 = on, 0 = off
                    ;         | |____ Display on/off
                    ;         |       1 = on, 0 = off
                    ;         |____ COMMAND BIT

    movwf    PORTB
    call    pulseE    ;pulseE and delay

;***********************|
; DISPLAY AND CURSOR ON |
;***********************|
    movlw    0x0e    ; 0 0 0 0 1 1 1 0 (DISPLAY ON/OFF)
                    ;         | | | |___ Blink character at cursor
                    ;         | | |      1 = on, 0 = off
                    ;         | | |___ Curson on/off
                    ;         | |      1 = on, 0 = off
                    ;         | |____ Display on/off
                    ;         |       1 = on, 0 = off
                    ;         |____ COMMAND BIT
    movwf    PORTB
    call    pulseE    ;pulseE and delay

;***********************|
;    ENTRY MODE SET     |
;***********************|
    movlw    0x06    ; 0 0 0 0 0 1 1 0 (ENTRY MODE SET)
                    ;           | | |___ display shift
                    ;           | |      1 = shift
                    ;           | |      0 = no shift
                    ;           | |____ cursor increment mode
                    ;           |       1 = left-to-right
                    ;           |       0 = right-to-left
                    ;           |___ COMMAND BIT
    movwf    PORTB    ;00000110
    call    pulseE

;***********************|
; CURSOR/DISPLAY SHIFT  |
;***********************|
    movlw    0x14    ; 0 0 0 1 0 1 0 0 (CURSOR/DISPLAY SHIFT)
                       ;       | | | |_|___ don't care
                    ;       | |_|__ cursor/display shift
                    ;       |       00 = cursor shift left
                    ;       |       01 = cursor shift right
                    ;       |       10 = cursor and display
                    ;       |            shifted left
                    ;       |       11 = cursor and display
                    ;       |            shifted right
                    ;       |___ COMMAND BIT
    movwf    PORTB    ;0001 1111
    call    pulseE

;***********************|
;   CLEAR DISPLAY       |
;***********************|
    movlw    0x01    ; 0 0 0 0 0 0 0 1 (CLEAR DISPLAY)
                    ;               |___ COMMAND BIT
    movwf    PORTB    ;0000 0001
;
    call    pulseE
    call    delay_5ms    ;delay 5 milliseconds after init
    return
;************************************************************
;               DELAY AND PULSE PROCEDURES
;************************************************************
;=======================
;  Procedure to delay
;   42 microseconds
;=======================
delay_125mcs
    movlw    D'42'            ; Repeat 42 machine cycles
    movwf    count1            ; Store value in counter
repeat
    decfsz    count1,f           ; Decrement counter
    goto    repeat            ; Continue if not 0
    return                    ; End of delay   
;------------------------------------------------------------
;=======================
;  Procedure to delay
;   5 milliseconds
;=======================
delay_5ms
    movlw    D'41'            ; Counter = 41
    movwf    count2            ; Store in variable
delay
    call    delay_125mcs        ; Delay
    decfsz    count2,f        ; 40 times = 5 milliseconds
    goto    delay
    return                ; End of delay
;========================
;     pulse E line
;========================
pulseE
    bsf        PORTA,E_line    ;pulse E line
    bcf        PORTA,E_line
    call    delay_125mcs        ;delay 125 microseconds
    return

;=============================
;   long delay sub-routine
;     (for debugging)
;=============================
long_delay
        movlw    D'200'    ; w = 200 decimal
        movwf    J        ; J = w
jloop:    movwf    K        ; K = w
kloop:    decfsz    K,f        ; K = K-1, skip next if zero
        goto     kloop
        decfsz    J,f        ; J = J-1, skip next if zero
        goto    jloop
        return
;=============================
;   LCD display procedure
;=============================
; Sends 16 characters from PIC buffer with address stored
; in variable pic_ad to LCD line previously selected
display16:
; Set up for data
    bcf        PORTA,E_line    ; E line low
    bsf        PORTA,RS_line    ; RS line low for control
    call    delay_125mcs        ; Delay
; Set up counter for 16 characters
    movlw    D'16'            ; Counter = 16
    movwf    count3   
; Get display address from local variable pic_ad
    movf    pic_ad,w        ; First display RAM address to W
    movwf    FSR                ; W to FSR
getchar:
    movf    INDF,w            ; get character from display RAM
                            ; location pointed to by file select
                            ; register
    movwf    PORTB
    call    pulseE    ;send data to display   
; Test for 16 characters displayed
    decfsz    count3,f          ; Decrement counter
    goto    nextchar        ; Skipped if done
    return
nextchar:
    incf    FSR,f            ; Bump pointer
    goto    getchar
;========================
;     blank buffer
;========================
; Procedure to store 16 blank characters in PIC RAM
; buffer starting at address stored in the variable
; pic_ad
blank16:
    movlw    D'16'        ; Setup counter
    movwf    count1
    movf    pic_ad,w    ; First PIC RAM address
    movwf    FSR            ; Indexed addressing
    movlw    0x20        ; ASCII space character
storeit:
    movwf    INDF        ; Store blank character in PIC RAM
                        ; buffer using FSR register
    decfsz    count1,f      ; Done?
    goto    incfsr        ; no
    return                ; yes
incfsr:
    incf    FSR,f        ; Bump FSR to next buffer space
    goto    storeit

;========================
; Set address register
;    to LCD line 1
;========================
; ON ENTRY:
;         Address of LCD line 1 in constant LCD_1
line1:
    bcf        PORTA,E_line     ; E line low
    bcf        PORTA,RS_line    ; RS line low, set up for control
    call    delay_125mcs        ; delay 125 microseconds
; Set to second display line
    movlw    LCD_1            ; Address and command bit
    movwf    PORTB
    call    pulseE            ; Pulse and delay
; Set RS line for data
    bsf        PORTA,RS_line    ; Setup for data
    call    delay_125mcs        ; Delay
    return
;========================
; Set address register
;    to LCD line 2
;========================
; ON ENTRY:
;         Address of LCD line 2 in constant LCD_2
line2:
    bcf        PORTA,E_line    ; E line low
    bcf        PORTA,RS_line    ; RS line low, setup for control
    call    delay_125mcs        ; delay
; Set to second display line
    movlw    LCD_2            ; Address with high-bit set
    movwf    PORTB
    call    pulseE            ; Pulse and delay
; Set RS line for data
    bsf        PORTA,RS_line    ; RS = 1 for data
    call    delay_125mcs        ; delay
    return

;===============================
;  first text string procedure
;===============================
storeMN:
; Procedure to store in PIC RAM buffer the message
; contained in the code area labeled msg1
; ON ENTRY:
;         variable pic_ad holds address of text buffer
;         in PIC RAM
;         w register hold offset into storage area
;         msg1 is routine that returns the string characters
;         an a zero terminator
;         index is local variable that hold offset into
;         text table. This variable is also used for
;         temporary storage of offset into buffer
; ON EXIT:
;         Text message stored in buffer
;
; Store offset into text buffer (passed in the w register)
; in temporary variable
    movwf    index        ; Store w in index
; Store base address of text buffer in FSR
    movf    pic_ad,w    ; first display RAM address to W
    addwf    index,w        ; Add offset to address
    movwf    FSR            ; W to FSR
; Initialize index for text string access
    movlw    0            ; Start at 0
    movwf    index        ; Store index in variable
; w still = 0
get_msg_char:
    call    msg1        ; Get character from table
; Test for zero terminator
    andlw    0x0ff
    btfsc    STATUS,Z    ; Test zero flag
    goto    endstr1        ; End of string
; ASSERT: valid string character in w
;         store character in text buffer (by FSR)
    movwf    INDF        ; store in buffer by FSR
    incf    FSR,f        ; increment buffer pointer
; Restore table character counter from variable
    movf    index,w        ; Get value into w
    addlw    1            ; Bump to next character
    movwf    index        ; Store table index in variable
    goto    get_msg_char    ; Continue   
endstr1:
    return

; Routine for returning message stored in program area
msg1:
    addwf    PCL,f        ; Access table
    retlw    'M'
    retlw    'i'
    retlw    'n'
    retlw    'n'
    retlw    'e'
    retlw    's'
    retlw    'o'
    retlw    't'
    retlw    'a'
    retlw    0

;=================================
;   second text string procedure
;=================================
storeUniv:
; Processing identical to procedure StoreMSU
    movwf    index        ; Store w in index
; Store base address of text buffer in FSR
    movf    pic_ad,0    ; first display RAM address to W
    addwf    index,0        ; Add offset to address
    movwf    FSR            ; W to FSR
; Initialize index for text string access
    movlw    0            ; Start at 0
    movwf    index        ; Store index in variable
; w still = 0
get_msg_char2:
    call    msg2        ; Get character from table
; Test for zero terminator
    andlw    0x0ff
    btfsc    STATUS,Z    ; Test zero flag
    goto    endstr2        ; End of string
; ASSERT: valid string character in w
;         store character in text buffer (by FSR)
    movwf    INDF        ; Store in buffer by FSR
    incf    FSR,f        ; Increment buffer pointer
; Restore table character counter from variable
    movf    index,w        ; Get value into w
    addlw    1            ; Bump to next character
    movwf    index        ; Store table index in variable
    goto    get_msg_char2    ; Continue   
endstr2:
    return

; Routine for returning message stored in program area
msg2:
    addwf    PCL,f        ; Access table
    retlw    'S'
    retlw    't'
    retlw    'a'
    retlw    't'
    retlw    'e'
    retlw    ','
    retlw    0x20
    retlw    'M'
    retlw    'a'
    retlw    'n'
    retlw    'k'
    retlw    'a'
    retlw    't'
    retlw    'o'
    retlw    0

    end






Sabtu, 06 Oktober 2012

PIC16F877A Microcontroller Tutorial using Proteus

In this post, a 7 segment display controlled by PIC16F877A microcontroller simulation in Proteus 8 will be shown.

The schematic for using PIC16F877A to produce characters on a 7 segment display is shown below-

PIC16F877A Microcontroller Tutorial using Proteus


 The parts that are used are-
  • PIC16F877A microcontroller
  • 7SEG-COM-CAT-Blue
  • 9C04021A2200FLHF3(220 ohm resistor)
  • 9C08052A1002JLHFT(10k ohm resistor)
  • BUTTON
  • CRYSTAL
  • DIPSW_4
  • SOUNDER
 The assembly source code is below-

;=========================
; setup and configuration
;=========================
    processor 16f877A
    include      <p16f877A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _LVP_OFF

#define Pb_sw  4    ; Port A line 4 to push button switch

porta    equ    0x05
portb   equ     0x06
;============================
;      local variables
;============================
    cblock    0x20        ; Start of block
    J                ; counter J
    K                ; counter K
    endc
;============================================================
;                           program
;============================================================
    org    0      ; start at address 0
    goto    main
;
; Space for interrupt handlers
    org        0x08

main:
    bsf STATUS,RP0
; Port A. Five low-order lines set for for input
    movlw    B'00011111'    ; w = 00011111 binary
    movwf    TRISA        ; port A (lines 0 to 4) to input
; Port B. All eight lines for output
    movlw    B'00000000'    ; w := 00000000 binary
    movwf    TRISB        ; port B to output
    movlw    0x6
    movwf    ADCON1
    bcf        STATUS,RP0
;===============================
; Pushbutton switch processing
;===============================
pbutton:
; Push button switch on demo board is wired to port A bit 4
; Switch logic is active low
    btfss    PORTA,Pb_sw    ; Test and skip if switch bit set
    goto    buzzit        ; Buz if switch ON,
; At this point port A bit 4 is set (switch is off)
    call    buzoff        ; Buzzer off
    goto    readdip        ; Read DIP switches
buzzit:
    call    buzon        ; Turn on buzzer
    goto    pbutton
;============================
;   dip switch monitoring
;============================
readdip:
; Read port A switches
    movf    PORTA,w        ; Port A bits to w
; Since board is wired active low then all switch bits
; must be negated.  This is done by XORing with 1-bits
    xorlw    b'11111111'    ; Invert all bits in w
; Mask off 4 high-order bits
    andlw    b'00001111'        ; And with mask
; At this point the w register contains a 4-bit value
; in the range 0 to 0xf. Use this value (in w) to
; obtain seven-segment display code
    call    segment
    movwf    PORTB        ; Display switch bits
    goto    pbutton
;================================
;  routine to returns 7-segment
;             codes
;================================
segment:
        addwf    PCL,f    ; PCL is program counter latch
        retlw    0x3f    ; 0 code
        retlw    0x06    ; 1
        retlw    0x5b    ; 2
        retlw    0x4f    ; 3
        retlw    0x66    ; 4
        retlw    0x6d    ; 5
        retlw    0x7d    ; 6
        retlw    0x07    ; 7
        retlw    0x7f    ; 8
        retlw    0x6f    ; 9
        retlw    0x77    ; A
        retlw    0x7c    ; B
        retlw    0x39    ; C
        retlw    0x5b    ; D
        retlw    0x79    ; E
        retlw    0x71    ; F
        retlw    0x7f    ; Just in case all on

;============================
;   piezo buzzer ON
;============================
; Routine to turn on piezo buzzer on port B bit 7
buzon:
        bsf        PORTB,7        ; Tune on bit 7, port B
        return   
;
;============================
;   piezo buzzer OFF
;============================
; Routine to turn off piezo buzzer on port B bit 7
buzoff:
        bcf        PORTB,7        ; Bit 7 port b clear
        return
;=============================
;   long delay sub-routine
;    (for code testing)
;=============================
long_delay
        movlw    D'200'    ; w = 200 decimal
        movwf    J        ; J = w
jloop:    movwf    K        ; K = w
kloop:    decfsz    K,f        ; K = K-1, skip next if zero
        goto     kloop
        decfsz    J,f        ; J = J-1, skip next if zero
        goto    jloop
        return       

        end   

-------------------------------------------------------------------------

It's easy to use this assembly code as the firmware code for the 16F877A micro-controller. Double click on the microcontroller and you can see "Edit Firmware" option. Click on that and copy/paste the above code into the firmware source editor.

PIC16F877A Microcontroller Tutorial using Proteus




Then click on the Build Project icon to compile the assembly code into Hex code(firmware). You should see Complied Successfully output message with minor warning.

PIC16F877A Microcontroller Tutorial using Proteus

Now go back to schematic and click on RUN to run the simulation. You can change the character to be displayed by turning ON/OFF the 4 Dip switch. And you can hear sound when you click on the push button.

PIC16F877A Microcontroller Tutorial using Proteus


If you require proteus, see the proteus software download post. See more microcontroller tutorials.

Kamis, 04 Oktober 2012

Proteus Microcontroller Project

This Proteus simulation shows alphanumeric character on a 7 segment display using a PIC16F84A micro-controller.

The schematic diagram is shown below-


The components used in the schematic are-
  • 7SEG-COM-CAT-BLUE(7 segment display)
  • 9C04021A2200FLHF3(200 ohm resistor)
  • 9C08052A1002FKHFT(10k ohm resistor)
  • BUTTON
  • CRYSTAL
  • DIPSW_4(switch 4 ports)
  • SOUNDER
  • PIC16F84A(Microcontroller)
 Connect the parts as shown in the schematic. The crystal is connected across the pin 15 and 16. The MCLR is a active low pin for reset which is connected to the +5V source with a 10k ohm series resistor. The microcontroller PIC16F84A has a two I/O ports- port A and port B. Port A will be configured as an input port and the port B will be the output port. The output signal from port B will be connected to the 7 segment display.

The microcontroller is programmed in assembly language, compiled into hex code and this hex code is burned into the microcontroller in Proteus. But first the program. The assembly program code is below-


;=========================
; setup and configuration
;=========================
    processor 16f84A
    include      <p16f84A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

#define Pb_sw  4    ; Port A line 4 to push button switch

porta    equ    0x05
portb   equ     0x06
;============================
;      local variables
;============================
    cblock    0x0c        ; Start of block
    J                ; counter J
    K                ; counter K
    endc
;============================================================
;                           program
;============================================================
    org    0      ; start at address 0
    goto    main
;
; Space for interrupt handlers
    org        0x08

main:
; Port A. Five low-order lines set for for input
    movlw    B'00011111'    ; w = 00011111 binary
    tris    porta        ; port A (lines 0 to 4) to input
; Port B. All eight lines for output
    movlw    B'00000000'    ; w := 00000000 binary
    tris    portb        ; port B to output
;===============================
; Pushbutton switch processing
;===============================
pbutton:
; Push button switch on demo board is wired to port A bit 4
; Switch logic is active low
    btfss    porta,Pb_sw    ; Test and skip if switch bit set
    goto    buzzit        ; Buz if switch ON,
; At this point port A bit 4 is set (switch is off)
    call    buzoff        ; Buzzer off
    goto    readdip        ; Read DIP switches
buzzit:
    call    buzon        ; Turn on buzzer
    goto    pbutton
;============================
;   dip switch monitoring
;============================
readdip:
; Read port A switches
    movf    porta,w        ; Port A bits to w
; Since board is wired active low then all switch bits
; must be negated.  This is done by XORing with 1-bits
    xorlw    b'11111111'    ; Invert all bits in w
; Mask off 4 high-order bits
    andlw    b'00001111'        ; And with mask
; At this point the w register contains a 4-bit value
; in the range 0 to 0xf. Use this value (in w) to
; obtain seven-segment display code
    call    segment
    movwf    portb        ; Display switch bits
    goto    pbutton
;================================
;  routine to returns 7-segment
;             codes
;================================
segment:
        addwf    PCL,f    ; PCL is program counter latch
        retlw    0x3f    ; 0 code
        retlw    0x06    ; 1
        retlw    0x5b    ; 2
        retlw    0x4f    ; 3
        retlw    0x66    ; 4
        retlw    0x6d    ; 5
        retlw    0x7d    ; 6
        retlw    0x07    ; 7
        retlw    0x7f    ; 8
        retlw    0x6f    ; 9
        retlw    0x77    ; A
        retlw    0x7c    ; B
        retlw    0x39    ; C
        retlw    0x5b    ; D
        retlw    0x79    ; E
        retlw    0x71    ; F
        retlw    0x7f    ; Just in case all on

;============================
;   piezo buzzer ON
;============================
; Routine to turn on piezo buzzer on port B bit 7
buzon:
        bsf        portb,7        ; Tune on bit 7, port B
        return   
;
;============================
;   piezo buzzer OFF
;============================
; Routine to turn off piezo buzzer on port B bit 7
buzoff:
        bcf        portb,7        ; Bit 7 port b clear
        return
;=============================
;   long delay sub-routine
;    (for code testing)
;=============================
long_delay
        movlw    D'200'    ; w = 200 decimal
        movwf    J        ; J = w
jloop:    movwf    K        ; K = w
kloop:    decfsz    K,f        ; K = K-1, skip next if zero
        goto     kloop
        decfsz    J,f        ; J = J-1, skip next if zero
        goto    jloop
        return       

        end

-------------------------------------------------------------------------------------------------------------

Copy the code and double click on the PIC16F84A microcontroller and then click on edit firmware and paste into the source editor.

7 segment proteus simulation





Then click on the build project icon to compile the .asm file into hex source code.

7 segment proteus simulation
7 segment proteus simulation



The VMS output should show "Compiled Successfully" as shown below-

7 segment proteus simulation
Now come back to the schematic diagram and run the simulation-

7 segment proteus simulation




By toggling ON/OFF the 4 DIP switch button the characters in the 7 segment will change.

7 segment proteus simulation

Also by pressing the button we will hear a tone from the SOUND part-

7 segment proteus simulation

Minggu, 30 September 2012

Microcontroller with single LED Project in Proteus

This is a simulation project that shows how to write program in assembly language for PIC16F84A microcontroller that turns on a single LED and use it in Proteus VSM to stimulate the working of the microcontroller controlled LED.

To do this start by creating a new project in Proteus, give some name and save it to some folder.

Microcontroller with single LED Project in Proteus
Click Next. We require a schematic so select Create a schematic from the selected template and choose default or any size you want.

Click Next. We do not require a PCB so select Do not create a PCB layout and click next again.

We do require a Firmware so select Create a Firmware Project and select PIC16 as Family, PIC16F84A as Controller, MPASM(MPLAB) as the Compiler.

Microcontroller with single LED Project in Proteus

Clicking next will bring up the source code editor window and the schematic window. Go to the Schematic and add the following components-
  • 9C04021A3300FLHF3 (330ohm resistor)
  • 9C08052A1002JLHFT (10K ohm resistor)
  • CRYSTAL
  • LED-GREEN
The PIC16F84A micro-controller is already added so no need to add that part.

Microcontroller with single LED Project in Proteus

Draw the schematic as shown-

Microcontroller with single LED Project in Proteus

Click on the VCC power and change it to +5V

Now switch over to the Source Code by clicking on the Source Code tab. The Source code editor shows a default template. Delete the template code and Copy the following code below into it.
----------------------------------------------------------------------------------------------------------------------
    processor 16f84A
    include      <p16f84A.inc>
    __config  _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

    org    0      ; start at address 0
    goto    main
;=============================
; space for interrupt handler
;=============================
    org        0x04
;=============================
;       main program
;=============================
main:
; Initialize all line in port B for output
    movlw    B'00000000'    ; w = 00000000 binary
    tris    PORTB        ; Set up port B for output
; Turn on line 0 in port B. All others remain off
    movlw    B'00000001'
                    
    movwf    PORTB
; Endless loop intentionally hangs up program
wait:
    goto    wait

        end   
-------------------------------------------------------------------------------------------------------------------------

Code Explanation

The part "processor 16f84A" tells which microcontroller is being used. The "include  <p16f84A.inc>" part is a directive that tell to use the p16f84A microcontroller include file. The __config directive specifies various configuration aspect of the microcontroller such as the type of the oscillator, whether watch dog timer is on or off, whether the Power-Up timer is on or off and code protection is on/off. Then Org 0 tells the assembler to assemble all subsequent code starting at address 0. The next instruction it reads is the main so the program control goes to main. The instruction movlw    B'00000000' tells to load working register with 000000000. The instruction tris    PORTB tells to make the Port B direction as output. Then the sequence of instruction movlw    B'00000001' and movwf PORTB directs to turn on the line 0 of the Port B.

Microcontroller with single LED Project in Proteus
Go to Build>Build Project or click on the Build icon in the toolbar.

Microcontroller with single LED Project in Proteus
If everything is right then the VMS output should show Compiled Successfully as shown-

Microcontroller with single LED Project in Proteus
Go back to the Schematic and click on the PIC16F84A to open its properties. Check that the debug.cof is selected as this is the file that will be used for simulation of the microcontroller.

Microcontroller with single LED Project in Proteus

Click OK and go back to the schematic and run the simulation.

Microcontroller with single LED Project in Proteus

Thats it. The LED is now turned on.

For more tutorials visit Proteus Professional Tutorials

Minggu, 23 September 2012

Create Component Faster in Altium Designer

It is really frustrating when one has to spend hours on creating schematic symbols and footprints for parts rather than doing the real design part. It can take hours to build the library and symbol for schematic and footprints. It is especially time consuming to build for component for large number of pins.

This video tutorial shows how designers can use altium designer Smart Grid Tool and IPC Footprint Wizard to quicker build the schematic symbol and footprint and compile them into integrated library.

Here in this video, schematic symbol and footprint for NRF2401A  single chip 2.4GHz transceiver will be build.


For more tutorials visit video tutorial collection and Altium Designer Tutorials

Sabtu, 22 September 2012

How to change Font size in Altium designer PCB

When PCB designs are imported from other PCB design software such as eagle, the top overlay text are much bigger than normal. In such case the text must be re-sized. This short tutorial shows how to resize all the text to suitable size in Altium designer PCB.

Below you can see an example of a PCB design that was imported to Altium designer which has abnormal text size.

change Font size in Altium designer PCB

As you can see the yellow colored texts are not readable. To change the size of the text, you can select the PCB tab option at the bottom right corner and then select the PCB List as shown-

change Font size in Altium designer PCB




This brings up the PCB List panel. Here we can select all the Text in the PCB and then set text size all at once. To do this, click on the "all types of objects" then select Display only option and then select Text as shown-

change Font size in Altium designer PCB

The PCB List will then contain only the Text as object in the list.

change Font size in Altium designer PCB




To change the Height and width of the text, navigate to the right side until you see the Text Height and Text Width column as shown-

change Font size in Altium designer PCB


The Text Height is 16mils and the text width is 10mils. We will change the height from 16mils to 10 mils and width from 10 mils to 3 mils. To to this, select the first entry(16) in the Height column, then right click and select the "Select Column(s)" option.

change Font size in Altium designer PCB

Right click the first entry and select "Edit" and change the number from 16 to 10 as shown-

change Font size in Altium designer PCB

Hit enter to make the change. Now all texts have a height of 10mils.

change Font size in Altium designer PCB
Follow the same steps for the width as for the height to change the width from 10 mils to 3 mils.

change Font size in Altium designer PCB
Now if we Zoom in to the PCB we can now clearly understand the yellow overlay text-

change Font size in Altium designer PCB

This completes the tutorial.


Locating components/parts/nets between schematic and PCB

Often during the schematic and PCB layout design and during study of electronic system one requires to know and locate part/wires from schematic in PCB or vice versa. This is especially required in highly dense and complex schematic/pcb work. 

Altium designer has many options available to see and locate components and connection back and forth between the schematic and PCB. One of them is the cross probing tool.

Below shows a typical schematic and its PCB layout-


Now suppose we want to see the oscillator in the PCB. It is quite difficult to locate the oscillator in the PCB because the PCB is simply dense with different components of various sizes filling up the PCB and because of the different color assignment to different layers, pads, silkscreen etc.

Here we will find the cross probing tool in Altium designer very helpful. To do this, go to Tools>Cross Probe from the toolbar as shown.





A + cross will appear at the tip of cursor. Select the oscillator (the part you want to cross probe, in this case oscillator) in the schematic and immediately Altium designer will highlight the oscillator part(footprint) and dim others in the PCB editor-

Now the oscillator is clearly visible in the PCB. To deselect the cross probing tool press ESC key and then select the clear button-


Similarly we can locate parts or nets from the PCB to schematic. Go to Tools>Cross Probe as before or select the cross probe icon and select the part in the PCB to get locate part in the schematic as shown-