• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Hi-Tech C Compiler: What am I doing wrong?

Status
Not open for further replies.

micro571

New Member
I am trying to program a PIC16F877A. I know my hardware is good because I can load on the LED blink program from here: blink a LED and it works.

I am trying to do an led blink program using the Hi-Tech C Compiler. I have it specified as the tool chain in MPLab.

Here is my code:
#include <pic.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "delay.h"
//#include "delay.c"
//void delay(void);
//#define _16F877
// __CONFIG(UNPROTECT|BODEN|FOSC1|BKBUG|WRT);
//__CONFIG( XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT );
void main (){

ADCON1 =0x06 ; // Changes PORTA to digital
CMCON = 0x07 ; // Disable analog comparators
PORTA = 0x00 ;
PORTB = 0X00 ;
PORTC = 0X00 ;
PORTD = 0X00 ;
PORTE = 0X00 ;
TRISA = 0x00 ; // Configure PORTA as output
TRISB = 0X00 ;
TRISC = 0X00 ;
TRISD = 0X00 ;
TRISE = 0X00 ;

while(1){
PORTA = 0XFF ;
PORTB = 0XFF ;
PORTC = 0XFF ;
PORTD = 0XFF ;
PORTE = 0Xff ;
DelayMs(500);
PORTA = 0X00 ;
PORTB = 0X00 ;
PORTC = 0X00 ;
PORTD = 0X00 ;
PORTE = 0X00 ;
DelayMs(500);
}
}

The code compiles, but nothing happens when I load the hex file.
It's a simple program. I must be missing something small. Any suggestions?
 

be80be

Well-Known Member
just a thought how many leds do you have hooked to that chip it cant lite 33 all at one time
 
Last edited:

be80be

Well-Known Member
try this and see if it works change the xtal setting to match yours
Code:
#include <htc.h>	// Required to interface with delay routines

#ifndef _XTAL_FREQ
 // Unless already defined assume 4MHz system frequency
 // This definition is required to calibrate __delay_us() and __delay_ms()
 #define _XTAL_FREQ 4000000
#endif
void main(void){
ADCON1 =0x06 ; // Changes PORTA to digital
CMCON = 0x07 ; // Disable analog comparators
PORTA = 0x00 ;
PORTB = 0X00 ;
PORTC = 0X00 ;
PORTD = 0X00 ;
PORTE = 0X00 ;
TRISA = 0x00 ; // Configure PORTA as output
TRISB = 0X00 ;
TRISC = 0X00 ;
TRISD = 0X00 ;
TRISE = 0X00 ;

while(1){
PORTA = 0XFF ;
PORTB = 0XFF ;
PORTC = 0XFF ;
PORTD = 0XFF ;
PORTE = 0Xff ;
__delay_ms(100);
PORTA = 0X00 ;
PORTB = 0X00 ;
PORTC = 0X00 ;
PORTD = 0X00 ;
PORTE = 0X00 ;
__delay_ms(100);
}
}
 

micro571

New Member
I changed your reference code value from 4MHz to 20MHz and compiled.

As is, the new code produces an error:

Error [499] ; . undefined symbol:
___delay_ms (877.obj)

I'm using the Hi-Tech C compiler, v9.60.

At the top of the delay.h file I was referencing in my code, I had defined:
#define PIC_CLK 20000000
 

Pommie

Well-Known Member
Most Helpful Member
Can you try this,

Code:
#include <pic.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define _16F877
__CONFIG( HS & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT );

#define	XTAL_FREQ	20MHZ
#include "delay.c"

void main (){
    ADCON1 =0x06 ; // Changes PORTA to digital
    CMCON = 0x07 ; // Disable analog comparators
    PORTA = 0x00 ;
    PORTB = 0X00 ;
    PORTC = 0X00 ;
    PORTD = 0X00 ;
    PORTE = 0X00 ;
    TRISA = 0x00 ; // Configure PORTA as output
    TRISB = 0X00 ;
    TRISC = 0X00 ;
    TRISD = 0X00 ;
    TRISE = 0X00 ;    
    while(1){
        PORTA = 0XFF ;
        PORTB = 0XFF ;
        PORTC = 0XFF ;
        PORTD = 0XFF ;
        PORTE = 0Xff ;
        DelayMs(500);
        PORTA = 0X00 ;
        PORTB = 0X00 ;
        PORTC = 0X00 ;
        PORTD = 0X00 ;
        PORTE = 0X00 ;
        DelayMs(500);
    }
}
Mike.
 
Last edited:

be80be

Well-Known Member
I'm using the Hi-Tech C compiler, v9.60.
I have v9.65 and it wouldn't build your code
 

micro571

New Member
I tried the code as-is and got a bunch of errors:
Error [482] ; . symbol "_DelayMs_interrupt" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayS" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayMs" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayBigMs" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayBigUs" is defined more than once in "877.obj"
Error [482] ; . symbol "_delayus_variable" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayMs_interrupt" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayS" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayMs" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayBigMs" is defined more than once in "877.obj"
Error [482] ; . symbol "_DelayBigUs" is defined more than once in "877.obj"
Error [482] ; . symbol "_delayus_variable" is defined more than once in "877.obj"

