⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 program.pbp

📁 Embedded microcontroller program (PicBasic) to implement RFID-based Medicine Teller system, used to
💻 PBP
字号:
'**************************************************************************
' RFID based Medicine Reminder (e-Nurse System)
' =============================================
'**************************************************************************
' This system aims to provide a RFID based medicine reminder for the elder
' for easier way to take right medicine in accordance to the right schedule.
' The RFID tags are put on the medicines, and the tag code are scheduled and
' stored in MCU unit.
' The clock time is running based on timer interrupt. When the time, LED (or 
' buzzer) on to remind the patient to take medicine. The patient needs to scan
' the RFID tag (on the medicines). After the correct medicine been scanned,
' the reminder will be OFF.
'
' The timer interrupt TMR0 is used to update the time. The timer is configured
' to interrupt at every 16.384ms. When the count is 61, one second is elapsed
' and the seconds variable is incremented by 1. The minutes or the hours
' variables are incremented if necessary.
' Program by Kee K.K.
' Use Microchip PIC16F876A.

Define Loader_used  1
Define OSC          4
'Setting the LCD panel 16x2, to port B with the pins specified
DEFINE LCD_DREG PORTb
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTb
DEFINE LCD_RSBIT 7
DEFINE LCD_EREG PORTb
DEFINE LCD_EBIT 6
DEFINE LCD_BITS 4
'Define different symbols to IO pins
SYMBOL scan_input = portA.0
Symbol Hrs_button = PORTA.2     ' Hour setting button
Symbol Mins_button = PORTA.3    ' Minute setting button
Symbol scan_button = PORTA.4    ' RFID scanning start button
Symbol exit_button = PORTA.5    ' RFID scanning start button

' ---[ Variables ]----------------------------
Ticks   VAR byte                ' Tick count (61 ticks = 1 sec)
Hour    VAR byte                ' Hour variable
Minute  VAR byte                ' Minute variable
Second  VAR byte                ' Second variable
Delay   VAR byte                ' Used to Debounce button
Disp    VAR byte                ' Disp = 1 to update display
Remind  VAR byte                ' Remind = 1 to remind the patient
'Variables for RFID use
buf     var byte(10)            ' Buffer for variable to store bytes received
tagNum  var byte                ' Stores number of tags to scan
idx     var byte                ' Index for bytes received
char    var byte                ' Byte to store temp character

' ---[ Initialisation ]----------------------------
ADCON1 = 7                      ' Set PortA as digital IO
TRISA = %11111111 	            'All port A input
TRISC = %00000000 	            'All port C output
' Clear Hour, Minute, Second and Ticks to zero
Hour = 0
Minute = 0
Second = 0
Ticks = 0
remind = 0
disp = 0
'Initialise the tags to be recognised
tag1 data "0005104474"
tag2 data "0000939743"

lcdout $FE,1,  "e-Nurse System "
lcdout $FE,$c0,"  by Kee K.K   "
pause 3000
lcdout $FE,1,  " RFID Medicine "
lcdout $FE,$c0,"    Reminder   "
pause 3000

' ---[ Initiase the timer interrupt for 1 sec tick ]----------------
' The prescaler is set to 64 and the TMR0 is left to run from 0 to 255. 
' With a clock frequency of 4MHz, the timer interrupt is generated at 
' every 256 * 64 = 16.384ms. Inside the ISR, variable ticks is incremented 
' by 1. When Ticks = 61 then time for a timer interrupt is: 61*16.384 = 
' 999.424ms and variable second is then updated. i.e. Second is updated 
' nearly every second.
OPTION_REG = $05        ' Set prescaler = 64
ON INTERRUPT GOTO ISR   ' ISR routine
INTCON = $A0            ' Enable TMR0 interrupt and global interrupts
LCDOUT $FE, 1           ' Clear LCD

'*************************************************************************
' ---[ Beginning of MAIN program loop ]----------------
LOOP:
' Check buttons for Hour and Second variables increment, and scan_button.
IF Hrs_button = 1 THEN      'Check button for Hour
    Hour = Hour + 1
    IF Hour = 24 THEN Hour = 0
    Gosub Debounce
ENDIF
IF Mins_button = 1 THEN     'Check button for Minute
    Minute = Minute +1
    IF Minute = 60 THEN Minute = 0
    Gosub Debounce
