PIC18F4510 Programming and MPLab X environment - Page 1
Forum section: electronics / general

author: MechEng87
author_rank: Contributor
timestamp: February 25, 2017, 09:54:46 pm
content: Hi everyone,I have a new prototype board that I built for myself with a Pic18f4510 on it, a 40Mhz Crystal and that's basically it. I am trying to program a Hello World for it to test the board and soldering just 4 leds on port A to blink at 1 sec interval. I have tried several example code on the web, with no success. I have a PicKit 2 as a programmer, using the XC8 compiler in Mplabx. Tried 3 times to make the board with no results. The program compiles and builds successfully, the pickit 2 loads the hex file and programs the chip successfully(or so it says), but no blinky light. Like I said I have tried 3 times to test my soldering and double checked the datasheet for the pin-out, wondering if its my config and header files? Not sure as I am new to MPlab and C programming for pics. I have my code inserted below I hope. :-)I thank you in advance for any advice you can give and help you can render to get this thing working.

author: cv007
author_rank: Frequent Contributor
timestamp: February 25, 2017, 10:35:22 pm
content: __delay_ms(10);Whatever other problems you may have, that is not enough time between blinking. I you want 1 sec interval, use __delay_ms(500), for half sec on, half sec off. With what you have, if everything else was working properly, you would get led's showing at 50% duty cycle- basically half brightness (you can't see the 50hz blinking)I would also add that you are only setting/clearing 1 pin (PORTA = 1; PORTA = 0;). To set 4 pins use PORTA = 0x0F;

author: Buriedcode
author_rank: Super Contributor
timestamp: February 25, 2017, 10:37:09 pm
content: I could be your '40MHz' crystal. Generally crystals that oscillate > 25MHz tend to be 3rd overtone crystals which requires a more complicated oscillator driver. I suspect if you really did have a 40MHz XTAL with a couple of say 10pF caps to ground - it won't oscillate at all.Try a 10MHz crystal and use the on-board x4 PLL. I believe the recommended range of crystal frequencies on 18F's is 4 - 12MHz. Just for testing try any value within this range, PLL enabled or not.

author: MechEng87
author_rank: Contributor
timestamp: February 25, 2017, 11:30:24 pm
content: Ok, so i had the LED on RA0 blinking at about .1 hz or so before by using __delay_us(10000). then i tried the suggestion by setting/clearing portA by 0x0F then 1x1F after to alter the state of the led. I've tried several variations of 0x1f, 1x1f,.... no luck, all 4 leds just stay on now instead of blinking at about 100ms. I know this isn't a situation where I need to ask" hey teach me how to write C code for this chip" but just trying to get a verification that i can send the chip a program an it will take it.

author: cv007
author_rank: Frequent Contributor
timestamp: February 26, 2017, 02:15:48 am
content: I'm not sure what you are referring to with the 1x1F, etc., but it appears you are not clearing the 4 low bits.Here's how to set the four lowest bits on porta-PORTA = 0x0F; //this also clears the high four bits// orPORTA = 0b00001111;// orPORTA = 15;and then to clear the four lower bits (and all the others too)-PORTA = 0x00;//orPORTA = 0b00000000;//orPORTA = 0;so, to blink-PORTA = 0x0F;delay(something);PORTA = 0;delay(something;or, to do each pin individually-RA0 = 1;RA1 = 1;RA2 = 1;RA3 = 1;delay(something);RA0 = 0;RA1 = 0;RA2 = 0;RA3 = 0;delay(something;

author: MechEng87
author_rank: Contributor
timestamp: February 26, 2017, 10:17:43 am
content: Wow, thanks guys this has been super helpful thus far. Much more helpful than trying to poke through the Microchip Forum.. Any ideas as to why the program will not build if i input a __delay_ms() of longer than 19 seconds? give me an error that the argument is too large. Again I have posted the code I am using below if it helps. It seems silly the way I have it implemented but its the only way I could get it to blink at a visible rate.

author: JPortici
author_rank: Super Contributor
timestamp: February 26, 2017, 10:44:26 am
content: check the XC8 compiler manual!

author: jaromir
author_rank: Unknown
timestamp: February 26, 2017, 05:33:33 pm
content: It is not time limit you see, rather number of loops limit - and this makes specific time limit, depending on your CPU clock, in your particular case it's 19ms. If you had 20 instead od 40MHz clock rate, your limit would be about 38ms.By the way, since XC8 1.40 release, there are new delay routines, allowing more cycles and consequently longer time.Alternatively, you can make function likeCode:void delay_x_ms (unsigned int howmuch){unsigned int i;for (i=0;i<howmuch;i++) __delay_ms(1);}and you can have (with slightly worse precision) delays up to 65,5 seconds.

