Beginner to PIC microships

Status
Not open for further replies.

mikkelbg

New Member
Hi,

I've bought the PICkit 1 and are now trying to programme the PIC12F675. Im using HI-TECH (HI-TIDE?) C to write to code and programme it to the chip with "PICkit 1 Classic".

I want four of the pins on the chip to be input and two of them to be output, this should be possible right?

To do this i've used: TRISIO = 0b11001111;
But what should I then set GPIO to set the two outputs high/low?

Thanks in advance!
Mikkel

*microchips!
 
Last edited:
But what should I then set GPIO to set the two outputs high/low?
In assembly:
bsf GPIO, GP4 ;To make bit 4 of GPIO high
bsf GPIO, GP5 ;To make bit 5 of GPIO high
bcf GPIO, GP4 ;To make bit 4 of GPIO low
bcf GPIO, GP5 ;To make bit 5 of GPIO low

In C this should work(Not sure on HighTech C):
GP4 = 1; //To make bit 4 of GPIO high
GP5 = 1; //To make bit 5 of GPIO high
GP4 = 0; //To make bit 4 of GPIO low
GP5 = 0; //To make bit 5 of GPIO low
 
That gives me the following error: undefined identifier "GP4".

By reading posts on this site i understand that I somehow has to turn stuff like analog ports off, is that correct?

Here's all the code in C (found it in the examples that came with the PICkit 1):
Code:
GPIO = 0;		//Clear GPIO
ANSEL = 0b00000000;	// configure A/D inputs as digital I/O
TRISIO = 0b11001111;	//GPIO 3,4 outputs, GPIO 0,1,2,5,6,7 inputs
OPTION = 0b11010000;	// Timer0 internal clock, 1:2 prescale
CMCON = 0b00000000;	// configure comparator inputs as digital I/O
GP4 = 1;		//To make bit 4 of GPIO high
 
That gives me the following error: undefined identifier "GP4".
By reading posts on this site i understand that I somehow has to turn stuff like analog ports off, is that correct?
That is correct, but it is not the source of the undefined identifier error. Either you haven't included the right C header file for PIC12F675 or HighTech-C uses a slightly different identifier. I don't know for sure because I've only used Microchips C with their 18F series chips.... But you need to change this:
CMCON = 0b00000000; // configure one comparator input as digital I/O
to this:
CMCON = 0b00000111; // configure all comparator inputs as digital I/O
So that GP0 & 1 are IO only....
 
Ports dosn't react as expected

Looked in some of the header files and found no GP4, but did find GPIO(0-5), that might be it?

It still dosn't work though. It almost seems like it's random (not only the two outputs but all the ports on the chip) which ports opens when changing the GPIO4 and GPIO5 to either 0 or 1.

Here is the full sourcecode:

main.c
Code:
#include <htc.h>
#include "main.h"

void
main(void)
{
	Init();	//Initalize the chip
	while (1){
		GPIO4 = 1; //To make bit 4 of GPIO high/low
		GPIO5 = 1; //To make bit 5 of GPIO high/low
	}
}

void Init(void)
{
	#asm			
		call 0x3FF	    //Load Factory Calibration Value Into OSCCAL
				
		bsf _STATUS,5  //BANK1
		movwf _OSCCAL
	#endasm

	ANSEL = 0b00000000;	// configure A/D inputs as digital I/O
	TRISIO = 0b11001111; //GPIO 3,4 outputs, GPIO 0,1,2,5,6,7 inputs
	OPTION = 0b11010000;	// Timer0 internal clock, 1:2 prescale
	
	CMCON = 0b00000111; // configure all comparator inputs as digital I/O
}

main.h
Code:
#ifndef MAIN_H_
#define MAIN_H_

#include <pic.h>

__CONFIG(UNPROTECT & BOREN & MCLRDIS & PWRTEN & WDTDIS & INTIO);   

void Init(void);

#endif /*MAIN_H_*/

Thanks for your help so far!
Mikkel
 
You may try this:

