📄 program.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 + -