![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
ulpwu and interrupt on change using rfid tecnology |
Posted: Tue Jun 12, 2007 9:47 am |
|
|
i'm tring to study the trasmission phase of rfid in order to change this trasmission using microcontroller. I'm using the anticollision receiver to do it (using ccs and pickit2 of Microchip). My application refers to temperature sensore: I want to register temperature and trasmit it uusing microcontroller and anticollision receiver. THis is my code:
Code: | #define zero 223
#define uno 255
#define address_byte 10
int8 j=0;
unsigned int8 dato=0;
int8 i=0;
int8 vettore[25]={0,1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int8 indice=0;
int8 temp_mem=255; // corrisponde a -58 gradi celsius di temperatura
void inserimento(int8 temperatura)
{
i=16;
while(temperatura!=0)
{
if (temperatura%2==1)
{
j=10+i;
vettore[i]=j;
j=136+i;
vettore[i+8]=j;
}
i--;
temperatura=temperatura/2;
}
for(j=9;j<24;j++)
{
if(vettore[j]==0)
{
i=j;
while(vettore[i]==0 && i!=25)
{
i++;
}
if(i!=25)
{
vettore[j]=vettore[i];
vettore[i]=0;
}
}
}
}
#int_TIMER1
void TIMER1_isr(void)
{
int8 aux=uno;
int8 aux2=zero;
setup_timer_1(T1_DISABLED);
indice=0;
i=1;
while(indice!=154)
{
set_tris_b(aux);
indice++;
if(indice==vettore[i])
{
i=i+1;
set_tris_b(aux2);
aux=uno;
aux2=zero;
}
else
{
set_tris_b(aux2);
aux=zero;
aux2=uno;
}
}
indice=0;
}
#int_RA
void RA0_isr(void)
{
output_high(PIN_C4);
disable_interrupts (INT_RA0);
disable_interrupts(GLOBAL);
}
void main()
{
setup_adc_ports(sAN4|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//enable_interrupts(INT_TIMER1);
//enable_interrupts(INT_RA0);
//enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);
set_adc_channel(4);
delay_us(10);
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
set_tris_b(0xFF);
for(j=9;j<25;j++)
{
vettore[j]=0;
}
/*
dato=read_adc();
delay_us(10);
if (dato<temp_mem)
{
temp_mem=dato;
write_eeprom(address_byte,temp_mem);
delay_ms(20);
inserimento(temp_mem);
}
else
{
temp_mem=read_eeprom(address_byte);
delay_ms(20);
inserimento(temp_mem);
}
*/
temp_mem=100;
//temp_mem=read_adc(); do not function!!!
inserimento(temp_mem);
output_low(PIN_C4);
i=0;j=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(65500);
delay_ms(1);
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);
enable_interrupts(INT_RA0);
enable_interrupts(GLOBAL);
sleep_ulpwu(40000);
}
} |
If I do not use sleep_ulpwu functio, all is ok; if I use it, I trasmit only the same value (the first). I think I have a problem on interrupt on change I have to use because of the ulpwu module. My testing microcontroller are both PIC16f690 and PIC12f683 (both of them including ulpwu). My aim is detects the temperature, write it on eeprom and the trasmit it (using timer1..). The problem is this: if I don't use temperature sense and trasmit a value (for example 100..) all is ok; if I use temperature sensor, I trasmit only one value and it doesn't update.
Help me .............Thanks a lot. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 12, 2007 3:27 pm |
|
|
Quote: | #int_RA
void RA0_isr(void)
{
output_high(PIN_C4);
disable_interrupts (INT_RA0);
disable_interrupts(GLOBAL);
} |
There is no point to disable Global interrupts inside an ISR.
They are already disabled automatically by the PIC hardware
when the interrupt is executed. Also, when the PIC leaves
the ISR (and the CCS interrupt dispatcher exit code), Global
interrupts will be automatically re-enabled.
Delete the line shown in bold. It doesn't do anything.
There is another problem in your ISR. Read Section 4.2.3 of
the 16F690 data sheet. It says:
Quote: | This interrupt can wake the device from Sleep. The
user, in the Interrupt Service Routine, clears the
interrupt by:
a) Any read or write of PORTA.
This will end the mismatch condition, then,
b) Clear the flag bit RABIF. |
You must do item (a). Item (b) is done by the compiler.
Add the lines shown in bold below:
Quote: |
#int_RA
void RA0_isr(void)
{
int8 value;
output_high(PIN_C4);
disable_interrupts (INT_RA0);
value = input_a();
}
|
Your code has a few other problems. The correct style in C, is to
put constants in all caps, like this:
Code: | #define ZERO 223
#define UNO 255
#define ADDRESS_BYTE 10 |
Do the same thing in the program code.
Also, you're using too many global variables. Many of your variables
are used only temporarily in functions, and should be declared inside
the functions as shown below. This is the correct style in C.
Quote: |
void inserimento(int8 temperatura)
{
int8 i, j;
i=16;
while(temperatura!=0)
{
if (temperatura%2==1)
{
j=10+i;
|
Your code might have other problems, but at least these need to be
corrected. |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
Re: PCM programmer |
Posted: Wed Jun 13, 2007 4:09 am |
|
|
I changed my code as you have proposed:
Code: | [quote]#int_RA
void RA0_isr(void)
{
output_high(PIN_C4);
disable_interrupts (INT_RA0);
disable_interrupts(GLOBAL);
}[/quote] |
I always see the same value, after that I have set adc:
Code: | void main()
{
setup_adc_ports(sAN4|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_8MHZ);
set_adc_channel(4);
delay_us(10);
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
set_tris_b(0xFF);
for(j=9;j<25;j++)
{
vettore[j]=0;
}
temp_mem=read_adc();
delay_us(20);
inserimento(temp_mem);
output_low(PIN_C4);
i=0;j=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(65500);
delay_ms(1);
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);
enable_interrupts(INT_RA0);
enable_interrupts(GLOBAL);
sleep_ulpwu(40000);
}
} |
The temperature sensore doesn't update, and also give me an errate value (for example I always see the equivalent of -8°C, an absurd negative value...).
Please, help me... THanks a lot. |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
Re: PCM programmer |
Posted: Wed Jun 13, 2007 4:43 am |
|
|
Excuse me, but I have done an error. The correct code in the interrupt is that:
Code: | #include "C:\Documents and Settings\Admin04\Desktop\Ultimo codice\Ultimo codice 16f690 prova\16f690.h"
#include <math.h>
#define ZERO 223
#define UNO 255
#define ADDRESS_BYTE 10
int8 j=0;
unsigned int8 dato=0;
int8 i=0;
int8 vettore[25]={0,1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int8 indice=0;
int8 temp_mem=255; // corrisponde a -58 gradi celsius di temperatura
void inserimento(int8 temperatura)
{
i=16;
while(temperatura!=0)
{
if (temperatura%2==1)
{
j=10+i;
vettore[i]=j;
j=136+i;
vettore[i+8]=j;
}
i--;
temperatura=temperatura/2;
}
for(j=9;j<24;j++)
{
if(vettore[j]==0)
{
i=j;
while(vettore[i]==0 && i!=25)
{
i++;
}
if(i!=25)
{
vettore[j]=vettore[i];
vettore[i]=0;
}
}
}
}
#int_TIMER1
void TIMER1_isr(void)
{
int8 aux=uno;
int8 aux2=zero;
setup_timer_1(T1_DISABLED);
indice=0;
i=1;
while(indice!=154)
{
set_tris_b(aux);
indice++;
if(indice==vettore[i])
{
i=i+1;
set_tris_b(aux2);
aux=uno;
aux2=zero;
}
else
{
set_tris_b(aux2);
aux=zero;
aux2=uno;
}
}
indice=0;
}
#int_RA
void RA0_isr(void)
{
int8 value;
output_high(PIN_C4);
disable_interrupts (INT_RA0);
value=input_a();
}
void main()
{
setup_adc_ports(sAN4|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//enable_interrupts(INT_TIMER1);
//enable_interrupts(INT_RA0);
//enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);
set_adc_channel(4);
delay_us(10);
while(1)
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
set_tris_b(0xFF);
for(j=9;j<25;j++)
{
vettore[j]=0;
}
/*
dato=read_adc();
delay_us(10);
if (dato<temp_mem)
{
temp_mem=dato;
write_eeprom(address_byte,temp_mem);
delay_ms(20);
inserimento(temp_mem);
}
else
{
temp_mem=read_eeprom(address_byte);
delay_ms(20);
inserimento(temp_mem);
}
*/
[b] temp_mem=read_adc();[/b]
delay_us(20);
inserimento(temp_mem);
output_low(PIN_C4);
i=0;j=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(65500);
delay_ms(1);
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);
enable_interrupts(INT_RA0);
enable_interrupts(GLOBAL);
sleep_ulpwu(40000);
}
} |
I had the same problem: always the same value of temperature. Please, give me a hand...Thanks a lot. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 13, 2007 5:44 am |
|
|
PCM programmer wrote: | Also, you're using too many global variables. Many of your variables
are used only temporarily in functions, and should be declared inside
the functions as shown below. This is the correct style in C.
Quote: |
void inserimento(int8 temperatura)
{
int8 i, j;
i=16;
while(temperatura!=0)
{
if (temperatura%2==1)
{
j=10+i;
|
Your code might have other problems, but at least these need to be
corrected. | Why didn't you implement these and the other suggestions???
Now your code is hard to follow and prone to errors. For example the variable i is used in inserimento() but it is possible for the timer interrupt to get active and modify this same variable in between with unknown resulting behaviour.
Garbage in == garbage out.
Unless you clean up your code I'm not going to waste my time looking for other errors. |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
|
Posted: Wed Jun 13, 2007 8:24 am |
|
|
I must use these global variables because I use them both in inserimento () and in timer1. However if I don't use sleep_ulpwu() the temperature sensore works very good, when I use this function the sensore returns one random value (always the same). |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 13, 2007 9:04 am |
|
|
giustraman wrote: | I must use these global variables because I use them both in inserimento () and in timer1. | I can see you are using the same variable in both functions, but that is the whole point we are trying to make clear. You say you _must_ make it a global variable where we say that is not true as the variable is doing different things in both functions. The only common thing is that the variable has the same name.
The problem now is that when executing inserimento() the timer1 is also active and could fire an interrupt. Because both functions are using the same _global_ variable it is possible that your program starts inserimento(), is interrupted by Timer1 and than continues afterwards with a modified value for i. Because the interrupt is occuring at an undefined moment it is impossible to tell how your program will respond to this modified value of i.
It is very well possible that the above mentioned problem has nothing to do with the behaviour you are seeing, but it is a serious bug and easy to solve. With a known bug present in your program I want to see that fixed first before we start a ghost hunt looking for another bug. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 13, 2007 9:17 am |
|
|
Which processor and compiler version are you using? |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
|
Posted: Thu Jun 14, 2007 2:02 am |
|
|
I use PIC C COMPILER and RFLAB V 3.4 |
|
![](templates/subSilver/images/spacer.gif) |
ttelmah Guest
|
|
Posted: Thu Jun 14, 2007 3:04 am |
|
|
giustraman wrote: | I use PIC C COMPILER and RFLAB V 3.4 |
Compiler _version_...
Number at the top of the .lst file
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
|
Posted: Thu Jun 14, 2007 4:49 am |
|
|
PIC Compiler v 4.033
RFLAB v 3.4 |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jun 14, 2007 12:05 pm |
|
|
... and which processor?
Did you implement my suggestion? And did this improve anything? |
|
![](templates/subSilver/images/spacer.gif) |
giustraman
Joined: 11 Jun 2007 Posts: 25
|
|
Posted: Fri Jun 15, 2007 1:35 am |
|
|
The problem is the same always: whether I implement all your suggestions, when I set temperature sensor, on rfllab I see the first value that is correct, afther that I always see only a random value (always the same). If I don't use sleep_ulpwu() function, all goes correctly. But I need of sleep_ulpwu() function... |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jun 15, 2007 2:11 am |
|
|
Sleep_ulpwu() is a new function in the v4 compiler, it is very well possible this function contains a bug. You are using v4.033, have you tried the latest release v4.041?
Another option is for you to compare the generated assembly code in the *.lst file with the example code given in the datasheet.
I can't test the compiler as I still consider all v4 compilers as beta releases and am working with v3.249 (the last known stable release and still available for download).
Maybe someone else can jump in here?
... we still don't know which processor you are using ... (I hate having to repeat myself 3 times).
Your program as posted is not complete, the #fuses line, #delay, etc. are missing. These lines tell us a lot about your system configuration and are required for us to reproduce your problem. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 17, 2007 3:02 pm |
|
|
He did say that in his original post.
Quote: | My testing microcontroller are both PIC16f690 and PIC12f683 |
My question is:
The ULPWU module is normally used with an external capacitor on pin A0.
See the Microchip appnote, AN879, below:
http://ww1.microchip.com/downloads/en/AppNotes/00879C.pdf
Do you have this capacitor installed on your board ? Is on pin A0 ?
What is the value of the capacitor ? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|