PIC Programming in Hi-Tech C

Discussion in 'Embedded Systems and Microcontrollers' started by jj_alukkas, Jul 31, 2011.

  1. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009

    Im new to PIc programming and as a part of the interest to flash some projects onto pic's, I bought a PICkit2 programmer. So now Im trying to learn how to write programs on my own in Hi-tech C. Im using MPlab 8.53 and hi-tech PICC 9.7 modules and a PIC16F628A chip and the internal OSC. The problem I am facing is that I can flash my 16F628 well enough and blink my led's but it acts totally wierd.

    Code ( (Unknown Language)):
    1. #include <HTC.H>
    2. #define _XTAL_FREQ 20000000
    6. void main()
    8. {
    9.     TRISA=0;
    10.     TRISB=0;
    11.     unsigned char i=0;
    14. while (1)
    15. {
    16. i=0;
    17. while (i<2){
    18. PORTA = 0xFF;
    19. _delay(100000);
    20. _delay(100000);
    21. PORTA = 0x00;
    22. _delay(100000);
    23. _delay(100000);
    24. i=i+1;
    25. }
    26. i=0;
    27. while (i<2){
    28. PORTB = 0xFF;
    29. _delay(100000);
    30. PORTB = 0x00;
    31. _delay(100000);
    32. i=i+1;
    33. }
    34. PORTB = 0x00;
    35. }
    36. }
    The port A led's blink 2 times, then the port B blinks Twice and whole repeats..

    However if I change the delay to _delay(1000), it doesnt blink at all.. and _delay_ms(100) gives unidetified errors.. how do I fix the delay problems??
    Last edited: Jul 31, 2011
  2. nerdegutta


    Dec 15, 2009

    I'm also using the PIC16F628 MCU for my projects. The following program flashes all the LEDS on PORT A and B.

    Code ( (Unknown Language)):
    2. /*
    4. Program:    Skeleton program        
    5. Description:To get going
    6. PIC:        PIC 16 F 628
    7. IDE:        MPLAB
    8. Compiler:    High tech C
    9. */
    11. #include <htc.h>
    13. #define _XTAL_FREQ 4000000
    15. /* Configuration */
    17. __CONFIG    (WDTDIS &
    18.             PWRTEN &
    19.             MCLREN &
    20.             BOREN &
    21.             LVPDIS &
    22.             DATUNPROT &
    23.             UNPROTECT &
    24.             INTIO);
    26. /* Prototyping the functions */
    27. void lightLED();
    28. void turnoffLED();
    31. /* Global variables */
    34. /* Functions */
    35. void lightLED()
    36. {
    37.     PORTA = 0b11111111;
    38.     PORTB = 0b11111111;
    40. __delay_ms(5000);
    42. }
    44. void turnoffLED()
    45. {
    46.     PORTA = 0b00000000;
    47.     PORTB = 0b00000000;
    49. __delay_ms(5000);
    51. }
    54. /* Main program */
    55. void main()
    56. {
    57. TRISA = 0b00000000;    // Setting all bits on port a to output
    58. TRISB = 0b00000000;    // Setting all bits on port b to output
    60. PORTA = 0b00000000; // Setting all bits on port a to LOW
    61. PORTB = 0b00000000;    // Setting all bits on port b to LOW
    63. CMCON = 0x07;    // Disabling the analogue comparators
    67. while (1)
    68. {
    69. lightLED();
    70. turnoffLED();
    72. } // end while
    74. }  //end main
    Depending on your circuit, that is...

    Don't know if this is any good for you, but its usually how I start.:)
  3. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Of course it would be usefull because I can 'know' all the ways to do something and then use whats best for the situation. I have a doubt though, why is this used?
    CMCON = 0x07; // Disabling the analogue comparators its not enabled in the beginning??
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Actually, they are already enabled and on. PIC pins that have both analog and digital functions default to analog on reset.
  5. AlexR

    Well-Known Member

    Jan 16, 2008
    Using the internal 4MHz oscillator the instruction _delay(1000) will only give you a 1mSec delay. This is much too short for the eye to see hence you will not see any LED blinks.

    The syntax for the mSec delay command is __delay_ms(100); with 2 leading underscores rather than just one as used in the simple instruction cycle delay routine.
  6. AlexR

    Well-Known Member

    Jan 16, 2008
    One further point.
    If you use the __delay_ms(); command you should correct the line
    Code ( (Unknown Language)):
    1. #define _XTAL_FREQ 20000000
    The __delay_ms(); routine uses the _XTAL_FREQ information to calculate the number of machine cycles required to produce a given delay so as you are using the chip's internal oscillator your clock frequency will be 4 MHz and that line should read
    Code ( (Unknown Language)):
    1. #define _XTAL_FREQ 4000000
  7. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Thank you for that, so can I vary the brightness of an led by varying the output level on just one pin in analogue mode? or do I need to use 4 pins tied up with resistors and connected to led and run a binary counter to do that?
    Sorry If that was a dumb question :p
  8. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Wow wow.. finally Got __delay_ms() working with this! Thank You a lot. Actually I was trying with 20Mhz clock and it keeps throwing errors on compile, so I was about to post a screenshot question for your first post, then saw this reply!! Now its working, thanks a lot. I was trying to do this since a day and all websites just give info that the xtal frq must be defined to use it not that it shud be set to 4mhz..!! Thank you!!

    Could you also tell me if I can test every change i make to the program by flashing it onto the pic, I mean, is it safe, or will I end the read write cycles allowed within a week with a 100 flashes a day? Or should I use some simulators instead? Chip is a 16F628a
  9. t06afre

    AAC Fanatic!

    May 11, 2009
    You can debug in MPLAB. But I do not almost sure you can not debug the 16f628 using the PICKIT hardware debugger. Without any extra hardware named a ICD header. An extra piece of hardware. Some PICs in the 16F series can be debugged directly by PICKIT 2. These are
    But I think all 18F series PICs that are compatible with PICKIT 2 can be debugged without any extra hardware.
    You can find info about it here
    Many errors can also be tracked by the software simulator in MPLAB. You will find my sticky her useful http://forum.allaboutcircuits.com/showthread.php?t=44852
    I would not worry about about your flash. Your chip can take about
    100000 write Flash cycles.
    I would also have changed to a newer version of HI-TECH C. In version 9.71Aa they changed the delay function so it could take MUCH larger numbers in the _delay() functions. The __delay_ms() functions use the latter functions. Now seconds delays is not a problem.
  10. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Ok, Now I understand why mplab throws an error when i select debugger>select tool>pickit2 !! but there is an extra 6th pin on the ICSP header on my pickit2 which is not used but goes directly to pin 6 of the 18F on the PICKIT, any Idea what it is for?

    It think for now I will be sticking to the 16F628 as its the only one I have in hand and is very cheap and small, but have to try on 18F's once I get a hold of all this.

    I checked that thread yesterday and downloaded that very important file you had linked, thanks for that, but Im not quite getting a hold of how to show the port led's while in the SIM mode..

    Yes, I tried that and something got messed up totally. It stopped recognizing my fuses and showed each of my fuse bits as an individual error, but I should try again because I could save a couple of lines of codes with that update.
  11. t06afre

    AAC Fanatic!

    May 11, 2009
    They have changed the config word naming style in the latest versions from 9.81 I think. You will find this in the header file. You can find the header here C:\Program Files\HI-TECH Software\PICC\9.81\include
    But I also include a part of it it here
    Code ( (Unknown Language)):
    3. // Config Register: CONFIG
    4. #define CONFIG               0x2007
    5. // Oscillator Selection bits
    6. // RC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, Resistor and Capacitor on RA7/OSC1/CLKIN
    7. #define FOSC_EXTRCCLK        0xFFFF
    8. // RC oscillator: I/O function on RA6/OSC2/CLKOUT pin, Resistor and Capacitor on RA7/OSC1/CLKIN
    9. #define FOSC_EXTRCIO         0xFFFE
    10. // INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
    11. #define FOSC_INTOSCCLK       0xFFFD
    12. // INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
    13. #define FOSC_INTOSCIO        0xFFFC
    14. // EC: I/O function on RA6/OSC2/CLKOUT pin, CLKIN on RA7/OSC1/CLKIN
    15. #define FOSC_ECIO            0xFFEF
    16. // HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
    17. #define FOSC_HS              0xFFEE
    18. // XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
    19. #define FOSC_XT              0xFFED
    20. // LP oscillator: Low-power crystal on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
    21. #define FOSC_LP              0xFFEC
    22. // Watchdog Timer Enable bit
    23. // WDT enabled
    24. #define WDTE_ON              0xFFFF
    25. // WDT disabled
    26. #define WDTE_OFF             0xFFFB
    27. // Power-up Timer Enable bit
    28. // PWRT disabled
    29. #define PWRTE_OFF            0xFFFF
    30. // PWRT enabled
    31. #define PWRTE_ON             0xFFF7
    32. // RA5/MCLR/VPP Pin Function Select bit
    33. // RA5/MCLR/VPP pin function is MCLR
    34. #define MCLRE_ON             0xFFFF
    35. // RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD
    36. #define MCLRE_OFF            0xFFDF
    37. // Brown-out Detect Enable bit
    38. // BOD enabled
    39. #define BOREN_ON             0xFFFF
    40. // BOD disabled
    41. #define BOREN_OFF            0xFFBF
    42. // Low-Voltage Programming Enable bit
    43. // RB4/PGM pin has PGM function, low-voltage programming enabled
    44. #define LVP_ON               0xFFFF
    45. // RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming
    46. #define LVP_OFF              0xFF7F
    47. // Data EE Memory Code Protection bit
    48. // Data memory code protection off
    49. #define CPD_OFF              0xFFFF
    50. // Data memory code-protected
    51. #define CPD_ON               0xFEFF
    52. // Flash Program Memory Code Protection bit
    53. // Code protection off
    54. #define CP_OFF               0xFFFF
    55. // 0000h to 07FFh code-protected
    56. #define CP_ON                0xDFFF
  12. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Thank You for this.. updating to the new one.. :)

    Btw, yesterday tried some crazy stuff.. I ripped out a vintage Nokia 6150 Long range cordless phone and found an HD44780 chip wired to the lcd.. tracked down the pins, removed the onboard uC, did some soldering and wired it down to the PIC16F628. Found an LCD Hitech c program in the samples folder and edited the ports and R/W pin data and flashed it, here's what I got :p


    Now could you help me wire switches to the port? I tried using a 10k resistor pulled up to Vcc and then a 330ohm pulled down through a switch to ground but it doesnt seems to work. can I use conditions like

    Code ( (Unknown Language)):
    1. #define LED_1 RA0
    2. #define LED_2 RA1
    3. #define SW RB3
    4. .
    5. .
    6. .
    7. .
    8. .
    9. TRISA=0;
    10.     TRISB=1;
    11.     unsigned char i=1;
    14. while (1)
    15. {
    16. i=SW;
    17. if(i==0)
    18. {
    19. LED_1 = 1;
    20. __delay_ms(100);
    21. __delay_ms(100);
    22. __delay_ms(100);
    23. LED_1 = 0;
    24. }
    25. else
    26. {
    27. LED_2 = 1;
    28. __delay_ms(100);
    29. __delay_ms(100);
    30. __delay_ms(100);
    31. LED_2 = 0;
    32. }
    33. i=i+1;
    34. }
    Is there any mistake in this?
    • up.jpg
      File size:
      123.6 KB
  13. stahta01


    Jun 9, 2011
    Code ( (Unknown Language)):
    2. #define SW RB3
    Code ( (Unknown Language)):
    2. TRISA=0;
    3. TRISB=1;
    You have defined all of Port A as Output;
    And, RB0 as input with the rest of Port B as Output.

    I assume this is wrong since you are trying to use RB3 as an input switch.

    Code ( (Unknown Language)):
    2. TRISB=8; /* set RB3 as input using 8=2^3 */
    Edit: Most students in the PIC Class I assist use this method
    Code ( (Unknown Language)):
    2. TRISB=0b00001000; /* set RB3 as input; the rest output */
    Tim S.
    Last edited: Aug 2, 2011
  14. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Yes, I realized it immediately after posting this and tested with both hex and binary values setting all of port b as inputs but I am not able to get it work. Can you help me on how to wire the switch?? presently it is wired as vcc to RB3 thru 10k resistor and RB3 to ground through switch. But I guess there is something wrong somewhere..
  15. stahta01


    Jun 9, 2011
    The switch should work like that; some people add a cap in case the switch is dirty to prevent multiple transitions from off to on.

    What LED is flashing?

    Does the switch seem to be always ON (high; Open) or always OFF(Low; Closed)?

    Tim S.
    Last edited: Aug 3, 2011
  16. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    I changed the whole setup again to see if it was my mistake.. so now RB0 is connected to GND through 10k resistor, N/O switch between RB0 and Vcc. 2 leds, one on RA0 and one on RA1.

    Now the RA1 led keeps lit up though I have pulled it low both through software and hardware and without the switch pressed. So switch always seems to be high, without an input even. Removing delays, does no good. :( No change on switch press.. Checked all ports, working fine otherwise, not damaged.
  17. stahta01


    Jun 9, 2011
    Code ( (Unknown Language)):
    2. if(PORTB=0b00000001)
    You set PORTB to be high on RB0 in this line.
    Also, this is always true statement.
    NOTE: "==" is not the same as "="

    Tim S.
  18. jj_alukkas

    Thread Starter Distinguished Member

    Jan 8, 2009
    Oh Man... what a stupid mistake... Thanks a lot for that..

    I realized I had another chance for a bug and put a low bit to the PORTA led after the delay so that it would switch off the led momentarily before the next state check and wouldnt keep it on and it worked!!

    Thank you a lot for helping me on this.!!