|
|
View previous topic :: View next topic |
Author |
Message |
imbue
Joined: 28 May 2005 Posts: 13
|
18F2455 Problems |
Posted: Sat May 28, 2005 2:21 am |
|
|
I am working on my first 18F project, and it's giving me a lot of trouble. I am running into several problems, and I'm not sure if they are related or not. When I program the PIC, delay_ms() doesn't seem to work, and printf() doesn't seem to output numbers properly. The odd thing is that everything works perfectly in MPLAB SIM, it just don't seem to work on the real pic.
Anyway, here is a short program to demostrate my problem.
Code: | #include <18F2455.h>
#fuses NOWDT,WDT128,INTRC_IO, NOPROTECT, BROWNOUT, BORV20, NOPUT, NOCPD, NOSTVREN, NOLVP, NOWRT, NOWRTD, NOIESO, NOFCMEN, NOPBADEN, NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, LPT1OSC, NOMCLR, XINST, PLL1
#use delay(clock=8000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,PARITY=N,bits=8)
void main();
#INT_RDA
void rda_handler(){
unsigned int8 input = 0;
printf("\n\rRDA_Handler().\n\r");
while(KBHIT()){
input = getc();
putc(input);
}
}
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
printf("ONLINE.\n\r");
{
unsigned int8 count = 0;
for(count = 1; count <= 20; count++){
printf("Count = %u.\n\r", count);
delay_ms(1000);
}
}
while(1){}
} |
Now in MPLAB SIM this works perfectly. The delay delays the right amount of time, the UART sim shows me that printf works correctly, and the UART interrupt works for input.
Once I load the program into a real pic things seem to change. First of all, the program seems to run instantly with no delays (at least it's so fast I can't tell). Also, printf "%u" outputs a "*" instead of the number that it's passed. Finally, I cannot get the UART input to work. Here is a log of the RS-232 port.
Quote: | ONLINE.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D]
Count[20]=[20]*.[0A][0D] |
If anyone has any advice, it'd help a ton.
Thanks! |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat May 28, 2005 8:25 am |
|
|
A very common misunderstanding is that of the RDA interrupt.
The pic services this interrupt when it has a char in the UART receive buffer.
The A in UART stands for asynchronous which means you can't most often predict when data is transferred. If you put a printf in an interrupt service routine it will consume time transmitting chars that will prevent incoming chars from being recognized. Use a circular buffer to capture the incoming chars and return control to the main routine as fast as you possibly can. The pointer to the last read char and the pointer to the next availble free position in your circular buffer will tell your main routine how much you captured. Read the pointers in a loop and do all the printf in your main routine. You can get away with a simple echo via putc of the incomming char inside your interrupt routine but more than that is asking for random trouble.
There are many examples of circular buffer routines if you search the forum study them and many of the issues you now have will become clear to you.
The simulator works cause it is by nature synchronous as it simulates receipt of chars. The real UART gets data asynchronously. |
|
|
imbue
Joined: 28 May 2005 Posts: 13
|
|
Posted: Sat May 28, 2005 12:50 pm |
|
|
Thanks for your input. I've read before not to waste time in interrupts, but this program was just a quick hack to try and demonstrate my problem with. It also seems that the interrupt never gets called, so can it really be causing any problems? (not that it wouldn't in the future)
If I completely remove the interrupt from the program, I still have the same problems in main(). Why won't the printf() and delay_ms() inside of main() work?
Thanks. |
|
|
Ttelmah Guest
|
|
Posted: Sun May 29, 2005 2:39 pm |
|
|
Move your #use delay statement, in front of your fuses statement.
If this doesn't fix the problem, try adding:
setup_oscillator(OSC_8MHZ);
at the start of your main, after the variables are initialised.
The delay statement has to be in front of the fuse statement for the oscillator to be correctly programmed. In the simulator, you set the oscillator frequency elsewhere, so this being wrong will not give problems. Some compiler versions do not automatically set the oscillator, and on these the setup_oscillator line is needed.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 29, 2005 3:01 pm |
|
|
Quote: |
Move your #use delay statement, in front of your fuses statement. |
I think the #fuses statement (with INTRC_IO) has to come first, before
the #use delay statement. Then the compiler will setup the internal oscillator.
http://www.ccsinfo.com/forum/viewtopic.php?t=21231 |
|
|
imbue
Joined: 28 May 2005 Posts: 13
|
|
Posted: Sun May 29, 2005 4:39 pm |
|
|
When I move #use delay before the #fuses then the RS-232 only receives garbage (a mix of 0x00 and 0x80). When I then add setup_oscillator things return to working just like before I made any changes.
By the way, since 8mhz is the fastest this PIC can run on it's internal RC, wouldn't an incorrectly setup oscillator run delays slower, not faster?
Also, if I change the delay to 60,000 ms then it still seems to run instantly.
I am using PCWH 3.224. |
|
|
imbue
Joined: 28 May 2005 Posts: 13
|
|
Posted: Sun May 29, 2005 5:05 pm |
|
|
Can someone please explain this error message to me?
Quote: | The Extended CPU Mode configuration bit is enabled, but the program that was loaded was not built using extended CPU instructions. |
Whenever I compile the project in MPLAB IDE I get that error message, but when I compile in PCWH I don't.
Thanks. |
|
|
imbue
Joined: 28 May 2005 Posts: 13
|
|
Posted: Sun May 29, 2005 5:28 pm |
|
|
I changed the XINST fuse to NOXINST and now everything works perfectly. I would still be interested in why this is though, and why CCS makes XINST the default for a new project if it breaks eveything.
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
imbue
Joined: 28 May 2005 Posts: 13
|
|
Posted: Sun May 29, 2005 8:20 pm |
|
|
Alright, I emailed them. |
|
|
|
|
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
|