Continue to Site

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.

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

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);
	}
}
 
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:
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.

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 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
    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:
Status
Not open for further replies.

Latest threads

Back
Top