Interrupt and Serial communication to PC.


Closed Thread
Results 1 to 3 of 3

Hybrid View

  1. #1
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Assuming that you have a MAX232 attach between your PIC and your PC, here is something to play with.

    Code:
        '
        '   Simple program to handle USART interrupt using PIC16F877 @20MHZ
        '   ===============================================================
        '
        '   This program will Blink a LED on PORTB.0 to show
        '   that the PIC is running.  
        '
        '   This program also allow the user to activate or deactivate 
        '   a LED connected on PORTB.1 pin by sending command from a PC
        '   terminal software using 9600,n,8,1 setting
        '
        '   User command:
        '   =============
        '                1. If character "1" is received => enable the LED
        '                2. if character "2" is received => disable the LED
        '
        '
        DEFINE LOADER_USED 1        ' using bootloader
        DEFINE OSC 20               ' running at 20 MHZ
        
        '    PORT setting
        '    ============
             '
             TRISC=%10000000        ' RC.7 => USART RX pin set to input
                                    ' all other pin set to output
                                    '
             TRISB=0                ' RB<7:0> set to output
        
        '    USART setting
        '    =============
             ' Since we will not use HSERIN/HSEROUT, we must
             ' write directly to internal PIC register
             ' 
             TXSTA=$24              ' enable transmit and SPBRGH=1
             RCSTA=$90              ' Enable USART and continuous receive
             SPBRG=129              ' BAUD RATE = 9600 BAUDS
       
        '    Interrupt definition
        '    ====================
             '
             PIE1.5   =1            ' enable USART receive interrupt
             INTCON.6 =1            ' enable peripheral interrupt
        
        '    Alias definition
        '    ================
             '
             RCIF      var PIR1.5   ' receiver interrupt
             StatusLED var PORTB.0  ' the LED who show a 'running process'
             UserLED   var PORTB.1  ' the LED that user want to control
             
        '    Variable definition
        '    ===================
             '
             Delay     var word     ' 
             DataIn    var byte     ' use to store RCREG content
             Discard   var byte     ' use to erase RCREG register
            
        '    Hardware/software initialisation
        '    ================================
             '
             PORTB=0                ' clear PORTB         
             on interrupt goto USARTInterrupt
            
    Start:
        '    Main program loop that make the user happy to
        '    see a LED flashing to mean that something is 
        '    running 
        '
        toggle statusled
        for delay = 1 to 5000       ' use a loop delay to ensure
          pauseus 5                 ' getting interrupt as fast as
          next                      ' possible
        goto start
        
    
    disable interrupt
    USARTInterrupt:
        '    Here's the interrupt routine who will make the user
        '    much happy by giving him the feeling to have the 
        '    control on the machine when the status of the user
        '    LED will change
        '
        RCSTA=0                     ' Disable serial port AND
                                    ' clear possible error (FERR,OERR)
                                    
        datain=RCREG                ' Get data
                                    
        while RCif                  ' wait untill the RCREG is empty
              discard=RCREG         ' by reading it and store result in a
        wend                        ' don't care variable
                                    
        select case datain          ' What to do with that data???
                                    
               case "1"             ' User selection = 1
                    userled=1       '      => Enable the LED
                                    
               case "2"             ' User selection =2
                    userled=0       '      => disable the LED
                                    
               end select           
        RCSTA=$90                   ' Re-enable the serial PORT AND
        resume                      ' get out of here
    enable interrupt
    Last edited by mister_e; - 12th June 2005 at 17:06.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  2. #2
    obaskirt's Avatar
    obaskirt Guest


    Did you find this post helpful? Yes | No

    Smile

    Thank you for the code. I have just learned interrupts thanks to your code. But I have solved my problem in PC programming part. I have made some modifications in my algorithm but I think interrupts is more powerful than threads. Anyway I have not enough information about assembly language and some of the complex PBPro instruction (ex: on interrupt). Do you know links that I will find sufficient informations about these topics.

    Yes I used MAX232 voltage level converter. I used PIC16F877-04/P, 4 MHZ Crystal, comminication rate is 2400 Baud. I am gonna try that code.
    My current code is below, I have to fix some unnecessary declerations and variables, I have played that codes several times. Also I will try to use interrupts. But I am a newbie so maybe I will get lost in some complex timing analysis problems. Hopefully, you will help me.

    Additionaly in my graduation project presentation my instructor asked: "what is DS1820's baud rate?". My PIC baud rate is 2400, in pc program I set baud rate 2400 , but I dont know DS1820's baud rate??? I have confused. If you know something about that please answer it.


    ' --------------------- [DIGITAL TEMPERATURE MEASUREMENT and CONTROL]-----------------------

    temperature VAR WORD ' Temperature storage. (for storing measured value)
    count_remain VAR BYTE ' Count remaining
    count_per_c VAR BYTE ' Count per degree C
    tempc VAR WORD
    DQ VAR PORTC.2 ' One-wire data pin. (Ds1820's Dq line connected to RC2)
    RX VAR WORD ' Receive byte from PC.
    counter VAR BYTE ' Counter for Automatic Control
    state VAR BYTE
    maxtemp VAR BYTE
    mintemp VAR BYTE

    OUTPUT PORTB.5 ' Set portb pin 0 to an output. For LED. (or -> TRISB.0 = 0)
    OUTPUT PORTB.7 ' device
    INPUT PORTB.1 ' Set portb pin 1 to an input. (or -> TRISB.1 = 1)
    OUTPUT PORTC.5 ' Sound output pin. Set portc pin 5 to an output (or -> TRISC.5 = 0)
    OUTPUT PORTC.6 ' Serial comm. output pin. Set portc pin 6 to an output. (or -> TRISC.6 = 0)
    INPUT PORTC.7 ' Serial comm. input pin. Set portc pin 7 to an input. (or -> TRISC.7 = 1)

    '---------------------------------------------[Includes/Defines]-----------------------------------------------

    DEFINE LCD_DREG PORTD ' I/O port with LCD. (Defining LCD data port)
    DEFINE LCD_DBIT 4 ' When using a 4 bit data bus, (0 or 4) designate beginning of data bits.
    DEFINE LCD_RSREG PORTD ' Defining LCD's register port.
    DEFINE LCD_RSBIT 2 ' Register select pin.
    DEFINE LCD_EREG PORTD ' Defining LCD's enable port.
    DEFINE LCD_EBIT 3 ' Defining LCD's enable pin.
    DEFINE LCD_BITS 4 ' Defining LCD has 4-bit data bus
    DEFINE LCD_LINES 2 ' LCD has two charecter lines
    INCLUDE "modedefs.bas" ' Including serial modes.

    ' Set PORTA and PORTE to digital. Any PICmicro MCU with analog inputs, such as the PIC16C7xx,
    ' PIC16F87x and PIC12C67x series devices, will come up in analog mode.
    ' You must set them to digital if that is how you intend to use them: ADCON1 = 7
    ADCON1 = 7
    PAUSE 100 ' Pause for starting LCD

    '-------------------------------------------------[Main Code]---------------------------------------------------

    ' OWOut and OWIn commands are detailly explained in PBP official manual.

    ' OWOUT Pin,Mode,[Item...]:
    ' Optionally send a reset pulse to a one-wire device and then writes one or
    ' more bits or bytes of data to it, optionally ending with another reset pulse.
    ' Mode of %001 (decimal 1) means reset before data and byte-sized data.

    ' OWIN Pin,Mode,[Item...]:
    ' Optionally send a reset pulse to a one-wire device and then read one or
    ' more bits or bytes of data from it, optionally ending with another reset pulse.
    ' Mode of %000 (decimal 0) means no reset and byte-sized data, Mode of %100 (decimal 4)
    ' means no reset and bit-sized data. SKIP for skipping a number of input values.

    HIGH PORTB.7
    counter= 0
    state=0
    maxtemp=29
    mintemp=17

    mainloop:
    OWOut DQ, 1, [$CC, $44]
    waitloop:
    OWIn DQ, 4, [count_remain]
    IF count_remain = 0 THEN waitloop

    OWOut DQ, 1, [$CC, $BE]
    OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]
    temperature = (((temperature >> 1) * 100) - 25) + (((count_per_c - count_remain) * 100) / count_per_c)
    tempc = (temperature / 100)
    LCDOut $fe, 1, "TEMP: ", SDEC (temperature / 100), ".", SDEC2 temperature, " C"

    IF tempc < maxtemp THEN
    LCDOut $fe, $c0, "STATUS OK"
    ENDIF

    ' LCDOut $fe, $c0, temperature/100, "-", HEX (temperature / 100),"-", BIN (tempc)

    GOTO automatic

    '-----------------------------------------[Automatic and Manuel Control]----------------------------------------

    ' If temperature is equal or higher than 29 C then led status off and Buzzer generates sound also LCD monitors Alarm.
    ' Else led status is on, buzzer status off, LCD monitors status OK.

    automatic:

    IF PORTB.1 = 1 THEN ' Test button value. If button is pressed.
    LOW PORTB.7 ' device status is off.
    counter=0
    SEROUT PORTC.6, T2400, ["disabled",10,13]
    IF tempc >= maxtemp THEN ' Test temperature value.
    SOUND PORTC.5,[80,10,60,10] ' If temperature higher than 25 C than buzzer generates sound that is
    ' between 80 & 60 frequency band about 120 ms seconds interval.
    LCDOut $fe, $c0, "ALARM!!!" ' LCD monitors ALARM.
    Pause 200
    ENDIF
    SEROUT PORTC.6, T2400, [#tempc,10]
    GOTO mainloop ' Do it forever
    ENDIF

    IF state=1 OR state=2 THEN

    IF tempc >= maxtemp THEN ' Test temperature value.
    HIGH PORTB.5 ' LED status is on.
    SOUND PORTC.5,[40,10,60,10] ' If temperature higher than 25 C than buzzer generates sound that is
    ' between 80 & 60 frequency band about 120 ms seconds interval.
    LCDOut $fe, $c0, "ALARM!!!" ' LCD monitors ALARM.
    ENDIF

    IF tempc < maxtemp THEN ' Test temperature value.
    LOW PORTB.5 ' LED status is off.
    ENDIF
    GOTO serial
    ENDIF

    IF tempc >= maxtemp THEN ' Test temperature value.
    HIGH PORTB.5 ' LED status is on.
    SOUND PORTC.5,[40,10,60,10] ' If temperature higher than 25 C than buzzer generates sound that is
    ' between 80 & 60 frequency band about 120 ms seconds interval.
    LCDOut $fe, $c0, "ALARM!!!" ' LCD monitors ALARM.
    counter = (counter + 1)
    IF counter = 20 THEN
    LOW PORTB.7
    SEROUT PORTC.6, T2400, ["automatic", 10, 13]
    ENDIF
    GOTO serial ' Do it forever
    ENDIF

    IF tempc < maxtemp THEN ' Test temperature value.
    LOW PORTB.5 ' LED status is off.
    HIGH PORTB.7 ' Device on
    counter=0
    GOTO serial
    ENDIF ' Do it forever


    '------------------------------------------------[Serial Communication]-----------------------------------------

    serial:

    ' ****** [Menu setup on PC screen] *************************
    serout PORTC.6, T2400, [#tempc,10]

    ' ***** [Receive the menu selection from PC] ***************
    serin PORTC.7, T2400,RX ' Receive menu number
    RX = RX - $30


    ' Convert ASCII number to decimal (0 = $30, 1 = $31, etc).

    SELECT CASE RX
    CASE 0
    goto zero
    CASE 1
    goto one
    CASE 2
    goto two
    CASE 3
    goto disconnect
    CASE IS > 3
    goto error
    CASE IS < 0
    goto error
    CASE ELSE
    goto mainloop
    END SELECT

    error:
    goto mainloop

    zero:
    state=0
    goto mainloop

    one:
    LOW PORTB.7 ' LED status is off.
    state=1
    GOTO mainloop

    two:
    HIGH PORTB.7 ' LED status is off.
    state=2
    GOTO mainloop

    disconnect:
    LCDOut $fe, $c0, "TURNED OFF " ' LCD monitors ALARM.
    Pause 1000
    Goto mainloop
    '---------------------------------------------------------------------------------------------------------------

    End ' End of program.

Similar Threads

  1. Wireless serial communication question
    By Ahmadabuomar in forum Serial
    Replies: 3
    Last Post: - 21st December 2009, 03:49
  2. 18F2480 asm interrupt
    By Richard Storie in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 5th March 2009, 19:40
  3. is there interrupt serial communication in pbp?
    By mimmmis in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 16th September 2008, 12:53
  4. Serial Communication with PC code
    By mike12345 in forum Serial
    Replies: 4
    Last Post: - 24th May 2006, 02:16
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts