PIC Programming in Hi-Tech C

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
Hello,

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.

Rich (BB code):
#include <HTC.H>
#define _XTAL_FREQ 20000000 

__CONFIG(INTIO & WDTDIS & PWRTDIS & BORDIS & LVPDIS );

void main()

{
    TRISA=0;
    TRISB=0;
    unsigned char i=0;


while (1)
{
i=0;
while (i<2){
PORTA = 0xFF;
_delay(100000);
_delay(100000);
PORTA = 0x00;
_delay(100000);
_delay(100000);
i=i+1;
}
i=0;
while (i<2){
PORTB = 0xFF;
_delay(100000);
PORTB = 0x00;
_delay(100000);
i=i+1;
}
PORTB = 0x00;
}
}
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:

nerdegutta

Joined Dec 15, 2009
2,684
Hi,

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

Rich (BB code):
/*

Program:    Skeleton program        
Description:To get going
PIC:        PIC 16 F 628
IDE:        MPLAB 
Compiler:    High tech C
*/

#include <htc.h>

#define _XTAL_FREQ 4000000

/* Configuration */

__CONFIG    (WDTDIS &
            PWRTEN &
            MCLREN &
            BOREN &
            LVPDIS &
            DATUNPROT &
            UNPROTECT &
            INTIO);

/* Prototyping the functions */
void lightLED();
void turnoffLED();


/* Global variables */


/* Functions */
void lightLED()
{
    PORTA = 0b11111111;
    PORTB = 0b11111111;

__delay_ms(5000);

}

void turnoffLED()
{
    PORTA = 0b00000000;
    PORTB = 0b00000000;

__delay_ms(5000);

}


/* Main program */
void main()
{
TRISA = 0b00000000;    // Setting all bits on port a to output
TRISB = 0b00000000;    // Setting all bits on port b to output

PORTA = 0b00000000; // Setting all bits on port a to LOW
PORTB = 0b00000000;    // Setting all bits on port b to LOW

CMCON = 0x07;    // Disabling the analogue comparators



while (1)
{
lightLED();
turnoffLED();

} // end while

}  //end main
Depending on your circuit, that is...

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

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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??
 

ErnieM

Joined Apr 24, 2011
8,377
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??
Actually, they are already enabled and on. PIC pins that have both analog and digital functions default to analog on reset.
 

AlexR

Joined Jan 16, 2008
732
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.
 

AlexR

Joined Jan 16, 2008
732
One further point.
If you use the __delay_ms(); command you should correct the line
Rich (BB code):
#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
Rich (BB code):
#define _XTAL_FREQ 4000000
 

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
Actually, they are already enabled and on. PIC pins that have both analog and digital functions default to analog on reset.
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
 

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
One further point.
If you use the __delay_ms(); command you should correct the line
Rich (BB code):
#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
Rich (BB code):
#define _XTAL_FREQ 4000000
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
 

t06afre

Joined May 11, 2009
5,934
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
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
PIC16F87, 88
PIC16F818, 819
PIC16F870, 871, 872, 873, 874, 876, 877
PIC16F873A, 874A, 876A, 877A
PIC16F882, 883, 884, 886, 887
PIC16F913, 914, 916, 917
PIC16F946
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
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en027813
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.
 

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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
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?


But I think all 18F series PICs that are compatible with PICKIT 2 can be debugged without any extra hardware.
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.

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 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..

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.
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.
 

t06afre

Joined May 11, 2009
5,934
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.
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
Rich (BB code):
// Config Register: CONFIG
#define CONFIG               0x2007
// Oscillator Selection bits
// RC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, Resistor and Capacitor on RA7/OSC1/CLKIN
#define FOSC_EXTRCCLK        0xFFFF
// RC oscillator: I/O function on RA6/OSC2/CLKOUT pin, Resistor and Capacitor on RA7/OSC1/CLKIN
#define FOSC_EXTRCIO         0xFFFE
// INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
#define FOSC_INTOSCCLK       0xFFFD
// INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
#define FOSC_INTOSCIO        0xFFFC
// EC: I/O function on RA6/OSC2/CLKOUT pin, CLKIN on RA7/OSC1/CLKIN
#define FOSC_ECIO            0xFFEF
// HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
#define FOSC_HS              0xFFEE
// XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
#define FOSC_XT              0xFFED
// LP oscillator: Low-power crystal on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
#define FOSC_LP              0xFFEC
// Watchdog Timer Enable bit
// WDT enabled
#define WDTE_ON              0xFFFF
// WDT disabled
#define WDTE_OFF             0xFFFB
// Power-up Timer Enable bit
// PWRT disabled
#define PWRTE_OFF            0xFFFF
// PWRT enabled
#define PWRTE_ON             0xFFF7
// RA5/MCLR/VPP Pin Function Select bit
// RA5/MCLR/VPP pin function is MCLR
#define MCLRE_ON             0xFFFF
// RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD
#define MCLRE_OFF            0xFFDF
// Brown-out Detect Enable bit
// BOD enabled
#define BOREN_ON             0xFFFF
// BOD disabled
#define BOREN_OFF            0xFFBF
// Low-Voltage Programming Enable bit
// RB4/PGM pin has PGM function, low-voltage programming enabled
#define LVP_ON               0xFFFF
// RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming
#define LVP_OFF              0xFF7F
// Data EE Memory Code Protection bit
// Data memory code protection off
#define CPD_OFF              0xFFFF
// Data memory code-protected
#define CPD_ON               0xFEFF
// Flash Program Memory Code Protection bit
// Code protection off
#define CP_OFF               0xFFFF
// 0000h to 07FFh code-protected
#define CP_ON                0xDFFF
 

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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

Rich (BB code):
#define LED_1 RA0
#define LED_2 RA1
#define SW RB3
.
.
.
.
.
TRISA=0;
    TRISB=1;
    unsigned char i=1;


while (1)
{
i=SW;
if(i==0)
{
LED_1 = 1;
__delay_ms(100);
__delay_ms(100);
__delay_ms(100);
LED_1 = 0;
}
else
{
LED_2 = 1;
__delay_ms(100);
__delay_ms(100);
__delay_ms(100);
LED_2 = 0;
}
i=i+1;
}
Is there any mistake in this?
 

Attachments

stahta01

Joined Jun 9, 2011
133
Rich (BB code):
#define SW RB3
Rich (BB code):
TRISA=0; 
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.

Rich (BB code):
TRISB=8; /* set RB3 as input using 8=2^3 */
Edit: Most students in the PIC Class I assist use this method
Rich (BB code):
TRISB=0b00001000; /* set RB3 as input; the rest output */
Tim S.
 
Last edited:

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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..
 

stahta01

Joined Jun 9, 2011
133
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:

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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.

#include <HTC.H>
#define _XTAL_FREQ 4000000

__CONFIG(INTIO & WDTDIS & PWRTDIS & BORDIS & LVPDIS );

void main()

{
TRISA=0b00000000;
TRISB=0b00000001;
PORTA=0b00000000;
while(1)
{
if(PORTB=0b00000001)
{
PORTA=0b00000010;
__delay_ms(100);
__delay_ms(100);
__delay_ms(100);
__delay_ms(100);
}
else
PORTA=0b00000001;
}
}
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.
 

stahta01

Joined Jun 9, 2011
133
Rich (BB code):
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.
 

Thread Starter

jj_alukkas

Joined Jan 8, 2009
753
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.!!
 
Top