I changed "delay.c" to "delay.h" and compiled...

It worked! I've got a blinking led now.

Thanks for your help. I'm guessing it's the config parameter that did it.

I had tried it with this config earlier:
__CONFIG( XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT );
but that didn't work.

Thanks again for your speedy responses!

Now it's time to upgrade blinky led program to something more useful. :)
 

micro571

New Member
Doing a bit of trial and error with the config line; I needed to specify HS (presumably high-speed) instead of XT (external??) for the oscillator selection bits.
 

be80be

Well-Known Member
HS and XT are both external here data sheet has about it
14.2.1 OSCILLATOR TYPES
The PIC16F87XA can be operated in four different
oscillator modes. The user can program two configuration
bits (FOSC1 and FOSC0) to select one of these four
modes:
• LP Low-Power Crystal
• XT Crystal/Resonator
• HS High-Speed Crystal/Resonator
• RC Resistor/Capacitor
 

millwood

Banned
a few things:

1) you will need to make sure that the fuses are set in a way consistent with your circuit. do you use the internal rc oscillator? for example.

2) I am assuming that the port settings are right. but you typically set TRISA/B... registers before you set the ports.

3) the errors with regarding to delay() is due to the header files.

how about this one?

Code:
#include	<pic.h>
#include	<conio.h>
#include	<stdlib.h>
#include <stdio.h>
#include	<ctype.h>
#include "delay.h"
//#include "delay.c"  // you may or may not be able to comment out this. depending on what's in delay.h and delay.c
//void delay(void);   // it is always a good idea to declare functions explicitly
//#define _16F877
//	__CONFIG(UNPROTECT|BODEN|FOSC1|BKBUG|WRT);
//__CONFIG( XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT );
void main (){

ADCON1 =0x06 ; // Changes PORTA to digital
CMCON = 0x07 ; // Disable analog comparators
TRISA = 0x00 ; // Configure PORTA as output
TRISB = 0X00 ;
TRISC = 0X00 ;
TRISD = 0X00 ;
TRISE = 0X00 ;
PORTA = 0x00 ;
PORTB = 0X00 ;
PORTC = 0X00 ;
PORTD = 0X00 ;
PORTE = 0X00 ;

while(1){
  DelayMs(500);
  PORTA = ~PORTA ;
  PORTB = ~PORTB ;
  PORTC = ~PORTC ;
  PORTD = ~PORTD ;
  PORTE = ~PORTE ;
  }
}
 
Last edited:

be80be

Well-Known Member
You no I've tried toggle like that and it doesn't blink the led
Code:
while(1){
  DelayMs(500);
  PORTA = ~PORTA ;
  PORTB = ~PORTB ;
  PORTC = ~PORTC ;
  PORTD = ~PORTD ;
  PORTE = ~PORTE ;
  }
}
 

3v0

Coop Build Coordinator
Forum Supporter
Where that on a 16f877a not a 18fchip
That's what I get for only reading one post down, but it illustrates the point, and a good reason to use an 18F.

On the 16F you need to toggle a variable and write it to the port
Code:
char toggleMe;
....
toggleMe = 0x00;
...
while(1)
{
  toggleMe = ~toggleMe;
  PORTA = toggleMe;
}
 

be80be

Well-Known Member
I found why the chip I was using has adc on portC so I needed this
Code:
void main (){
ANSEL = 0;                  // makes PORTC digital 
PORTC = 0;                 // Initialize PORTC
TRISC = 0;                 // Configure PORTC as output
while(1){
  Delay_Ms(100);
  PORTC = ~PORTC;
 }
}
works find like this LOL
 

Pommie

Well-Known Member
Most Helpful Member
If PORTC=~PORTC doesn't work then some possible reasons are,

1. You have the pins still set to analogue as pointed out by Burt.
2. You have overloaded the pins and this is forcing them high/low. Normally by connecting LEDs without series resistors.
3. You forgot to switch the pins to output.
4. The pins are configured for some other peripheral.
5. One of the other reasons for pics not working - not programmed, no oscillator, no power etc.

Mike.
 
Last edited:

millwood

Banned
the fact using an intermediate variable can toggle a port suggests that the port itself is in the right mode.

I am curious about this as well. I have never encountered an example where PORTA=~PORTA; does not work.

3v0, do you have an actual code where this is known to not work?
 

3v0

Coop Build Coordinator
Forum Supporter
Nope.

I was thinking about the Read-Modify-Write problem on the 16F's.

Burt said PORT=~PORT did not work. According to his post it did not work on any of the ports. I did not suspect he had not configured the port correctly.
 

Pommie

Well-Known Member
Most Helpful Member
the fact using an intermediate variable can toggle a port suggests that the port itself is in the right mode.

I am curious about this as well. I have never encountered an example where PORTA=~PORTA; does not work.

3v0, do you have an actual code where this is known to not work?
Try it on any pic chip with analogue pins. Any pins that are analogue work well as digital outputs but when you read them they always return zero. Hence why a copy will work.

Mike.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top