|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 04, 2006 11:30 pm |
|
|
I can see several errors.
1. If I try to program a 16F628A with an ICD2, with both the INTRC_IO
and NOMCLR fuses enabled, MPLAB gives me a warning saying don't
do that. It suggests changing the fuse to MCLR.
2. You have two "set_tris" lines that are just sitting out in space.
They're not part of a function. This means you have an older
compiler which doesn't give an error message for this.
Delete those two lines. You're using Standard i/o mode anyway.
You don't need to set TRIS in standard i/o mode, as long as you
use the CCS pin i/o functions (which you are doing).
3. According to the 16F628A data sheet, you're supposed to read
the CMCON register at the end of the INT_COMP isr, in order to
clear the "mismatch condition". This is in section 10.6 of the data
sheet -- Comparator Interrupts. You need to declare CMCON
register address with the #byte directive, and then just read it
into a variable at the end of the isr.
4. You have enabled Comparator interrupts, but you never enable
global interrupts, so nothing is going to happen.
5. Suppose 'sensor_alarm' gets set = 1. I don't see where you
you ever clear it back to 0. So your code (once it's fixed) is
going to set it to a 1, and it will stay that way forever. |
|
|
bsodmike
Joined: 05 Aug 2006 Posts: 52
|
|
Posted: Wed Oct 04, 2006 11:50 pm |
|
|
This *should* satisfy 4 & 5 by PCM, be sure to follow the rest,
Code: | ..
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
while(TRUE)
{
if (sensor_alarm) // when i have more that 2,5V in my R2 PIn.
{
output_high(PIN_B4);//led green
output_LOW(PIN_B3);
delay_ms(500);
sensor_alarm=FALSE;
}
else
{
output_high(PIN_B3);//led red
output_LOW(PIN_B4);
delay_ms(500);
}
}
.. |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 05, 2006 11:25 am |
|
|
Quote: | include <16F628A.h>
#fuses XT,WDT,NOPROTECT
#use delay(clock=4000000) |
In your new program, you have enabled the Watchdog Timer, and
for no reason. Why ? If you use WDT, you need to put in a
restart_wdt() statement inside your main loop. If you don't do that,
the PIC will constantly reset.
There is no reason to enable the WDT.
Also, you took out the NOLVP fuse that you had in your previous code.
This is needed. The PIC can lock up if you remove it.
Quote: |
setup_comparator(A0_A3_A1_A2);
setup_vref(VREF_HIGH|8);
|
Here, you have changed the comparator setup so it doesn't use
the Vref. But you are still using Vref in the next line. So where
will the comparator get the reference voltage ? From an external
circuit ?
Your main problem is that you don't understand PICs enough to write
a program, and you are just randomly changing important things for
no reason. You will never get a program to work if you do this.
You need to study some more. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 05, 2006 3:28 pm |
|
|
Quote: | The last code that i post here is from CCS Help. |
OK, I checked and I can see that part of that code is from the CCS
example file, EX_COMP.C. But you didn't say that, so I assumed that
you were randomly changing your code. Also, the CCS example
has this:
Code: |
setup_comparator(A1_VR_OUT_ON_A2);
setup_vref(VREF_HIGH|15);
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
|
But in the code you just posted, you changed the comparator setup
so it doesn't use the Vref. (The example code above does use it).
setup_comparator(A0_A3_A1_A2);
Quote: | I didnt see that this forum is only for advanced programmer |
It's not just for advanced programmers. But sometimes we get upset on
here if we think the person is not learning fast enough.
I will try to come up with an example program later today. (It might
be several hours from now). |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 06, 2006 1:07 am |
|
|
Here's a program that shows how to setup the 16F628A to use
only one comparator. It also uses the internal Vref generator.
This program doesn't use interrupts. It polls the comparator's
output bit (in the CMCON register), in a loop. It demontrates
how to create hysteresis between the on and off levels for the LED.
Normally in a comparator circuit, this is done is hardware,
but this program does it in software by changing Vref.
Code: |
#include <16F628A.h>
#fuses INTRC_IO, NOWDT, PUT, BROWNOUT, NOLVP, MCLR
#use delay (clock=4000000)
#define VREF_LOW_THRESHOLD 7 // Vref = 2.35 volts
#define VREF_HIGH_THRESHOLD 8 // Vref = 2.50 volts
#byte CMCON = 0x1F
#bit COMP2_OUTPUT_BIT = CMCON.7
//===========================================
void main()
{
// Turn on Comparator #2. Comparator #1 is not used.
setup_comparator(NC_NC_A1_A2);
// Turn on the Vref generator. Vref connects to the
// Vin+ input pin (pin A2) on Comparator #2.
setup_vref(VREF_HIGH | VREF_A2 | VREF_HIGH_THRESHOLD);
// Poll the comparator #2 output bit in a while() loop.
// If the input voltage goes above the upper threshold,
// then turn on the LED. In addition to that, change
// the threshold (Vref) to a slightly lower voltage.
// This provides some hysteresis (.15v) so the voltage
// level detection is not affected by noise.
// When the voltage goes below the lower threshold,
// turn off the LED and set the Vref back to the upper
// threshold voltage. So there is hysteresis going
// both directions.
while(1)
{
if(COMP2_OUTPUT_BIT == 0) // Is Vin > Vref ?
{
output_high(PIN_B0); // If so, turn on LED.
setup_vref(VREF_HIGH | VREF_A2 | VREF_LOW_THRESHOLD);
}
else // If not, turn off LED.
{
output_low(PIN_B0);
setup_vref(VREF_HIGH | VREF_A2 | VREF_HIGH_THRESHOLD);
}
delay_ms(10);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 06, 2006 11:27 am |
|
|
I didn't really try to understand what your code is doing. I just quickly
scanned it for coding errors. The following code doesn't look correct.
You have this:
Code: | case 0b00000000 : // status do sensor 0
if(in == 0b00000000)
output_high(PIN_A0); // on verde pino A0
output_low(PIN_A1); // off red pino A1
if(in == 0b11111111)
output_high(PIN_A1); // on red pino A1
output_low(PIN_A0); // off green pino A0
break;
|
If there are no braces after an "if()" statement, then only
the very next line will be executed if the if() statement is
true. So in your code above, the two lines for "output_low()"
will both always execute. The effect is that pin A0 and pin A1
will always be set low. I don't think that's what you intended.
I think that you probably really want to do this:
Code: |
case 0b00000000 : // status do sensor 0
if(in == 0b00000000)
{
output_high(PIN_A0); // on verde pino A0
output_low(PIN_A1); // off red pino A1
}
if(in == 0b11111111)
{
output_high(PIN_A1); // on red pino A1
output_low(PIN_A0); // off green pino A0
}
break;
|
There are several other "case" statements that also have to be fixed
in the same way. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 11, 2006 5:36 pm |
|
|
The basic problem is that there are several coding errors.
For example, you have brace just before the while(1). Why ?
Quote: | {while (1)
for(i=0b00000000; i< NUM_SENSORES;i++) // ask status sensor
out = (mask | i);
putc(out);
delay_ms(500);
if (kbhit())
|
If you want code to be inside a while(1) loop, you need to put braces
around the code. The first brace comes after the while(1).
or, many people write it like this:
Then farther down, in the switch statement, you have a brace just
after the first if() statement. Where's the closing brace for that one ?
Quote: |
switch (i) // sensor number
{
case 0b00000000 : // status do sensor 0
if(in == 0b00000000)
{
output_high(PIN_A0); // on verde pino A0
output_low(PIN_A1); // off red pino A1
break; |
Then you have two if() statements in a case statement.
What happens if neither one of those if() statements executes ?
The code will "fall through" to the next case, and execute that one.
Is that what you want to happen ? If not, you need to put a break
statement after the 2nd if() block, after the closing brace.
Code: |
case 0b00000001 : // setar status do sensor 1
{
if(in == 0b00000000)
output_high(PIN_B3); // on green pino B3
output_low(PIN_B0); // off red pino B0
break;
}
if(in == 0b11111111)
{
output_high(PIN_B0); // on red pino B0
output_low(PIN_B3); // off green pino B3
break;
}
case 0b00000010 :
|
Also, notice that in the first if() statement, just above, your braces
are in the wrong place. They should be done the same way as in
the lower if() statement.
Basically, you need to go through your entire program and fix all the
problems with braces. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 11, 2006 7:32 pm |
|
|
You still coding errors and possibly some design errors in your program.
In the code below, see the line in bold. This is a very common error.
You should have '==' there, and not '='.
Quote: |
while (1) {
if (kbhit()) { // when sensor receive data for serial port
in = getc();
}
if ( in = address) {
if (input(PIN_B7)) {
out = (0b11111111);
putc(out);
} else {
out = (0b00000000);
putc(out);
}
}
} |
In the code below, you call kbhit() to see if the UART has a character
available.
Quote: | while (1) {
if (kbhit()) { // when sensor receive data for serial port
in = getc();
} |
But suppose there is no character available ? You still go ahead and
execute all this other code anyway:
Quote: | if(in == (0b00000000) || in == (0b11111111))
{
configura_status_sensor(i, in);
}
else
{
deactive_sensor(i);
} |
Do you want to do that ?
Or, do you really want to wait for a key to be pressed by the user ?
If so, then get rid of the test for kbhit(), and just do this:
I'm not sure what you want, so you must decide. The line shown above
will wait until the user presses a key on the keyboard. Then the key
will be put into the 'in' variable.
Down in the lower program, you have this code. You define the UART
to use pin B1 for receive, but then in your set_tris_b() statement, you
set pin B1 to be an output pin. But it's supposed to be an input pin,
because it's used to receive characters.
Quote: | #use rs232(baud=4800, xmit=PIN_B2, rcv=PIN_B1, ERRORS)
void main()
{
set_tris_b(0b10000000);
setup_comparator (NC_NC_NC_NC); |
There might be other problems, but you basically need to go through
your entire program and clean up all these little bugs. |
|
|
Marcos Coseglio Guest
|
|
Posted: Wed Oct 11, 2006 9:54 pm |
|
|
I need to clear some things about my project.
I dont use keyboard, only communication PIC to PIC.
The communication is simple and dont have problems with distance because it is only before 500cm.
My first PIC send data from PIN B2
Quote: | for example : 0b11111000. |
I used kbhit function to detect my received data in PIN B1 in my second PIC. Can i use it?
for example:
Quote: | if (kbhit()) { // when sensor receive data for serial port
in = getc(); |
After receive data , the second PIC will process information and will sns from your PIN B2 only 2 types answer 0b00000000 or 0b11111111.
he has only 250ms to sens this infrmation to first PIC.
My first PIC will receive this data from second PIC and will process the information.
Quote: | if ( kbhit() ) {
in = getc();
}
if (in == (0b00000000) || in == (0b11111111)) |
MY several problem is wth USART communication.
Do you know how can i to make this communication?
We can call PICA and PICB:
Quote: | PICA send 0b11111000
PICB receive 0b11111000
PICB will compare the data with your address.If your address is the same that 0b11111000, he will send answer 0b00000000 or 0b11111111.
PICA wait 250ms and verify that PICB answer .
IF answer he will process information.If dont answer will realize other function. |
Note that 2 PIS will stay in infinite loop for this work.
Can i use kbhit to detect my data ?
Do you know a more eficient mode that i can realize this simple communication? i only neeed detect when my PICB receive data and when my PICA receive answer.
Thanks for help me. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 12, 2006 12:16 am |
|
|
The getc() function will wait for a character to come in.
The program will not advance beyond the getc() statement until
a character comes in.
The kbhit() function will check if a character is available.
If the purpose of your while() loop is to do several things, such as
check for a character, and also check the status of a push-button
switch, and also read an A/D converter, then you should use kbhit()
to see if you have a character before you call getc(). Example:
This code does many things in the loop, so you don't want to wait
at the getc() line for a character. kbhit() is called to check if a
character is ready before getc() is called. If a character is not
ready, then the code will call the other functions in the loop.
Code: |
while(1)
{
if(kbhit())
{
c = getc();
// Put other code here to do something
// with the character.
}
check_switch();
check_adc();
check_battery();
}
|
If the purpose of the while() loop is just to wait for a character to
come in and then take some action, then you can use getc() by
itself. Example:
Code: |
while(1)
{
c = getc();
// Put other code here to do something
// with the character.
}
|
|
|
|
|
|
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
|