C8051F02x Datasheet

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How can i enable PWM through this lines
i'm using c8051C0F2x toolkit , should i be using 8 or 16 bit pwm

i want to interface it with a servo motor

 

6-Bit Pulse Width Modulator Mode
Each PCA0 module may also be operated in 16-Bit PWM mode. In this mode, the 16-bit capture/compare module defines the number of PCA0 clocks for the low time of the PWM signal. When the PCA0 counter matches the module contents, the output on CEXn is asserted high; when the counter overflows, CEXn is asserted low. To output a varying duty cycle, new value writes should be synchronized with PCA0 CCFn match interrupts. 16-Bit PWM Mode is enabled by setting the ECOMn, PWMn, and PWM16n bits in the PCA0CPMn register. For a varying duty cycle, CCFn should also be set to logic 1 to enable match interrupts. The duty cycle for 16-Bit PWM Mode is given by Equation 23.3.
Important Note About Capture/Compare Registers: When writing a 16-bit value to the PCA0 Capture/Compare registers, the low byte should always be written first. Writing to PCA0CPLn clears the ECOMn bit to ‘0’; writing to PCA0CPHn sets ECOMn to ‘1’
Using Equation 23.3, the largest duty cycle is 100% (PCA0CPn = 0), and the smallest duty cycle is 0.0015% (PCA0CPn = 0xFFFF). A 0% duty cycle may be generated by clearing the ECOMn bit to ‘0’.
Equation 23.3. Duty Cycle = (65536-PCA0CPn)/65536

 

this a code from the internet but i have a problem with the value of the duty cycle

#include <c8051f020.h>                    // SFR declarations
#include <intrins.h>
#include<stdio.h>
/* Define value to be loaded in timer for PWM period of 20 milli second */
#define PWM_Period 0xB7FE
//------------------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//------------------------------------------------------------------------------------

sfr16 DP       = 0x82;                    // data pointer
sfr16 TMR3RL   = 0x92;                    // Timer3 reload value
sfr16 TMR3     = 0x94;                    // Timer3 counter
sfr16 ADC0     = 0xbe;                    // ADC0 data
sfr16 ADC0GT   = 0xc4;                    // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                    // ADC0 less than window
sfr16 RCAP2    = 0xca;                    // Timer2 capture/reload
sfr16 T2       = 0xcc;                    // Timer2
sfr16 RCAP4    = 0xe4;                    // Timer4 capture/reload
sfr16 T4       = 0xf4;                    // Timer4
sfr16 DAC0     = 0xd2;                    // DAC0 data
sfr16 DAC1     = 0xd5;                    // DAC1 data

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 11000000                    // approximate SYSCLK frequency in Hz
ECOMn = 1;
PWMn = 1;
PWM16n = 1;
CCFn = 1;
sbit motor_pin = P2^6;
unsigned int ON_Period, OFF_Period, DutyCycle;                    
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void PORT_Init(void);
sbit Servo_Motor_Pin = P2^6;
void Timer_init();
void Timer0_ISR();
void Set_DutyCycle_To(float duty_cycle);
void delay(unsigned int count);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {

   // disable watchdog timer
   WDTCN = 0xde;
   WDTCN = 0xad;
   Timer_init();
  PORT_Init();
    PORT_Init();
    EA  = 1;		/* Enable global interrupt */
   ET0 = 1;         	/* Enable timer0 interrupt */
  

   while(1)
    {
	Set_DutyCycle_To(1);
    
   }
}
   


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
void PORT_Init (void)
{
   XBR2    = 0x40;                     // Enable crossbar and weak pull-ups
   P2MDOUT |= 0x40;                    // enable P1.6 (LED) as push-pull output
}
void delay(unsigned int count)
{
    int i,j;
    for(i=0; i<count; i++)
			for(j=0; j<112; j++);
}

void Timer_init()
{
	TMOD = 0x01;		/* Timer0 mode1 */
	TH0 = (PWM_Period >> 8);/* 20ms timer value */
	TL0 = PWM_Period;
	TR0 = 1;		/* Start timer0 */
}

/* Timer0 interrupt service routine (ISR) */
void Timer0_ISR() interrupt 1	
{
	Servo_Motor_Pin = !Servo_Motor_Pin;
	if(Servo_Motor_Pin)
	{
		TH0 = (ON_Period >> 8);
		TL0 = ON_Period;
	}	
	else
	{
		TH0 = (OFF_Period >> 8);
		TL0 = OFF_Period;
	}	
			
}

/* Calculate ON & OFF period from duty cycle */
void Set_DutyCycle_To(float duty_cycle)
{
	float period = 65536 - PWM_Period;
	ON_Period = ((period/100.0) * duty_cycle);
	OFF_Period = (period - ON_Period);	
	ON_Period = 65536 - ON_Period;	
	OFF_Period = 65536 - OFF_Period;
}

 

Last Edited: Tue. Apr 9, 2019 - 11:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

That question may be better asked here ?

https://www.silabs.com/community/mcu/8-bit/forum

Topic locked