Migration from PIC18 to PIC12

Status
Not open for further replies.

haxan

New Member
Hi, i have written a code for PIC18 using C18 compiler. I want to know how to migrate it for PIC12F629 and which compiler to use. Can anyone please guide. Its for a Fan dimming circuit i am making.


Code:
#include <p18cxxx.h>
#include <delays.h>

#pragma config WDT = OFF

#define ZERO_CROSSING PORTAbits.RA0
#define OUTPUT PORTBbits.RB0

void detect_zero(void);
void fireTriac(void);
void Pulse(unsigned int);			// Sends pulse after int value
void delay_ms(unsigned int);

unsigned int dimmer = 0;
unsigned int ZC = 0;
unsigned int stat=0;

void main (void)
{
	ADCON1 	= 0b00001111;	// Set Port A for digital i/o
	TRISA 	= 0b00011111;	// Set ZeroCrossing input;
	TRISB 	= 0x00;
	PORTA 	= 0;
	PORTB 	= 0;

	while (1)
	{
		dimmer = PORTA & 0b00011110;
		dimmer = dimmer >> 1;
		detect_zero();
	}
}

void detect_zero(void)
{
	if(ZERO_CROSSING == 1 && stat == 0)
	{
		stat = 1;
		fireTriac();
	}

	if (ZERO_CROSSING == 0 && stat == 1)
	{
		stat = 0;
		fireTriac();
	}
}

void fireTriac(void)
{
	OUTPUT = 0;
	ZC++;
	if(dimmer == 0){ZC = 0;}
	if(dimmer == 1){if(ZC == 5){Pulse(1);}}
	if(dimmer == 2){if(ZC == 2){Pulse(1);}}
	if(dimmer == 3){Pulse(175);}
	if(dimmer == 4){Pulse(150);}
	if(dimmer == 5){Pulse(125);}
	if(dimmer == 6){Pulse(100);}
	if(dimmer == 7){Pulse(75);}
	if(dimmer == 8){Pulse(50);}
	if(dimmer == 9){Pulse(25);}
	if(dimmer == 10){Pulse(1);}
}

void Pulse(unsigned int del)
{
	delay_ms(del);
	OUTPUT = 1;
	ZC = 0;
	delay_ms(1);
	OUTPUT = 0;
}

void delay_ms(unsigned int ms)
{
	int i = 0;
	for(;i < ms;i++)
	{
		Delay10TCYx(2);
	}
}
 
You need to BUY an expesive C compiler, only the C18 one is free.

Bear in mind you're dropping a LOT of power from an 18 to a 12.
 
Can you give an example of C compiler which will be easier to use from C18 to PIC12's C compiler.
 
Really how would you do a project using TCP/IP library from Microchip and also graphics libraries etc ? They are all in C language
 
All the Microchip Ethernet libraries are for the 18F or better PICs. Hard to find a good reason to use the older 16F stuff really.

PS your program is small enough that it wouldn't be that difficult to convert to MPASM which is ideal for those wee 12F & 10F PICs.
 
Last edited:

Yes, i am actually using PIC24F for Ethernet connectivity.

Ok thank you, i have actually downloaded and installed CCS C compiler which supports PIC10/12/16/18/24/dsPIC series.

I have worked extensively in Assembly language but in a different microcontroller of AT80S51.
 
okay i have written the following code but its not properly working:
The problem is that i cannot read input from 4 switches connected at A0 - A3;
Also i cannot figure out how to use internal oscillator of PIC12F629 for 4MHz.
Code:
#include <12F629.h>

#fuses 	LP,NOWDT,NOPROTECT,NOBROWNOUT
#use 	delay(clock=4000000)

#define ZERO_CROSSING pin_A5
#define OUTPUT pin_A4

void detect_zero(void);
void fireTriac(void);
void Pulse(unsigned int);			// Sends pulse after int value

unsigned char dimmer = 0;
unsigned char ZC 	= 0;
unsigned char stat	= 0;

void main (void)
{
	SET_TRIS_A(0b101111);	//All input and one output
	OUTPUT_A(0x00);

	while(TRUE)
	{
		dimmer = 0x00;
		if(input(pin_A3) == 1){dimmer = 0x08;}
		if(input(pin_A2) == 1){dimmer = dimmer | 0x04;}
		if(input(pin_A1) == 1){dimmer = dimmer | 0x02;}
		if(input(pin_A0) == 1){dimmer = dimmer | 0x01;}
		detect_zero();
	}
}

void detect_zero(void)
{
	if(input(ZERO_CROSSING) == 1 && stat == 0)
	{
		stat = 1;
		fireTriac();
	}

	if (input(ZERO_CROSSING) == 0 && stat == 1)
	{
		stat = 0;
		fireTriac();
	}
}

