Interrupt and Serial communication to PC.


Closed Thread
Results 1 to 3 of 3
  1. #1
    obaskirt's Avatar
    obaskirt Guest

    Unhappy Interrupt and Serial communication to PC.

    I have a DS1820 one wire digital temp. sensor, I designed a temperature measurement and control circuit and I used PIC16F877, I connected a led on PORTB7 and I wrote a pc program with C# 2005 Beta 2. In PC program I made a two buttons (turn led off and turn led on) . Led initial condititon is off. When I pressed turn on Led have to tuurn on. And also when I pressed turn off, led have to turn off. But there is a tricky problem. I used SERIN comand for receiving data, but when PBP code came to that command it waited a response from PC so for solving that problem I used a THREAD in PC program I send "0" every 2 seconds and when "0" sending to the pic, pic goes to the mainloop. When I send "1" , then PIC turns off the led, when I send "2" pic turns on the led. But When thread is starting, I mean when pc send "0" automatically and after that you pressed "1" or "2" PBP not respond this. Because when PC send "0" PBP program goes to mainloop and after a little time later if you press "1" or "2" PBP program maybe is not at line where SERIN command exist so both of the buttons wont work. I increased timeout but anyway this means wait at serin command for example 5 second then if user dis not pressed any button send "0" to PIC. This is not a exact solution. Exact solution is using INTERRUPT. But ı could not accomplish that. Please help me... How to use interrupt for this program??? I mean when interrupt comes to pic from usart ("1", or "2") then pic will leave current job and jump to the if value is "1" turn on the led or value is "2" turn off the led after this process resume previous position in the main loop. Thanks for your attention...

  2. #2
    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.

  3. #3
    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 : 1

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