|
|
View previous topic :: View next topic |
Author |
Message |
Chris Burger Guest
|
LEDs are NOT changing |
Posted: Sun Jul 20, 2003 2:50 pm |
|
|
I'm trying to change my programs in C. I'm NOT able to get
this program work. The LEDs on PORTB are not changing.
What is wrong??
regards
Chris Burger
The Netherlands
// Settings:
// 4Mhz resonator
// All Port A inputs
// Port B outputs tied to LEDs (low-active)
#include <16f84.h>
#fuses xt,nowdt,put,noprotect
// xt=crystal; nowdt=no watchdog timer
// put=powerup timer; noprotect=memory protection off
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte PORTA = 0x05
#byte PORTB = 0x06
#bit ra3 = 0x05.3
byte times, count, point;
#use delay (clock=4000000) // clock freq = 4MHz
#int_rtcc
timer_isr(int times)
{
--times;
}
void main(void)
{
byte const table[18] = {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF, 0xE7,0xC3,0x81,0x00,0x00,0x18,0x3C,0x7E,0xFF};
TRISA=0x1f; // make portA all inputs
TRISB=0x00; // make portB all outputs
PORTB = 0xFF; // switch all LEDs off
set_rtcc(0); // clear clock
setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
// setup clock divisor to 128
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
times = 7;
count = 9;
if (ra3 == 1) // is pinA3 1 -> point = 00
point = 0x00;
if (ra3 == 0)
point = 0x09; // is pinA3 0 -> point = 09
PORTB = table[point]; // PORTB next figure
++point;
--count;
while(1) // do always
{
if (times == 0)
{
PORTB = table[point]; // PORTB next figure
++point;
--count;
if (count == 0)
{
count = 9;
if (ra3 == 1) // is pinA3 1 -> point = 00
point = 0x00;
if (ra3 == 0)
point = 0x09; // is pinA3 0 -> point = 09
};
times=7;
}
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516201 |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
Re: LEDs are NOT changing |
Posted: Sun Jul 20, 2003 5:14 pm |
|
|
:=I'm trying to change my programs in C. I'm NOT able to get
:=this program work. The LEDs on PORTB are not changing.
:=What is wrong??
:=
:=regards
:=Chris Burger
:=The Netherlands
:=
:=
:=// Settings:
:=// 4Mhz resonator
:=// All Port A inputs
:=// Port B outputs tied to LEDs (low-active)
:=
:=#include <16f84.h>
:=#fuses xt,nowdt,put,noprotect
:= // xt=crystal; nowdt=no watchdog timer
:= // put=powerup timer; noprotect=memory protection off
:=#byte TRISA = 0x85
:=#byte TRISB = 0x86
:=#byte PORTA = 0x05
:=#byte PORTB = 0x06
:=#bit ra3 = 0x05.3
:=byte times, count, point;
:=#use delay (clock=4000000) // clock freq = 4MHz
:=
:=#int_rtcc
:=timer_isr(int times)
:={
:= --times;
:=}
:=
:=void main(void)
:={
:=
:=byte const table[18] = {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF, 0xE7,0xC3,0x81,0x00,0x00,0x18,0x3C,0x7E,0xFF};
:=
:= TRISA=0x1f; // make portA all inputs
:= TRISB=0x00; // make portB all outputs
:= PORTB = 0xFF; // switch all LEDs off
:= set_rtcc(0); // clear clock
:= setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
:= // setup clock divisor to 128
:= enable_interrupts(INT_RTCC);
:= enable_interrupts(GLOBAL);
:=
:= times = 7;
:= count = 9;
:= if (ra3 == 1) // is pinA3 1 -> point = 00
:= point = 0x00;
:= if (ra3 == 0)
:= point = 0x09; // is pinA3 0 -> point = 09
:= PORTB = table[point]; // PORTB next figure
:= ++point;
:= --count;
:=
:= while(1) // do always
:= {
:= if (times == 0)
:= {
:= PORTB = table[point]; // PORTB next figure
:= ++point;
:= --count;
:= if (count == 0)
:= {
:= count = 9;
:= if (ra3 == 1) // is pinA3 1 -> point = 00
:= point = 0x00;
:= if (ra3 == 0)
:= point = 0x09; // is pinA3 0 -> point = 09
:= };
:= times=7;
:= }
:= }
:=}
CCS does't support directly pointing to constant strings in ROM yet. They are working on it but it will generate a lot of code because of the architecture of the PIC with separate addressing.
You can get around it by copying the byte to RAM first.
byte led_pattern;
led_pattern = table[point];
PORTB = led_pattern;
Regards
Kenny
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516202 |
|
|
Chris Burger Guest
|
Re: LEDs are NOT changing |
Posted: Mon Jul 21, 2003 1:32 am |
|
|
Hello Kenny,
Thank you very much for your reaction. I have made the changes but there is no change in the program.
By the way in the first part of MAIN the statement PORTB = table[point] is executed correctly because the pattern of one of the two groups is shown by the LEDs.
I’m afraid that there is a problem with the ISR. Is the Interrupt Subroutine correct?
timer_isr(int times) { --times;}
kind regards,
Chris Burger
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516216 |
|
|
Chris Burger Guest
|
Re: LEDs are NOT changing |
Posted: Mon Jul 21, 2003 2:05 am |
|
|
I have changed the ISR as followed:
#int_rtcc
timer_isr()
{
--times;
}
and still with the statemnt:
PORTB = table[point];
The program is now working. I don’t understand why you are NOT allowed to pass the argument 'times' to the ISR?
kind regards
Chris Burger
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516217 |
|
|
R.J.Hamlett Guest
|
Re: LEDs are NOT changing |
Posted: Mon Jul 21, 2003 2:30 am |
|
|
:=I'm trying to change my programs in C. I'm NOT able to get
:=this program work. The LEDs on PORTB are not changing.
:=What is wrong??
:=
:=regards
:=Chris Burger
:=The Netherlands
:=
:=
:=// Settings:
:=// 4Mhz resonator
:=// All Port A inputs
:=// Port B outputs tied to LEDs (low-active)
:=
:=#include <16f84.h>
:=#fuses xt,nowdt,put,noprotect
:= // xt=crystal; nowdt=no watchdog timer
:= // put=powerup timer; noprotect=memory protection off
:=#byte TRISA = 0x85
:=#byte TRISB = 0x86
:=#byte PORTA = 0x05
:=#byte PORTB = 0x06
:=#bit ra3 = 0x05.3
:=byte times, count, point;
:=#use delay (clock=4000000) // clock freq = 4MHz
:=
:=#int_rtcc
:=timer_isr(int times)
:={
:= --times;
:=}
:=
:=void main(void)
:={
:=
:=byte const table[18] = {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF, 0xE7,0xC3,0x81,0x00,0x00,0x18,0x3C,0x7E,0xFF};
:=
:= TRISA=0x1f; // make portA all inputs
:= TRISB=0x00; // make portB all outputs
:= PORTB = 0xFF; // switch all LEDs off
:= set_rtcc(0); // clear clock
:= setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
:= // setup clock divisor to 128
:= enable_interrupts(INT_RTCC);
:= enable_interrupts(GLOBAL);
:=
:= times = 7;
:= count = 9;
:= if (ra3 == 1) // is pinA3 1 -> point = 00
:= point = 0x00;
:= if (ra3 == 0)
:= point = 0x09; // is pinA3 0 -> point = 09
:= PORTB = table[point]; // PORTB next figure
:= ++point;
:= --count;
:=
:= while(1) // do always
:= {
:= if (times == 0)
:= {
:= PORTB = table[point]; // PORTB next figure
:= ++point;
:= --count;
:= if (count == 0)
:= {
:= count = 9;
:= if (ra3 == 1) // is pinA3 1 -> point = 00
:= point = 0x00;
:= if (ra3 == 0)
:= point = 0x09; // is pinA3 0 -> point = 09
:= };
:= times=7;
:= }
:= }
:=}
Two things 'leap out at me' here. You are manually controlling TRIS, but nowhere have you added the configuration line #use fast_io(A) (or B or C). Now though you don't use the compilers own I/O functions, I don't know whether it may still insert TRIS control lines unless this is added to tell it not to. This could result in unexpected operations...). Hence I'd add these declarations to be 'safe'.
Your definition of the timer ISR is wrong.
The ISR's, should allways be defined as
void function(void)
With your current definition, you are telling the code that this function will receive a _local_ variable called 'timer', passed to it on the function stack. No such variable will be passed (nothing is passed to the ISR's, unless you re-write the INT_GLOBAL routine, and do this yourself), so the update of 'timer' inside the ISR, will instead result in corruption of part of the memory.
Because 'timer' is allready declared as a global variable (anything declared outside the functions, is global), you do not need to (and should not) try to 'pass' this to the ISR. Just remove the 'int timer' declaration from the ISR definition, and the code will start updating the 'right' variable...
Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516219 |
|
|
Ron Guest
|
Re: LEDs are NOT changing |
Posted: Mon Jul 21, 2003 3:46 am |
|
|
<font face="Courier New" size=-1>:=The program is now working. I don’t understand why you are NOT allowed to pass the argument 'times' to the ISR?
There is nothing like passing arguments to a ISR function, because there is no function call. The ISR just executes at the time an interrupt is triggered.
Regards,
Ron</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516221 |
|
|
Dave Yeatman Guest
|
Re: LEDs are NOT changing |
Posted: Mon Jul 21, 2003 6:53 am |
|
|
Chris,
As was pointed out above you cannot pass a parameter to the ISR because you are NEVER calling it DIRECTLY. It is only called by the HW when the interrupt occurs. This is NOT a fault of the compiler.
If you took off the interrupt header and just called it as a standard function or procedure you can pass the parm with no problem.
One other side issue that was raised earlier and I want to point out again is that you are using the same name for a local variable as is used for a global. This is not a good thing to do in any programming language and you should always avoid doing this when possible if for no other reason than readability.
Good Luck!
dave
:=Hello Kenny,
:=Thank you very much for your reaction. I have made the changes but there is no change in the program.
:=By the way in the first part of MAIN the statement PORTB = table[point] is executed correctly because the pattern of one of the two groups is shown by the LEDs.
:=I’m afraid that there is a problem with the ISR. Is the Interrupt Subroutine correct?
:=timer_isr(int times) { --times;}
:=
:=kind regards,
:=Chris Burger
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516224 |
|
|
R J Hamlett Guest
|
Re: LEDs are NOT changing |
Posted: Tue Jul 22, 2003 10:15 am |
|
|
:=I have changed the ISR as followed:
:=#int_rtcc
:=timer_isr()
:={
:= --times;
:=}
:=
:=and still with the statemnt:
:=PORTB = table[point];
:=
:=The program is now working. I don’t understand why you are NOT allowed to pass the argument 'times' to the ISR?
:=
:=kind regards
:=Chris Burger
Think about it for a moment.
Passing an argument, requires two 'ends'. The function that receives the variable, and the 'calling statement', where the variable is passed to the function. Now you _never_ 'call' the ISR. This is done automatically, as a result of the hardware event, and could occur anywhere at all in the main code, and variables could have different meanings at different points in the code. There is no provision to control the 'calling' end of the interrupt operation, and hence no ability to define a variable to be 'passed' with the ISR.
This is _not_ a CCS limitation. The same thing would happen in Microsoft 'C', or 'C' under Unix, when writing an ISR. You have to write such functions, to meet the calling convention defined by the interrupt hardware, and nothing else...
Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516246 |
|
|
Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
Re: LEDs are NOT changing |
Posted: Tue Jul 22, 2003 4:48 pm |
|
|
:=Hello Kenny,
:=Thank you very much for your reaction. I have made the changes but there is no change in the program.
:=By the way in the first part of MAIN the statement PORTB = table[point] is executed correctly because the pattern of one of the two groups is shown by the LEDs.
:=I’m afraid that there is a problem with the ISR. Is the Interrupt Subroutine correct?
:=timer_isr(int times) { --times;}
:=
:=kind regards,
:=Chris Burger
Sorry for the bad advice. Forgot to engage brain and missed the real problems that the other posters saw.
Kenny
___________________________
This message was ported from CCS's old forum
Original Post ID: 144516267 |
|
|
|
|
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
|