void fireTriac(void)
{
	output_low(OUTPUT);
	ZC++;
	switch(dimmer)
	{
		case 0:
			ZC = 0;
			break;
		case 1:
			if(ZC == 5){Pulse(1);}
			break;
		case 2:
			if(ZC == 2){Pulse(1);}
			break;
		case 3:
			Pulse(175);
			break;
		case 4:
			Pulse(150);
			break;
		case 5:
			Pulse(125);
			break;
		case 6:
			Pulse(100);
			break;
		case 7:
			Pulse(75);
			break;
		case 8:
			Pulse(50);
			break;
		case 9:
			Pulse(25);
			break;
		case 10:
			Pulse(1);
			break;
	}	
}

void Pulse(unsigned int del)
{
	delay_ms(del);
	output_high(OUTPUT);
	ZC = 0;
	delay_ms(2);
	output_low(OUTPUT);
}
 
I don't use the CCS compiler as it uses strange syntax. I use the free version of BoostC.

As to your problem, I suspect you need to turn off the comparators with CMCON=7;

Mike.
 
I don't use the CCS compiler as it uses strange syntax. I use the free version of BoostC.

As to your problem, I suspect you need to turn off the comparators with CMCON=7;

Mike.

The doesn't work in this compiler. I am new to this as well. Its first program coding in CCS.

It says "Undefined identifier CMCON"
 
I know many are apprehensive about learning assembly, but your task is QUITE simple. It is worthwhile to learn 12F asm, and the instruction set is VERY short, so I'd say learn it.
 
This is the circuit i am using.

I cannot find out how to turn of Comparator in CCS Nothing mentioned in its help either.
 

Attachments

  • Capture.JPG
    170 KB · Views: 223
That is why I don't use that compiler. In BoostC it is simply cmcon=7;

If you want to try converting to BoostC I can get you started.

Mike.
 
I just installed CCS yesterday. let me play with it for a few hours first. It still not resolved, i will switch to BoostC

Here is a function it uses to control comparator.

Code:
setup_comparator(NC_NC);

And here are the parameters it can take:
Code:
////////////////////////////////////////////////////////////////// COMP
// Comparator Variables: C1OUT, C2OUT
// Constants used in setup_comparator() are:
#define NC_NC_NC_NC  0x0ff07
#define NC_NC  0x0ff07
#define A0_A1  0x3ff02
#define A1_VR_OUT_ON_A2  0x6fb03
#define A1_VR  0x2ff04
#define A0_A1_OUT_ON_A2  0x3fb01

//Optionally OR with the following
#define COMP_INVERT           0x10

#bit C1OUT = 0x19.6

////////////////////////////////////////////////////////////////// VREF
// Constants used in setup_vref() are:
//
#define VREF_LOW  0xa0
#define VREF_HIGH 0x80
// Or (with |) the above with a number 0-15
 
I'm not around later so, just in case, here's your program in BoostC.
Code:
#include <system.h>

#pragma DATA _CONFIG, _MCLRE_OFF&_WDT_OFF&_INTRC_OSC_CLKOUT

#pragma CLOCK_FREQ 4000000

#define ZERO_CROSSING gpio.5
#define OUTPUT gpio.4

void detect_zero(void);
void fireTriac(void);
void Pulse(unsigned int);			// Sends pulse after int value

unsigned char dimmer = 0;
unsigned char ZC = 0;
unsigned char stat = 0;

void main()
{ 
    cmcon=7;
    trisio=0b101111;
    while(1){
        dimmer = 0x00;
        if(gpio.3 == 1){dimmer = 0x08;}
        if(gpio.2 == 1){dimmer = dimmer | 0x04;}
        if(gpio.1 == 1){dimmer = dimmer | 0x02;}
        if(gpio.0 == 1){dimmer = dimmer | 0x01;}
        detect_zero();
     }
}

void detect_zero(void)
{
    if(ZERO_CROSSING == 1 && stat == 0)
    {
        stat = 1;
        fireTriac();
    }

    if (ZERO_CROSSING == 0 && stat == 1)
    {
        stat = 0;
        fireTriac();
    }
}

void fireTriac(void)
{
    OUTPUT=0;
    ZC++;
    switch(dimmer)
    {
        case 0:
            ZC = 0;
            break;
        case 1:
            if(ZC == 5){Pulse(1);}
            break;
        case 2:
            if(ZC == 2){Pulse(1);}
            break;
        case 3:
            Pulse(175);
            break;
        case 4:
            Pulse(150);
            break;
        case 5:
            Pulse(125);
            break;
        case 6:
            Pulse(100);
            break;
        case 7:
            Pulse(75);
            break;
        case 8:
            Pulse(50);
            break;
        case 9:
            Pulse(25);
            break;
        case 10:
            Pulse(1);
            break;
    }    
}

