This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I'm having problems with TM4C123GXL and PWM

Hi,

I'm having an issue getting PWM to work consistently on a TM4C123GXL using Keil.

When I deploy to the board and hit the reset button I get nothing out of pin PB6 (M0PWM0), however, when I deploy to the board and then debug, I get the output I expect.

I've tried the code I wrote (using the user manual as a guide), and also some sample code I found (from a UTAustin course).

This is the code I wrote, and I've attached the project below.

void initMotors (void){
	
	volatile unsigned long delay;
	
	SYSCTL_RCGC0_R |= 0x00100000;   // Enable PWM clock
	delay = SYSCTL_RCGC0_R;
	
	SYSCTL_RCGC2_R |= 0x02;		      // Turn on the clock for Port B 
	delay = SYSCTL_RCGC2_R;		      
	
	GPIO_PORTB_AFSEL_R |= 0xC0;			// Enable the alt function for PB6/7
	GPIO_PORTB_DEN_R |= 0xC0;			  // Enable digital on PB6/7
	GPIO_PORTB_AMSEL_R &= 0x00;			// Disable analog function on all PB pins
	GPIO_PORTB_PCTL_R |= 0x44000000;  // Set Port control to select PWM as the Alt function
	
	// Divide the 80MHz system clock by 8 to get 10MHz PWM clock
	// Set the period to 20,000. so 10,000,000 / 20,000 = 500Hz wave period, which is just above the Energia frequency.
	
	SYSCTL_RCC_R |= 0x00100000;      // Enable PWM clock divisor
	SYSCTL_RCC_R &= ~0x000C0000;     // Set to /8 divider
	
	PWM0_CTL_R = 0x00000000;        // Configure the PWM generator for countdown mode with immediate updates to the parameters.
	PWM0_GENA_R = 0x0000008C;       // High on load, low on comparator A down
	PWM0_GENB_R = 0x0000080C;       // High on load, low on comparator B down
	
	PWM0_LOAD_R = 19999;             // This is the period, number of clock ticks per period
	
	// How much of the period the output will remain low. 
	// When it's running for these motors we want 50% (10000)
	// But set to 100% for init
	PWM0_CMPA_R = 9999; //19999;
	PWM0_CMPB_R = 9999; //19999;
	
	PWM0_CTL_R = 0x00000001;         // Enable PWM
	PWM_ENABLE_R |= 0x00000003;      // Enable PWM Outputs on M0PWM0 (PB6) + M0PWM1 (PB7)
	
}

pwmtest2.zip

I realise some of the above code uses "legacy" registers, but the sample code I used (included in the project file, but commented out) does not, I was trying to see whether there was something wrong with either way or if they produced the same results.

Does anyone have any idea what might be wrong with this? I've been banging my head against the desk for a few days now, and the threads on here and elsewhere don't seem to have helped.

Thanks

Will

  • Hello Will,

    Did you check if the scatter file has the address of the application's reset vector at 0x0? You can see the same in the map file report after the program compiles.

    Regards
    Amit
  • Hi Amit, thanks for your reply.

    I've just checked the map file and yes reset is at 0x00.

    I should note, I've extracted the PWM code from a bigger project that does other things, the other things work fine, I just wanted to be sure they weren't affecting the PWM stuff, so I took it out to try and debug on it's own.

    Thanks again

    Will
  • Hello Will,

    The code otherwise seems fine (though I see a small part of the code). When after power up the code does not work and you connect a debugger is the CPU showing that is in Fault handler? If yes then my best guess will be

    SYSCTL_RCGC2_R |= 0x02; // Turn on the clock for Port B
    delay = SYSCTL_RCGC2_R;

    That the delay is not sufficient. Also as a suggestion move away from the DRM method of coding and rely on API's from TivaWare. Code is more readable.

    Regards
    Amit
  • Don't see the PWM generators being enabled prior to configuring, find it strange GENA/B work at all - often don't & simply halt other class MPU.
  • Hello BP101

    It is there in last-but-one line

    PWM0_CTL_R = 0x00000001; // Enable PWM

    The DRM makes it a tough reading

    Regards,
    Amit
  • Amit from my past experience Gen enable need be right after clock set or later configuring the generators trap an exception. Never seem to have exception events during debug stepping similar PWM code with ICDI set to ignore interrupts while single stepping F5/F6.

    BTW: That appears to be the peripheral enable ?

    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_2);
  • Hello BP101,

    It seems that the defines are coming for the poster from some place else and not for TivaWare (PWM_ENABLE_R is not defined in TivaWare). My suspicion is on Port B clocking and register operations

    Regards
    Amit
  • Hi Amit,

    I've only run a few short tests but it looks like you've solved it!

    I've introduced a 10ms delay after enabling Port B and it's running perfectly now.

    Thanks so much for your help with this, I will also take a good look at TivaWare.

    Will
  • Hello Will,

    My suggestion: Move away from the DRM and to the API's, as we may deprecate the DRM's due to the very specific reason of low readability, higher maintenance and more chances of an error.

    Regards
    Amit