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.

PIC18F1330 & PWM Update.

Status
Not open for further replies.

bsodmike

New Member
Hi folks,

Thanks to many people here I was pointed in the direction of the 18F1330 PIC featuring 3 on-board PWMs.

I've gotten as far as this, simulated in MPLAB. Coded with Hi-Tech's PICC18 STD compiler:

**broken link removed**

I was able to configure the PIC to only enable PWM on the 'odd' port pins, and output a 500Hz signal, which works nicely as it brings the PWM resolution to a maximum of 13.96 (odd). This works out to '16000' representing a 100% duty cycle, which is a nice round number.

In the above simulation I had the code loop from 0% to 100% duty cycle and at the end to flip the state on the other 'RB' pins (configured as I/O rather than PWM).

Next up: Implement a serial 'receive' interrupt to adjust the duty cycle on the fly based on data received from a PC.
 
Help

Hi mate, I am new to PIC, and can I take a look at ur code, I am trying to generate a PWM output with a steady duty cycle but still not working. So could you send me a copy of the code to deathknightdjc@hotmail.com , so I could learn somethin from it. TY :D
 
PWM Code Snippet...

Apologies for the extremely late response. Mind you, I have not looked at this code in quite some time but this is what I was able to dig up. I do not like the practice of handing "everything" on a platter - especially as I achieved this with much hard work.

Intro & Initialisation

The following code was compiled with Hi-Tech PICC18 STD v9.51PL1 @ Global (9) Optimization. This code was submitted to King's College London for the award of MSc (Distinction) in Mechatronics as part of my thesis titled "Mobile Autonomous Omni-Directional Robotic Vehicle Control for Indoor Navigation".

First you need to configure the PIC:

Code:
#ifdef _18F4331
// Settings for PIC18F4331

//__CONFIG(1,RCCLKO & IESODIS & FCMDIS); //RCCLKO [CONFIG1H<0:3>: 0xF9]: Internal RC, RA6=Fosc/4 & RA7=IO
__CONFIG(1,RCIO & IESODIS & FCMDIS); //RCIO [CONFIG1H<0:3>: 0xF8]: Internal RC, RA6=IO & RA7=IO
__CONFIG(2,BORDIS & PWRTDIS & WDTDIS);
//__CONFIG(3,MCLRDIS & PWM4RD5); //Configure PWM4 on alternate pin, RD5
__CONFIG(3,MCLRDIS);
__CONFIG(4,DEBUGDIS & STVRDIS & LVPDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,WRTEN);
#else
	#error Unsupported PICmicro MCU selected
#endif

PIC Init Routine with PWM Code

This is the entire function as from my complete code.

