Remember, EPWrites take time! If the USART overruns (like because the eeprom writes aren't complete by the time the next character comes in), the USART will lock up and you'll have to reset it. Try taking the EPWrites out of the interrupt sub and see what happens. Also, writes to EEProm shouldn't be interrupted. Save your characters to RAM variables, and write to EEProm in your main loop at a time when you can disable interrupts.
Joe
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK here is what I got now:
#chip 16F690, 20 'mhz
#config MCLRE=off, WDT=off
#define USART_BAUD_RATE 9600
#define USART_BLOCKING
InitUsart
On Interrupt UsartRX1Ready call rec_data
dir portb.5 in 'serial rx p12
dir portc.0 out 'save led
dir portc.1 out 'store led
dim temp as byte
dim eloc as byte
dim rloc as word
rloc = 160
eloc = 0
main:
goto main
sub rec_data
set portc.0 on
If RCIF On Then
poke (rloc, rcreg)
rloc = rloc + 1
if rloc = 239 then rloc = 288
rcif=0
end if
set portc.0 off
if rloc = 366 then save_data
end sub
sub save_data
set portc.1 on
rloc = 160
eloc = 0
intoff
do until rloc = 366
Temp = PEEK(rloc)
epwrite eloc, temp
eloc = eloc + 1
rloc = rloc + 1
if rloc = 239 then rloc = 288
loop
rloc = 160
eloc = 0
wait 250 ms
set portc.1 off
IntOn
end sub
But it only runs trough one time, it stores the data, saves it to eeprom and turns off the led, then just stops and does not do it again, why? I want it to update the data every time it is sent new.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There are a few things that need changing in your code.
Try using the built in USART receive function, it'll take care of clearing the error flags for you. To do this, you'll need to change your rec_data sub to this:
sub rec_data
set portc.0 on
If RCIF On Then
'poke (rloc, rcreg)
HSerReceive NewDataIn
Poke rloc, NewDataIn
rloc = rloc + 1
if rloc = 239 then rloc = 288
rcif=0
end if
set portc.0 off
if rloc = 366 then save_data
end sub
Also, as Joe points out, the EEPROM writing takes quite a while. You'd be better off doing this in your main routine - maybe have a variable that the serial routine sets when there is new data, which then triggers the EEPROM write to occur. It's always a good idea to make sure that you only do things in the interrupt handler if they absolutely cannot be done somewhere else.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is my code:
#chip 16F690, 20 'mhz
#config MCLRE=off, WDT=off
#define USART_BAUD_RATE 9600
#define USART_BLOCKING
InitUsart
On Interrupt UsartRX1Ready call get_data
dir portb.5 in 'serial rx p12
dir portc.3 out
dim temp as byte
dim loc as byte
loc = 0
main:
set portc.3 off 'heartbeat
wait 250 ms
set portc.3 on
wait 250 ms
goto main
sub get_data
If RCIF On Then serdata = RCREG
temp = serdata
epwrite loc, temp
loc = loc + 1
end sub
I only get the first three characters saved to the eeprom, then it saves no more, but the heartbeat is still running?
Remember, EPWrites take time! If the USART overruns (like because the eeprom writes aren't complete by the time the next character comes in), the USART will lock up and you'll have to reset it. Try taking the EPWrites out of the interrupt sub and see what happens. Also, writes to EEProm shouldn't be interrupted. Save your characters to RAM variables, and write to EEProm in your main loop at a time when you can disable interrupts.
Joe
OK here is what I got now:
#chip 16F690, 20 'mhz
#config MCLRE=off, WDT=off
#define USART_BAUD_RATE 9600
#define USART_BLOCKING
InitUsart
On Interrupt UsartRX1Ready call rec_data
dir portb.5 in 'serial rx p12
dir portc.0 out 'save led
dir portc.1 out 'store led
dim temp as byte
dim eloc as byte
dim rloc as word
rloc = 160
eloc = 0
main:
goto main
sub rec_data
set portc.0 on
If RCIF On Then
poke (rloc, rcreg)
rloc = rloc + 1
if rloc = 239 then rloc = 288
rcif=0
end if
set portc.0 off
if rloc = 366 then save_data
end sub
sub save_data
set portc.1 on
rloc = 160
eloc = 0
intoff
do until rloc = 366
Temp = PEEK(rloc)
epwrite eloc, temp
eloc = eloc + 1
rloc = rloc + 1
if rloc = 239 then rloc = 288
loop
rloc = 160
eloc = 0
wait 250 ms
set portc.1 off
IntOn
end sub
But it only runs trough one time, it stores the data, saves it to eeprom and turns off the led, then just stops and does not do it again, why? I want it to update the data every time it is sent new.
There are a few things that need changing in your code.
Try using the built in USART receive function, it'll take care of clearing the error flags for you. To do this, you'll need to change your rec_data sub to this:
sub rec_data
set portc.0 on
If RCIF On Then
'poke (rloc, rcreg)
HSerReceive NewDataIn
Poke rloc, NewDataIn
rloc = rloc + 1
if rloc = 239 then rloc = 288
rcif=0
end if
set portc.0 off
if rloc = 366 then save_data
end sub
Also, as Joe points out, the EEPROM writing takes quite a while. You'd be better off doing this in your main routine - maybe have a variable that the serial routine sets when there is new data, which then triggers the EEPROM write to occur. It's always a good idea to make sure that you only do things in the interrupt handler if they absolutely cannot be done somewhere else.