Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with C code for 16 bit PWM using Silabs C8051F005

Status
Not open for further replies.

chamarnadh

Member level 1
Joined
Nov 13, 2008
Messages
36
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Location
HYDERABAD,INDIA
Activity points
1,544
Hi friends

Iam struggling with 16 bit pwm using Silabs C8051F005.with this iam not getting PWM frequency more than 250 Hz. I want PWM with 1Khz or more.
I used PCA for PWM and Timer0 for PCA time base.

This is my C code. Can anybody suggest for this.

Thanks in Advance
Amarnadh


#include <c8051f000.h>
#include <stdio.h>
#include <string.h>
//#include <math.h>


sbit PWM_OUT= P0^0;
sbit test = P0^1;
//sbit T2 = P0^5; // counter inputT2
//sbit PWM_CCW= P0^5;
sbit PWM_CCW= P0^6;
sbit PWM_CW = P0^7;


#define PWM_START 0x8000

unsigned PWM = PWM_START;
unsigned int DIR;



void SYSCLK_Init (void)
{
int n;
OSCXCN = 0x67; // EXTERNAL Oscillator Control Register
for (n=1;n<255; n++) ; // XTLVLD blanking interval (>1ms)
while ((OSCXCN & 0x80)== 0 ); // wait for xtal osc to start up

OSCICN = 0x88; // Internal Oscillator Control Register
// select external oscillator as SYSCLK source and
// enable missing clock detector
}

void Rx_byte()
{
while(!RI); //wait until RI flag set
RI=0; // clear RI flag
}


void Tx_byte(unsigned char c)
{
SBUF=c;
while(!TI); // wait until TI flag set
TI=0; // clear TI flag
}



void delay_ms(unsigned int i)
{
int j;

for (j=0;j<i;j++)
{
TMR3CN=0x04;
// timer3 reload value=64614 for 1ms.

TMR3RLH = 0xFC; // Timer 3 Reload Register High Byte
TMR3RLL = 0x66; // Timer 3 Reload Register Low Byte

while (TMR3CN==0x04);

TMR3CN=0x00;
}
}

void Tx_string(unsigned char a[])
{
unsigned char i;
delay_ms(100); //delay required
for(i=0;a!='\0';i++)
Tx_byte(a);
}




void PORT_Init (void)
{
XBR0 = 0x08; // XBAR0: Initial Reset Value
XBR1 = 0x00; // XBAR1: Initial Reset Value,Timer2 External I/P Enable
XBR2 = 0x40; // XBAR2: Initial Reset Value

// Port configuration (1 = Push Pull Output)
PRT0CF = 0x01; // Output configuration for P0
PRT1CF = 0x00; //
PRT2CF = 0x00; // Output configuration for P2
PRT3CF = 0x00; // Output configuration for P3
}

void UART0_Init (void)
{
SCON = 0x50; // Serial Port Control Register; mode1,8bit UART,enable rcvr
SCON &= 0xFC; //clear interrupt pending flags
PCON = 0x80; // Power Control Register SMOD=1,doubles clock to UART
}

void timer(void)
{
//----------------------------------------------------------------
// Timer Configuration
//----------------------------------------------------------------

CKCON = 0x08; // Clock Control Register timer 0 uses sys clk
TH0 = 0x00; // Timer 0 High Byte
TL0 = 0xFF; // Timer 0 Low Byte
TH1 = 0xB8; // Timer 1 High Byte,Baudrate value for 9600
TL1 = 0x00; // Timer 1 Low Byte
TMOD = 0x02; // Timer0 mode is 16bit counter,Timer1 Mode is 8bit counter/timerwith autoreload
TCON = 0x30; // Timer Control Register Timer 1 enabled,timer0 overflow flag set

}


void PCA_Init (void)
{
//----------------------------------------------------------------
// PCA Configuration
//----------------------------------------------------------------

PCA0MD = 0x05; // PCA time base=Timer0 overflow PCA Mode Register and disable the CF interrupt
//PCA0CN = 0x40; // Enable PCA counter

PCA0H = 0x00; // PCA Counter/Timer High Byte
PCA0L = 0x00; // PCA Counter/Timer Low Byte

//Module 0
PCA0CPL0 = (0xff & PWM);
PCA0CPH0 = (0xff & (PWM >>8) ); // Right shift 8

PCA0CPM0 = 0x4D;//0x49; // PCA Capture/Compare Register 0 Enable comparator function
// High speed o/p mode
}


void timer0_ISR (void) interrupt 1
{


//test = ~ test;
TR0=0; // Timer0 Disable


TH0 = 0xFF; // Timer 0 High Byte PWM frequency this value is for 200hz

TL0 = 0xFF; // Timer 0 Low Byte PWM frequency

TR0=1; // Timer0 Enable



}

void PCA_ISR (void) interrupt 9

{
///test = ~ test;
if (CCF0)

{
CCF0 = 0;
if(PWM_OUT)
{
PCA0CPL0 = (0xff & PWM);
PCA0CPH0 = (0xff & (PWM >>8) ); //Right shift 8
}
else
{
PCA0CPL0 = 0;
PCA0CPH0 = 0;
}
} else if(CCF1)

{
CCF1 = 0;
} else if(CCF2)
{
CCF2 = 0;
} else if(CCF3)
{
CCF3 = 0;
} else if(CCF4)
{
CCF4 = 0;
} else if(CF)
{
CF = 0;
}

}


void main(void)

{

WDTCN = 0xDE; // Disable WDT
WDTCN = 0xAD; // Disable WDT

PORT_Init ();
SYSCLK_Init ();
timer ();
PCA_Init ();
UART0_Init();
IE = 0x82; // Enable T0 and Global interrupts
//IP = 0x02; // Set Timer0 Interrupt Priority to high
//EA = 1;
EIE1 |= 0x08; // Enable PCA Interrupt
EIP1 |= 0x08;

PCA0CN = 0x40;

while(1)
{

PCON |= 0x01;

}


}
 

ejemplos timer 0 modo 1 16 bit

Could your problem be related to the fact that you load Timer0 with 0xFFFF (TH=0xFF, TL=0xFF) in the overflow ISR, which, according to your own (?) comment should give 200Hz?

I'd suggest creating a preprocessor macro / function that takes the desired frequency and loads the proper values in the registries, thus avoiding writing two different pieces of code doing the same thing (loading the timer in the initialization part, and again, in the ISR).

I hope this helps.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top