Code:
#include <htc.h>
#include "main.h"

void main(void)
{
	Init();	//Initalize the chip
	while (1){
		[b]GPIO0 = 1; //To make bit 0 of GPIO high/low
		GPIO1 = 1; //To make bit 1 of GPIO high/low[/b]
	}

}

void Init(void)
{
	#asm	
		
[b]        bsf STATUS, RP0   ;Bank 1
        call 3FFh         ;Get the cal value
        movwf OSCCAL      ;Calibrate
        bcf STATUS, RP0   ;Bank 0 [/b]

	#endasm

	CMCON = 0b00000111; // configure all comparator inputs as digital I/O
	ANSEL = 0b00000000;	// configure A/D inputs as digital I/O
[b]	TRISIO = 0b111100;       //GPIO0-1 outputs GPIO2-3-4-5 inputs [/b]

	OPTION = 0b1101[b]1[/b]000;	
		
}

GPIO3 is input only
 
Gpio3?

I didn't use GPIO3? Shouldn't it be possible to use GPIO4 and 5 as outputs?

EDIT: Oh sorry, did - will try it out
 
You can use GPIO4-5 as outputs

EDIT: you didn't use GPIO3, but the comment after TRISIO confused me: TRISIO = 0b11001111; //GPIO 3,4 outputs, GPIO 0,1,2,5,6,7 inputs

I think that the calibration routine was the issue.
 
Last edited:
Yes, you can check an input with an if instruction. For example:
Code:
if (GPIO0==0)

     // do something

If you need pull-up resistors, the PIC12F675 has internal weak pull-up resistors that can be enabled in the option register and in the WPU register (GP3 does not have the pull-up resistor).
 
Great thanks!

Do you also have some code that is able to make a delay? Currently i'm using this:

void Delay(char value)
{
for (outer=value; outer != 0; outer--)
{
for (inner=0x57; inner != 0; inner--) //0xAF
{

}
}
return;
}

But isn't precise enough to control a servo motor.
 
mikkelbg said:
Do you also have some code that is able to make a delay?
Do you need a function to generate variable delays? If not, you can place for loops with different initialization where each delay is required. You can use the Stopwatch function of MPLAB to check the accuracy.
By the way, do you want the delay to be exact? This is not always required.
If you want precise timing, you can use a TIMER and interrupts.
 
Last edited:
Nigel Goodwin -> How should the Delay function work? Delay(milliseconds) ?

eng1 -> Yes it needs to be precise. I'm going to control a servo with it, so I need to be able to make a pause less than a millisecond.
 
mikkelbg said:
Nigel Goodwin -> How should the Delay function work? Delay(milliseconds) ?

eng1 -> Yes it needs to be precise. I'm going to control a servo with it, so I need to be able to make a pause less than a millisecond.

Then move to assembler, where you can get 1uS resolution with a 4MHz clock - or at least add an inline assembler function to do it.
 
mikkelbg said:
Nigel Goodwin -> How should the Delay function work? Delay(milliseconds) ?

eng1 -> Yes it needs to be precise. I'm going to control a servo with it, so I need to be able to make a pause less than a millisecond.

Some compilers have built-in delay functions, for example: Delay_ms(int) and Delay_us(int) that are precise. Another option is to use for loops, for example:
for(int i=0; i<DELAY; i++); // DELAY is an integer constant
but you have to use a debugger or the StopWatch function of MPLAB to check how many machine cycles it generates.
You may also view the assembly code that your compiler generates.
 
Last edited:
By making a loop in assembler?

I know how to make inline assembler, but don't know how to code assembler.

#asm
assembler code
#endasm

eng1: I have tryed to make a loop in C, but it dosn't seems to be that precise:
void Delay(char value)
{
for (outer=value; outer != 0; outer--)
{
for (inner=0x57; inner != 0; inner--) //0xAF
{
}
}
return;
}
 
Your compiler should have some delay functions inside these files: delay.h and delay.c. Bear in mind that the accuracy may vary, depending of the optimization level.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…