![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 26, 2009 12:42 am |
|
|
You have a large number of things that are wrong with your program.
You're using direct register access unnecessarily, when you should be
using CCS functions, or CCS library code invoked with a #use statement.
You're using illegal function parameters for some CCS functions.
You're enabling Global interrupts inside an isr.
There is way too much code in your program that is unnecessary.
Here is an example of a program that uses Timer1 interrupts to blink
an LED on Pin B0 at approximately a 1 Hz rate.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#int_timer1
void timer1_isr(void)
{
output_toggle(PIN_B0);
}
//======================================
void main()
{
output_low(PIN_B0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1);
} |
Here is an example of a "Hello World" program.
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//======================================
void main()
{
printf("Hello World\n\r");
while(1);
} |
Note how simple and easy it is when you use CCS functions and library code. |
|
![](templates/subSilver/images/spacer.gif) |
taniyyus
Joined: 25 Jul 2009 Posts: 3
|
|
Posted: Sun Jul 26, 2009 10:55 am |
|
|
Thank you for your reply.
I am actually used to using C18 and HiTech, recently moved to CCS.
Could you be kind enough to point out, illegal function parameters for some CCS functions.
What you saw of my in only a small portion, it has multiple other routines to handle RS232 and wireless radio communication, spi to control radio, capacitive sensing, etc.
Could you also explain why is it not recommended to enable global interrupts inside the isr?
Many thanks,
Taniyyu |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 26, 2009 11:14 am |
|
|
Quote: |
Could you be kind enough to point out, illegal function parameters for
some CCS functions. |
These lines use illegal parameters. The parameters are not allowed to be
OR'ed together for these functions. Only a single parameter is allowed.
Quote: | CLEAR_INTERRUPT(GLOBAL|INT_RTCC|INT_RB|INT_EXT|INT_AD|INT_TBE|INT_RDA|INT_TIMER1|INT_TIMER2|INT_CCP1|INT_CCP2|INT_SSP|INT_TIMER0|INT_RB0|INT_RB1|INT_RB2|INT_RB3|INT_RB4|INT_RB5|INT_RB6|INT_RB7);
DISABLE_INTERRUPTS(GLOBAL|INT_RTCC|INT_RB|INT_EXT|INT_AD|INT_TBE|INT_RDA|INT_TIMER1|INT_TIMER2|INT_CCP1|INT_CCP2|INT_SSP|INT_TIMER0|INT_RB0|INT_RB1|INT_RB2|INT_RB3|INT_RB4|INT_RB5|INT_RB6|INT_RB7); |
Quote: | Could you also explain why is it not recommended to enable global interrupts inside the isr? |
Because nested interrupts are not supported. Also, the PIC will
automatically re-enable Global interrupts at the end of the CCS
interrupt handler code. It executes a RETFIE instruction which
does this. |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Sun Jul 26, 2009 12:57 pm |
|
|
Thank you for your suggestion. It certainly behaves better with your suggestions. So I have decided to convert the whole project to use CCS functions. Now, please bear with me because I am recent convert, some of the question I ask might be irrelevant and illogical.
Now I have a few questions:
I need to the control over most of the peripherals so it is essential that I can turn these on/off and also have access to the interrupt flags/enable bits.
So my question are,
1.what is the difference in using #use SPI (.....) or #use RS232 (....) and setup_SPI(...) or setup_uart(....) respectively.
2. how do i
a)disable SPI
b) enable/disable tramit/receive interrupt (TXIE,TXIF.RCIE,RCIF) on UART
c) change/add defines to the 16F727.h or any other devices' header files. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 26, 2009 1:35 pm |
|
|
So my question are,
Quote: |
1.what is the difference in using #use SPI (.....) or #use RS232 (....) and
setup_SPI(...) or setup_uart(....) respectively. |
#rs232() invokes the CCS "library" code to use the hardware UART
or a software UART (done by "bit-banging").
setup_uart() is used to change the baudrate of the hardware UART
at runtime. This is in the CCS manual.
#use spi() invokes the CCS library routines for SPI. However, this
method is new. It may still have some bugs, depending upon your
compiler version. The default settings of the #use spi() library code
are not always the normal expected settings. To ensure the correct
settings are used, you must specify more parameters than perhaps
you expected to. But, #use spi() has the ability to do software SPI
in addition to hardware SPI. The spi_xfer() function is used with
the #use spi() library, to transmit and receive data.
setup_spi() is the older, more reliable method of using the hardware
SPI module. spi_write() and spi_read() are used to transfer data
with this method.
Quote: |
2. how do i
a)disable SPI |
This line will clear the SSPCON1 register, disabling hardware SPI:
However the TRIS settings for the SDO and SCLK pins will be left as
output pins. In other words, setup_spi() with the correct parameters
will configure the TRIS. But setup_spi(FALSE) does not restore all SPI
pins to input mode.
Quote: | b) enable/disable tramit/receive interrupt (TXIE,TXIF.RCIE,RCIF) on UART |
Use these lines:
Code: | enable_interrupts(INT_TBE);
disable_interrupts(INT_TBE);
enable_interrupts(INT_RDA);
disable_interrupts(INT_RDA); |
This is in the manual. The list of constants used to enable/disable
interrupts is at the end of the .h file for your PIC.
Quote: | c) change/add defines to the 16F727.h or any other devices' header files.
|
Don't do that. Don't change any #defines in that file. If you do, the
CCS functions may work correctly anymore. You will be sabotaging
your program.
Download the CCS manual and study the functions in it.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf |
|
![](templates/subSilver/images/spacer.gif) |
taniyyus
Joined: 25 Jul 2009 Posts: 3
|
|
Posted: Tue Jul 28, 2009 9:51 pm |
|
|
I am trying to convert my project to use only CCS functions now.
Could you help me with the following:
1. How do I use the the following to check if my OSC is stable:
Code: |
setup_oscillator(OSC_STATE_LOCKED);
setup_oscillator(OSC_STATE_STABLE 8);
|
are the above lines correct?
2. How do I configure APFCON register?
3. How do I configure PortB Interrupt on Change (IOCB)?
4. How do I configure ANSELx?
5. I usually poll TRMT (TXSTA,0) to see if the UART is ready to transmit again, how can I achieve this with CCS functions.
I understand that I have many questions. But with a little help, I can get used to the compiler and understand it better.
I also have questions regarding the Capacitive Sensing Module but I will leave that for later on a new thread.
Many thanks in advance.
Regards,
Taniyyus |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 29, 2009 1:18 pm |
|
|
Quote: |
1. How do I use the the following to check if my OSC is stable:
setup_oscillator(OSC_STATE_LOCKED);
setup_oscillator(OSC_STATE_STABLE 8);
are the above lines correct?
|
No. The 16F727.h file says in oscillator section:
Quote: | // Constants used in setup_oscillator() are:
.
.
.
#define OSC_8MHZ 0x120
// Result may be (ignore all other bits)
#define OSC_STATE_LOCKED 4
#define OSC_STATE_STABLE 8
|
"Result" means the return value of the function, not the parameter.
"Ignore all other bits" means you must use those constants to mask
down the return value. Then test if those bits are set. Example:
Code: | #include <16F727.H>
#fuses INTRC_IO, NOWDT, PLLEN
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//====================================
void main()
{
int8 i;
// Allow up to 100 ms for internal oscillator to lock and stabilize.
for(i = 0; i < 100; i++)
{
if(setup_oscillator(OSC_8MHZ) & (OSC_STATE_LOCKED | OSC_STATE_STABLE))
break;
delay_ms(1);
}
while(1);
}
|
Quote: | 2. How do I configure APFCON register? |
Look up the register address in this section of the 16F727 data sheet:
Quote: | FIGURE 2-6: PIC16F726/LF726 AND PIC16F727/LF727 SPECIAL FUNCTION REGISTERS |
Declare the address of the APFCON register with a #byte statement in
a line of code above main(). Then within main() or in another function,
set the APFCON register to whatever 8-bit value you desire, with one line
of code.
Quote: | 3. How do I configure PortB Interrupt on Change (IOCB)? |
Same as above.
Quote: | 4. How do I configure ANSELx? |
Use the setup_adc_ports() function. Look in the 16F727.h file for the
constants that are used as parameters for that function. Individual
"sANx" constants may be bitwise-OR'ed together to configure multiple
i/o pins as analog pins.
Quote: |
5. I usually poll TRMT (TXSTA,0) to see if the UART is ready to transmit
again, how can I achieve this with CCS functions. |
You would have to define the bit address of the TRMT bit with a #bit
statement, and then test TRMT with a line of code. But, the CCS putc()
function tests the TXIF bit in a loop before it transmits data, so you don't
need to test TRMT. Here's the putc() code:
Quote: | .......... putc(0x55);
0021: MOVLW 55
0022: BTFSS PIR1.TXIF
0023: GOTO 022
0024: MOVWF TXREG |
You can study what the compiler does by compiling a short test program
and then examine the .LST file. That's where the code above came from. |
|
![](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
|