author: cv007
author_rank: Frequent Contributor
timestamp: February 26, 2017, 08:06:03 pm
content: Some possibly useful suggestions-I have been using the 10F,12F, and 16F lately, and I use a simple system that works quite well for me. My projects are always on the smaller side (these things don't hold a lot of code anyway) so I usually have just 2 files- main.c and fuses.c. I have MPLABX generate the fuse settings, save them in fuses.c, create a main.c from a standard template I have with section header comments, macros, etc.I have tried MCC to generate code, but it usually ends up in a mess so I don't use that. I have a set of macros that take care of the pin stuff and all other peripheral code I simply look up in the datasheet- its not hard, and the benefit is you have to dig into the datasheet a little (that's a good thing). Over time, you can use your previous projects to lookup code that you can reuse.Here is a simple example of a main.c file-https://gist.github.com/anonymous/619b77bc725c5eb0d65c57749ccfd50a(those macros would probably need tweaking for your 18F, I don't think it has ANSEL for example)After you get a template setup that works the way you like, when you create a new project just use your blank template, fill in where needed, add your specific code, and have fun.I can jump around different pics (10/12/16) without much trouble. The projects all look the same, no surprises, nothing forgotten, and its just a matter of figuring out the peripherals you want to use and setting them up according to the datasheet.One other suggestion for anyone listening-use-#include <stdint.h>so that you can use uint8_t, uint16_t, int8_t, int32_t, etc.- instead of unsigned char, unsigned short, char, long, etc.that way you know exactly what you are dealing with (unless you always know what an unsigned int actually means for each cpu/compiler combo you use). The previous post reminded me that I never know exactly what an unsigned int actually is (I usually have a pretty good idea, but me and the compiler may not agree). It may be a known known when programming pc's, but with microcontrollers you never really know (except for char and unsigned char- thats pretty certain)./my_little_unimportant_rant_over

author: jaromir
author_rank: Unknown
timestamp: February 26, 2017, 09:19:42 pm
content: Quote from: cv007 on February 26, 2017, 08:06:03 pmIt is written in compiler manual. We are all reading manuals, aren't we?Quote from: cv007 on February 26, 2017, 08:06:03 pmUnfortunately it isn't. It is "Smallest addressable unit of the machine that can contain basic character set." which could be whatever. Not to mention historic platforms with 9- or 12-bit long chars, there are platforms where char is 16 bits, and types as uint8_t can't and don't exist there.I didn't want to bother OP with this dark and fuzzy corner of C language. Yes, using data types as "uint8_t" is mostly good idea (with understanding why it's good idea and when it isn't good idea), but I intentionally omitted it for sake of simplicity in this particular case.

author: cv007
author_rank: Frequent Contributor
timestamp: February 26, 2017, 10:30:00 pm
content: QuoteDatasheets, yes, compiler manuals, only when necessary.

author: Ammar
author_rank: Regular Contributor
timestamp: February 26, 2017, 10:47:12 pm
content: You probably need to set some registers correctly. Page 113 of the data sheet shows that there are 6 other registers associated with PORTA. You need to check each one and initialise them appropriately. This is always a headache when starting with a new micro, so all the best with it.

author: BrianHG
author_rank: Super Contributor
timestamp: February 27, 2017, 03:23:37 am
content: 2 main thing I see,1, you need to change PORTA from analog mode to digital mode, look up ANSELA...2. Like mentioned above, switch to a 10MHz crystal and set the PLL to 4x modes. If you want to use a 40MHz crystal, it should be an oscillator, not a crystal. (Personal recommendation as I haven't successfully used fundamental crystals above 27MHz under all test and temperature operating conditions)

author: cv007
author_rank: Frequent Contributor
timestamp: February 27, 2017, 05:16:58 am
content: QuoteMakes no difference when set to an output. Looks like he is blinking the led's now, but will have to figure out inputs eventually (his 18F has something other than ANSELA).

author: jaromir
author_rank: Unknown
timestamp: February 27, 2017, 08:54:26 am
content: Quote from: cv007 on February 27, 2017, 05:16:58 amMakes a lot of difference when you control the outputs through individual bit operations at PORTx registers, as per your previous example (RMW issue).Makes no difference when you control the outputs via LATx registers, though. Anyway, as a rule of thumb, one should read input port state via PORT registers and write output state into LAT registers. Writing to LAT is absolutely safe with regard to bit operations too.

author: cv007
author_rank: Frequent Contributor
timestamp: February 27, 2017, 03:57:32 pm
content: Well, it makes no difference to the OP, as his led's are blinkingI should have used LATA in my example I guess and explained the difference. He will have to figure out PORT, LAT, ANSEL, ADCON, CMCON, &=, |=, unsigned int, uint16_t, etc. on his own.

author: Howardlong
author_rank: Super Contributor
timestamp: February 28, 2017, 10:55:17 am
content: I realise this is a bit late, but others' comments on the 40MHz chrystal are quite right.Maximum HS crystal (and external osc) frequency is 20MHz for this device. You have to use the PLL to get 40MHz clock.

author: Luminax
author_rank: Regular Contributor
timestamp: March 01, 2017, 05:01:06 am
content: Hmm... I wonder where is the function declaration and the definition for the delays... I did find some externs inside htc.h and somewhere else. Maybe the function definition is precompiled.Regardless, It would be far more easier and beneficial to employ one of the TMR0 or TMR1 to generates an interrupt for you to control your blinking LED.In the event that you're using a static delay, although I have no idea of the inner working of those macros/externs, 9 times out of 10 it's a locking-loop that blocks code execution until it completes. And as I've recently been re-introduced to the faith of the FSM, I have to frown on this as the greatest of sin!Joking aside, TMR0 on 40MHz PLLD will give you a solid 10MHz (FOSC/4) timer clock giving you 25.6 us (8-bit x 1/10MHz Period) count or 6.5536 ms (16-bit x 1/10MHz Period) counts until overflow.you can also preload the Timer so that it counts a certain counts before overflowing ex:Targetted Period : 10 us;Period = 1/10MHz = 100 ns;Counts required to reach 10us = 10,000/100 => 100 counts256-100 = 156 = 0x9C => Preload value to TMR0Aaaand I just went into rantmode did I not