ENDIF

IF scan_button = 1 THEN     ' Check button for scan (RFID)
check_RFID_tag:
    lcdout $FE,1,  "Please scan your"
    lcdout $FE,$c0,"    Medicine    "
    
    IF exit_button = 1 THEN ' Check button for exit
        Gosub Debounce
        goto LOOP
    endif
    ' Read RFID input from PortA.0. If 2 seconds elapsed, loop back again.    
    serin2 scan_input,84,2000,check_RFID_tag,[str buf\10]  
    for tagnum = 1 to 2     ' Set the number if more tags required
        for idx = 0 to 9    ' Set this if number of tag digits is different
            read(((tagnum-1)*10)+idx),char
            if(char<>buf(idx)) then no_tag_found
        Next idx
        goto tag_found
no_tag_found:
    'If no tag found, ON LED1 and sounding
    next tagnum 
    lcdout $FE,1,  "   Incorrect    "
    lcdout $FE,$c0,"  Medicine !!!  "
    freqout portC.5,1000*/$100,115*/$100
    pause 1500
    goto check_RFID_tag
tag_found:
    lcdout $FE,1,  "     Correct    "
    lcdout $FE,$c0,"  Medicine !!!  "
    freqout portC.5,2000*/$100,880*/$100
    pause 3000
    remind = 0      ' Reminder sign can be OFF
    disp = 1        ' Refresh LCD panel required  
ENDIF

' Check the system time with the schedule. If the time, both variables Remind
' and Disp will be set. Here we set 01:00:10 (am) to take medicine
IF ((Hour == 1) AND (Minute == 0) AND (Second == 10)) THEN 
    Sound portC.5,[100,1,50,1]
    remind = 1  
    disp = 1   
endif

' Display update section. If Disp = 1 then refresh the LCD screen
IF Disp = 1 THEN
    LCDOUT  $FE,1,  "Time ~ ", #Hour,":",#Minute,":",#Second
    ' Check the Remind variable. Update LCD where necessary
    if remind = 1 then 
        lcdout $FE,$c0,"Take medicine 1"   
    else
        lcdout $FE,$c0,"MedTime - 1:0:10"      
    endif
    Disp = 0    ' Reset the variable Disp finally.
ENDIF
GOTO LOOP
'*************************************************************************


' This subroutine Debounces the buttons. Also, a delay is introduced when
' a button is pressed so that the variable attached to the button (Hour or Second)
' can be incremented after a small delay.
Debounce:
FOR Delay = 1 To 200
    Pause 1     ' Delay 1ms inside a loop. This way,
NEXT Delay      ' timer interrupts are not stopped
Disp = 1        ' Set display flag to 1
RETURN

' This is the Timer interrupt Service Routine. The program jumps to this code
' whenever the timer overflows from 255 to 0. i.e. every 256 count. The prescaler
' is set to 64 and the clock frequency is 4MHz. i.e. the basic instruction cycle
' time is 1 microsecond. Thus, timer interrupts occur at every 64*256 = 16.384ms.
' Variable Ticks is incremented by 1 each time a timer interrupt occurs. When Ticks
' is equal to 61, then one second has elapsed (16.384*61 = 999.424ms) and then
' variable Second is incremented by 1. When Second is 60, variable Minute is
' incremented by 1. When Minute is 60, variable Hour is incremented by 1.
' Timer TMR0 interrupts are re-enabled just before the program exits this routine.
DISABLE
ISR:
Ticks = Ticks + 1

' 1 second has elapsed, now update seconds and if necessary minutes and hours.
IF Ticks < 61 THEN NoUpdate
    Ticks = 0
    Second = Second + 1     ' Update second
    IF Second = 60 THEN
        Second = 0
        Minute = Minute + 1 ' Update Minute
        IF Minute = 60 THEN
            Minute = 0
            Hour = Hour + 1 ' Update Hour
            IF Hour = 24 THEN
                Hour = 0
            ENDIF
        ENDIF
    ENDIF
    Disp = 1        ' LCD screen update required

NoUpdate:
    INTCON.2 = 0    ' Re-enable TMR0 interrupts
    Resume
    ENABLE          ' Re-enable interrupts
END             ' End of program

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -