Fast 20MHz PWM, with double edge controlled PWMs (90° Phase shifted). CPU clock had to be adjusted to 80MHz (PLL-controlled). Done by accessing the registers directrly.
main.cpp
00001 #include "mbed.h" 00002 00003 DigitalOut myled1(LED1); 00004 DigitalOut myled2(LED2); 00005 DigitalOut myled3(LED3); 00006 DigitalOut myled4(LED4); 00007 00008 DigitalOut outGND1(p21); 00009 PwmOut fmclck6(p22); 00010 PwmOut fmclck5(p23); 00011 DigitalOut outGND2(p24); 00012 PwmOut fmclck4(p25); 00013 00014 #define PLL0CFG_Val 0x00027 00015 #define PLL1_SETUP 0 00016 #define CCLKCFG_Val 5 00017 #define WAIT_SEC_BEFORE_START 5.0 00018 00019 int main() { 00020 // Wait a bit before changing the clock. Who knows, perhaps 00021 // it is needed to connect to the device 00022 myled1 = 1; 00023 wait(WAIT_SEC_BEFORE_START/4.0); 00024 myled1 = 0; 00025 myled2 = 1; 00026 wait(WAIT_SEC_BEFORE_START/4.0); 00027 myled2 = 0; 00028 myled3 = 1; 00029 wait(WAIT_SEC_BEFORE_START/4.0); 00030 myled3 = 0; 00031 myled4 = 1; 00032 wait(WAIT_SEC_BEFORE_START/4.0); 00033 myled1 = 1; 00034 myled2 = 1; 00035 myled3 = 1; 00036 myled4 = 1; 00037 00038 00039 00040 // The following sequence must be followed step by step in order to have PLL0 initialized 00041 // and running: 00042 00043 // 1. Disconnect PLL0 with one feed sequence if PLL0 is already connected. 00044 LPC_SC->PLL0CON &= ~0x02; /* PLL0 Disconnect */ 00045 LPC_SC->PLL0FEED = 0xAA; 00046 LPC_SC->PLL0FEED = 0x55; 00047 00048 // 2. Disable PLL0 with one feed sequence. 00049 LPC_SC->PLL0CON &= ~0x01; /* PLL0 Disable */ 00050 LPC_SC->PLL0FEED = 0xAA; 00051 LPC_SC->PLL0FEED = 0x55; 00052 00053 // 3. Change the CPU Clock Divider setting to speed up operation without PLL0, if desired. 00054 // LPC_SC->CCLKCFG = 2; /* Setup Clock Divider "2 + 1 = 3 DIVIDER" */ 00055 00056 // 4. Write to the Clock Source Selection Control register to change the clock source if 00057 // needed. 00058 LPC_SC->CLKSRCSEL = 0x00000001; /* Select Clock Source for PLL0 */ 00059 00060 // 5. Write to the PLL0CFG and make it effective with one feed sequence. The PLL0CFG 00061 // can only be updated when PLL0 is disabled. 00062 LPC_SC->PLL0CFG = 0x00000013; /* configure PLL0, N = 1, M = 20 (0x13 + 1) */ 00063 LPC_SC->PLL0FEED = 0xAA; 00064 LPC_SC->PLL0FEED = 0x55; 00065 00066 // 6. Enable PLL0 with one feed sequence. 00067 LPC_SC->PLL0CON |= 0x01; /* PLL0 Enable */ 00068 LPC_SC->PLL0FEED = 0xAA; 00069 LPC_SC->PLL0FEED = 0x55; 00070 00071 // 7. Change the CPU Clock Divider setting for the operation with PLL0. It is critical to do 00072 // this before connecting PLL0. 00073 LPC_SC->CCLKCFG = 5; /* Setup Clock Divider "5 + 1 = 6 DIVIDER" */ 00074 00075 // 8. Wait for PLL0 to achieve lock by monitoring the PLOCK0 bit in the PLL0STAT register, 00076 // or using the PLOCK0 interrupt, or wait for a fixed time when the input clock to PLL0 is 00077 // slow (i.e. 32 kHz). The value of PLOCK0 may not be stable when the PLL reference 00078 // frequency (FREF, the frequency of REFCLK, which is equal to the PLL input 00079 // frequency divided by the pre-divider value) is less than 100 kHz or greater than 00080 // 20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time 00081 // has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF 00082 // seconds when FREF is less than 400 kHz. 00083 while (!(LPC_SC->PLL0STAT & (1<<26))); /* Wait for PLOCK0 */ 00084 00085 // 9. Connect PLL0 with one feed sequence. 00086 LPC_SC->PLL0CON |= 0x02; /* PLL0 Connect */ 00087 LPC_SC->PLL0FEED = 0xAA; 00088 LPC_SC->PLL0FEED = 0x55; 00089 00090 // It is very important not to merge any steps above. For example, do not update the 00091 // PLL0CFG and enable PLL0 simultaneously with the same feed sequence. 00092 00093 00094 00095 // set PWM 00096 outGND1 = 0; // Just to have a GND near to the PWMs 00097 outGND2 = 0; // Just to have a GND near to the PWMs 00098 LPC_PWM1->TCR = (1 << 1); // Reset counter, disable PWM 00099 LPC_SC->PCLKSEL0 &= ~(0x3 << 12); 00100 LPC_SC->PCLKSEL0 |= (1 << 12); // Set peripheral clock divider to /1, i.e. system clock 00101 00102 LPC_PWM1->PCR |= 0x002C; // Double edge PWM for PWM2,3,5 00103 00104 LPC_PWM1->MR0 = 3; // Match Register 0 is shared period counter for all PWM1 00105 00106 LPC_PWM1->MR1 = 0; // so Match Register 0 00107 LPC_PWM1->MR2 = 2; // so Match Register 1 00108 LPC_PWM1->MR3 = 0; // so Match Register 2 00109 LPC_PWM1->MR4 = 1; // so Match Register 3 00110 LPC_PWM1->MR5 = 3; // so Match Register 3 00111 00112 LPC_PWM1->LER |= 1; // Start updating at next period start 00113 LPC_PWM1->TCR = (1 << 0) || (1 << 3); // Enable counter and PWM 00114 00115 while(1); 00116 }
Generated on Wed Jul 27 2022 03:29:55 by
1.7.2
Marco Graf