Not applicable
Jan 29, 2016
04:04 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 29, 2016
04:04 AM
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
Can anyone point me to an example or post some code how I can generate a asymmetric pwm on the CCU4.
Regards
Enigma
- Tags:
- asymmetric
- IFX
- pwm
1 Reply
Not applicable
Jan 29, 2016
05:13 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 29, 2016
05:13 AM
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;
}
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<
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<
}
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->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;
}