asymmetric pwm - CCU4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi All,

Can anyone point me to an example or post some code how I can generate a asymmetric pwm on the CCU4.

Regards
Enigma
0 Likes
1 Reply
Not applicable
Hi Enigma,
I attach an example that should get you started using edge aligned PWM. I use some type definition to make the program easier to read. But you can certainly set the registers directly.
#include
typedef enum Peripherie {vadc=1,ccu4=2, usic0=3, wdt=9, rtc=10} Peripherie;
typedef enum IO {DirectInput=0,Inverted_Input=4,PushPull=0x10,Open_Drain=0x18} IO;//PCxCoding
typedef enum IOCr {PullDown=1,PullUp=2,InputToOUTx=3,GPIO=0,Alt1=1,Alt2=2,Alt3=3,Alt4=4,Alt5=5,Alt6=6,Alt7=7} IOCr; //PCxCoding
typedef enum CC4x {CC40=0,CC41=1,CC42=2,CC43=3} CC4x;//timer


void SCU_CLK_CLKCR(uint8_t FDIV,uint8_t IDIV,uint8_t PCLKSEL) //SCU Clock deklarieren
{
//--- SCU_CLK setzen ----
uint16_t CNTADJ; CNTADJ=0x3ff;
uint8_t RTCCLKSEL;RTCCLKSEL=0;

SCU_GENERAL->PASSWD = 0xC0;
while(((SCU_GENERAL->PASSWD) & 2)){;} //wait until write enabled
SCU_CLK->CLKCR= (CNTADJ<<20)+(RTCCLKSEL<<17)+(PCLKSEL<<16)+(IDIV<<8)+FDIV;
SCU_GENERAL->PASSWD = 0xC3;
}

void switch_on(Peripherie Unit) //void switch_on(uint32_t Peripherie)
{
//---------- Takt einschalten --------------
SCU_GENERAL->PASSWD = 0x000000C0UL;
SCU_CLK->CGATCLR0|=0x1< while ((uint32_t)SCU_CLK->CLKCR & (uint32_t)SCU_CLK_CLKCR_VDDC2LOW_Msk) {;} //Warteschleife
SCU_GENERAL->PASSWD = 0x000000C3UL;
//---------- Takt einschalten --------------
};

void IOFunktion(uint32_t p[2],uint32_t PCxCoding)
{uint32_t Adresse,IOCRx,Position, *Register;

PCxCoding = PCxCoding<<3;
Adresse = PORT0_BASE+(p[0]*0x100);// Adresse von PORT0 Structure + Portx offset

IOCRx=(uint32_t) (p[1]/4)*4; //Bestimmung von IOCR0, IOCR4, IOCR8 oder IOCR12
Register = (uint32_t*)( Adresse+IOCRx+0x10); // + Offset von IOCRx

Position = (uint32_t)(8*(p[1]-IOCRx));
uint32_t Inhalt,Maske;
Maske = ~(0xFF<<(p[1]-IOCRx)*8);
Inhalt = *Register;
Inhalt = Inhalt & Maske;
Inhalt = Inhalt | (PCxCoding<*Register = Inhalt;
}


void CC4yInit(CC4x y)
{ //-------- Capture/Compare Unit ----------------------
CCU4_CC4_TypeDef *CCU40_CC4y;
CCU40_CC4y= (CCU4_CC4_TypeDef *) (CCU40_BASE+0x100*(y+1));

CCU40->GIDLC=CCU40->GIDLC | (0x1< CCU40_CC4y->TCCLR=7; //Clear Run Bit, Timer and Dither counter
CCU40_CC4y->PSL=0; //output passiv level low
CCU40_CC4y->TCSET=1; //Timer ein-------------
CCU40->GCSS|=0xFF<<(4*y) ; //Slice1 Period, Compare, Passive level, Dither, Prescaler Shadow xfer enable

//-------- Capture/Compare Unit ----------------------
}

void CC4yPWM(uint8_t y,uint16_t period,uint16_t compare)
{
CCU4_CC4_TypeDef *CCU40_CC4y;
CCU40_CC4y= (CCU4_CC4_TypeDef *) (CCU40_BASE+0x100*(y+1));

CCU40_CC4y->PRS=period; //Set Period
CCU40_CC4y->CRS=compare; //Set Compare
CCU40->GCSS=0x111; //shadow xfer enable
}


int main(void)
{
uint8_t FDIV,IDIV,PCLKSEL; FDIV=0;IDIV=0;PCLKSEL=1;
SCU_CLK_CLKCR(FDIV,IDIV,PCLKSEL);

switch_on(ccu4);//switch on CCU40 Unit

uint32_t mainclock[2]={0,0};//PIN PORT 0,0 for PWM output

IOFunktion(mainclock,PushPull+Alt4); //CCU40.OUT0 PWM, see PCxCoding in manual
uint32_t P0=10000,C0 =1000; //set periode and compare values
CC4yInit(CC40);
CC4yPWM(CC40,P0,C0);
CCU40->GIDLC |= 0x1<<8; //start timer: Sets Run bit of the Prescaler
CCU40->GIDLS |= (0x1<<8); //stop timer: clears Run bit of the Prescalar

while(1)
{
}
return 0;
}
0 Likes