void Pulse(unsigned int del)
{
    delay_ms(del);
    OUTPUT=1;
    ZC = 0;
    delay_ms(2);
    OUTPUT=0;
}

Mike.
 
Sorry to bother you again Pommie but can you please send the compiled file (.hex) so i can test directly. I want to see if it makes any difference or not. If it will i will install the BoostC compiler.

Does Boost Support all PIC12/PIC16/PIC18/PIC24 ?
 
Last edited:
Here's the hex file,
Code:
:02000000AA282C
:08000800A508031D08280800EB
:10001000F930FF3E031D09280000A50B0828080041
:100020002308A50004200516A1010230A500042024
:100030000512080083120512A10A2008003A0319CC
:100040004028013A03194228033A03194B28013A80
:1000500003195428073A03195928013A03195E284D
:10006000033A03196328013A031968280F3A031960
:100070006D28013A03197228033A031977280800FA
:10008000A10108002108053A031D08000130A30062
:10009000A401102008002108023A031D08000130C5
:1000A000A300A40110200800AF30A300A401102079
:1000B00008009630A300A401102008007D30A300A2
:1000C000A401102008006430A300A401102008003F
:1000D0004B30A300A401102008003230A300A4017B
:1000E000102008001930A300A401102008000130DE
:1000F000A300A401102008008312851E8528A208F1
:10010000031D85280130A2001A20851A0800220349
:10011000031D0800A2011A2008000730831299006D
:100120002F30831685008312A001851D9928083081
:10013000A000051D9E2804302004A000851CA328D3
:1001400002302004A000051CA82801302004A000D3
:100150007C2093288312A001A101A2018A110A1216
:020160008D28E8
:02400E00D43F9D
:00000001FF

And here's the source again as I changed the oscillator settings.
Code:
#include <system.h>

#pragma DATA _CONFIG, _MCLRE_OFF&_WDT_OFF&_INTRC_OSC_NOCLKOUT

#pragma CLOCK_FREQ 4000000

#define ZERO_CROSSING gpio.5
#define OUTPUT gpio.4

void detect_zero(void);
void fireTriac(void);
void Pulse(unsigned int);			// Sends pulse after int value

unsigned char dimmer = 0;
unsigned char ZC 	= 0;
unsigned char stat	= 0;

void main()
{ 
    cmcon=7;
    trisio=0b101111;
    while(1){
        dimmer = 0x00;
        if(gpio.3 == 1){dimmer = 0x08;}
        if(gpio.2 == 1){dimmer = dimmer | 0x04;}
        if(gpio.1 == 1){dimmer = dimmer | 0x02;}
        if(gpio.0 == 1){dimmer = dimmer | 0x01;}
        detect_zero();
     }
}

void detect_zero(void)
{
    if(ZERO_CROSSING == 1 && stat == 0)
    {
        stat = 1;
        fireTriac();
    }

    if (ZERO_CROSSING == 0 && stat == 1)
    {
        stat = 0;
        fireTriac();
    }
}

void fireTriac(void)
{
    OUTPUT=0;
    ZC++;
    switch(dimmer)
    {
        case 0:
            ZC = 0;
            break;
        case 1:
            if(ZC == 5){Pulse(1);}
            break;
        case 2:
            if(ZC == 2){Pulse(1);}
            break;
        case 3:
            Pulse(175);
            break;
        case 4:
            Pulse(150);
            break;
        case 5:
            Pulse(125);
            break;
        case 6:
            Pulse(100);
            break;
        case 7:
            Pulse(75);
            break;
        case 8:
            Pulse(50);
            break;
        case 9:
            Pulse(25);
            break;
        case 10:
            Pulse(1);
            break;
    }    
}

void Pulse(unsigned int del)
{
    delay_ms(del);
    OUTPUT=1;
    ZC = 0;
    delay_ms(2);
    OUTPUT=0;
}

Mike.
 
Thanks Mike, if i burn the code on PIC12F629, will i be able to reprogram it again and again? Some one was saying since the pins are multiplexed (/MCLR and GP3) it only programs once unless we specify from Configuration fuses.

Something to do with MCLR or NOMCLR in fuses.
 
The chip should be reprogrammable if your programmer can do Vpp first. The Pickit2 and ICD2 can both do this and I have in the past worked out how to do this on a JDM programmer.

Edit, BoostC supported devices.

Mike.
 
Last edited:
i am actually using a JDM programmer. Lets see

To program this IC, i need MCLR, ICSPDA,ICSPCLK,Vss and Vdd is that correct ?

However in normal PIC with 40 pins, there are 6 ISCP pins correct?
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…