Code:
// Init Routine
void init()
{
	//initialize clock and i/o ports
	OSCCON = 0x70; 		//OSCCON<6:4>: INTOSC set as 8MHz
	
	TRISA = 0x00; 		//defined as outputs
	TRISB = 0x00; 		//defined as outputs
	TRISC = 0x00; 		//defined as outputs
	TRISD = 0x00; 		//defined as outputs
	TRISE = 0x00; 		//defined as outputs
	PORTA = 0x00;
	PORTB = 0x00;
	PORTC = 0x00;
	PORTD = 0x00;
	PORTE = 0x00;		
	
	//configure a/d module - essentially disable it!
	ADCON0 = 0b00000000;
	ADCON1 = 0b00011111;
	ADCON2 = 0b10111111;
	ADON = 0; //A/D Converter module is disabled

	//Configure Power Control PWM Module

	/*
	At 8MHz, to obtain a PWM frequency of 500Hz
    
	TPWM 	= time period of PWM frequency
    PTPER 	= 12-bit period register PTPERL and PTPERH
    PTMRPS 	= PWM time base prescaler
     
           (PTPER+1)*PTMRPS     (3999+1) * 1
    TPWM = ----------------  =  ------------ = 0.002s
                Fosc/4           8000000/4
    
    Frequency = 1/TPWM = 500Hz
    
    PWM resolution (bits resolution for duty cycle):
    
                 log(8MHz/500Hz)
    Resolution = ------------------ = 13.96578428 = ~14 bits
                      log(2)
	*/

	//initialize PWM and timers
	PTCON0 	= 0b00000000; 	//Postscale 1:1, Fosc/4 Prescale 1:1, Free Running Mode
  	PTCON1 	= 0b10000000;   //Time base in ON, Time base counts up
  	PWMCON0 = 0b01111111;  	//All odd PWM I/O pins enabled for PWM output, Independent mode for all pins
							//PWMCON0 = 0b01110111; for PIC18F1330
  	PWMCON1 = 0b00001001;  	//Postscale 1:1, special event on count downwards, updates from Duty Cycle and Period Buffers enabled

	//4095d = 0xFFFh = 001111 11111111
	//16000 = 0x3E80 = 111110 10000000 = 62 80
	//16256 = 0x3F80 = 111111 10000000 = 63 80
	//16383 = 0x3FFF = 111111 11111111 = 63 255

  	PDC0H = 0;				//Duty Cycle control for PWM0/1
  	PDC0L = 0;   			//Duty Cycle control for PWM0/1
	//PDC0H = 0b001111;		//Duty Cycle control for PWM0/1
	//PDC0L = 0b11111111;   //Duty Cycle control for PWM0/1

  	PDC1H = 0;      		//Duty Cycle control for PWM2/3
  	PDC1L = 0;   			//Duty Cycle control for PWM2/3

  	PDC2H = 0;       		//Duty Cycle control for PWM4/5
  	PDC2L = 0;    			//Duty Cycle control for PWM4/5

  	PDC3H = 0;       		//Duty Cycle control for PWM6/7
  	PDC3L = 0;    			//Duty Cycle control for PWM6/7
	
 	//Period control for all PWM output  (set at 500 Hz)
  	//PTPERH = 0b1111;
  	//PTPERL = 0b10011111; 	//3999d = 0xF9Fh = H[1111] L[10011111] 
  	PTPERH = 0xF9F >> 8;
  	PTPERL = 0xF9F; 		//3999d = 0xF9Fh = H[1111] L[10011111] 

	//Define PWM Port Definitions
	#define M1 		PDC0H
	#define M2 		PDC1H
	#define M3 		PDC2H
	#define PWM7	PDC3H //free PWM output, PWM7/RD7

	//Define Motor Direction and Brake Pins
	#define M1_DIR	RD0
	#define M1_BR	RD1
	#define M2_DIR	RD2
	#define M2_BR	RD3
	#define M3_DIR	RD4
	#define M3_BR	RD5

	//initialise EUSART
	init_EUSART();
}

The main routine runs something like this:

Code:
// Main Service Loop
void main(void)
{
	//local variables declared here	

	//initialise
	init();
	/* MAIN LOOP */
	while(1)
	{
		//code never exits from this infinite loops.
	}
}

Of course, my code included interrupt driven serial communications. The motor control routine looked something like this:

Code:
void motor_test()
{
	short i=0;

	// Motor ramp test
	for (i=0;i<50;i++)
	{
		M1 = i+10;
		M2 = i+10;
		M3 = i+10;
		DelayMs(80);
	}

	DelayS(5); //persist PWM @ 95% for 5s.

	for (i=60;i>10;i--)
	{
		M1 = i-10;
		M2 = i-10;
		M3 = i-10;
		DelayMs(80);
	}

	DelayS(1);

	M1 = 0;
	M2 = 0;
	M3 = 0;
}

I have uploaded a video of this particular segment of code in action. The PWM signal generated is gradually ramped from a duty cycle of 0% to 100%.

MARV: PWM Ramp Test
MARV: Motor Speed Test
MARV: First Full Motor Test

You can see **broken link removed**.

**broken link removed**

Hope this helps!

Cheers,
Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top