TI论坛
直播中

李秀容

7年用户 204经验值
私信 关注
[问答]

TM4C123GXL PWM模块在没有使用锁相环的情况下修改外部时钟频率,下进板子后的PWM频率仍未改变的原因?

单片机 TM4C123GXL,芯片GH6PM
CCS 版本6.0.1
之前程序时钟设置为: SysCtlClockSet(SYSCTL_SYSDIV_64|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
在将时钟改为18MHz时,即SysCtlClockSet(SYSCTL_SYSDIV_64|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN |SYSCTL_XTAL_18MHZ);
使用示波器观察对应GPIO口,PWM波频率没有改变,这是为什么呢?
附程序如下:
/*利用PWMO,PWM1产生200HZ和400Hz 50%占空比的方波*/
#include
#include
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"
#include "driverlib/fpu.h"
#include "driverlib/pin_map.h"
int main (void)
[
//使能FPU
FPUEnable();
FPULazyStackingEnable();
//设置系统时钟为16MHz
SysCtlClockSet(SYSCTL_SYSDIV_64|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
//使能PWM0模块,使能PWM0和PWM1输出所在GPIO
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
GPIOPinConfigure(GPIO_PB6_M0PWM0);
GPIOPinConfigure(GPIO_PB7_M0PWM1);
GPIOPinConfigure(GPIO_PB4_M0PWM2);
GPIOPinConfigure(GPIO_PB5_M0PWM3);
//驱动电流8MA,推挽输出
GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,
GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
// PWM时钟配置
SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
// SysCtlPWMClockSet(SYSCTL_PWMDIV_32);
//配置PWM发生器0:加减计数,不同步
PWMGenConfigure(PWM0_BASE,PWM_GEN_0,PWM_GEN_MODE_UP_DOWN| PWM_GEN_MODE_NO_SYNC);
PWMGenConfigure(PWM0_BASE,PWM_GEN_1,PWM_GEN_MODE_UP_DOWN| PWM_GEN_MODE_NO_SYNC);
//设置PWM发生器0的频率,时钟频率/PWM分频数/n,16M/64/1250=200HZ
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 1250);
//设置PWM发生器1的频率,时钟频率/PWM分频数/n,16M/16/625=400HZ
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, 625);
//设置PWM0/PWM1输出的脉冲宽度
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,1250/2);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,1250/2);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2,625/2);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3,625/2);
//使能PWM0和PWM1的输出
PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT |PWM_OUT_1_BIT| PWM_OUT_2_BIT| PWM_OUT_3_BIT), true);
//使能PWM发生器
PWMGenEnable(PWM0_BASE, PWM_GEN_0);
PWMGenEnable(PWM0_BASE, PWM_GEN_1);
while(1)
[
]
]

回帖(8)

冯敬宇

2020-8-26 13:52:01
SysCtlClockSet(SYSCTL_SYSDIV_64|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
SYSCTL_SYSDIV_64改变这个配置来修改其频率
SYSCTL_XTAL_16MHZ 这个参数只是你外部接的晶振频率 
详细你可以参考TI数据手册上具体描述
//*****************************************************************************
//
//! Sets the clocking of the device.
//!
//! param ui32Config is the required configuration of the device clocking.
//!
//! This function configures the clocking of the device. The input crystal
//! frequency, oscillator to be used, use of the PLL, and the system clock
//! divider are all configured with this function.
//!
//! The e ui32Config parameter is the logical OR of several different values,
//! many of which are grouped into sets where only one can be chosen.
//!
//! The system clock divider is chosen with one of the following values:
//! b SYSCTL_SYSDIV_1, b SYSCTL_SYSDIV_2, b SYSCTL_SYSDIV_3, ...
//! b SYSCTL_SYSDIV_64.
//!
//! The use of the PLL is chosen with either b SYSCTL_USE_PLL or
//! b SYSCTL_USE_OSC.
//!
//! The external crystal frequency is chosen with one of the following values:
//! b SYSCTL_XTAL_4MHZ, b SYSCTL_XTAL_4_09MHZ, b SYSCTL_XTAL_4_91MHZ,
//! b SYSCTL_XTAL_5MHZ, b SYSCTL_XTAL_5_12MHZ, b SYSCTL_XTAL_6MHZ,
//! b SYSCTL_XTAL_6_14MHZ, b SYSCTL_XTAL_7_37MHZ, b SYSCTL_XTAL_8MHZ,
//! b SYSCTL_XTAL_8_19MHZ, b SYSCTL_XTAL_10MHZ, b SYSCTL_XTAL_12MHZ,
//! b SYSCTL_XTAL_12_2MHZ, b SYSCTL_XTAL_13_5MHZ, b SYSCTL_XTAL_14_3MHZ,
//! b SYSCTL_XTAL_16MHZ, b SYSCTL_XTAL_16_3MHZ, b SYSCTL_XTAL_18MHZ,
//! b SYSCTL_XTAL_20MHZ, b SYSCTL_XTAL_24MHZ, or b SYSCTL_XTAL_25MHz.
//! Values below b SYSCTL_XTAL_5MHZ are not valid when the PLL is in
//! operation.
//!
//! The oscillator source is chosen with one of the following values:
//! b SYSCTL_OSC_MAIN, b SYSCTL_OSC_INT, b SYSCTL_OSC_INT4,
//! b SYSCTL_OSC_INT30, or b SYSCTL_OSC_EXT32. b SYSCTL_OSC_EXT32 is only
//! available on devices with the hibernate module, and then only when the
//! hibernate module has been enabled.
//!
//! The internal and main oscillators are disabled with the
//! b SYSCTL_INT_OSC_DIS and b SYSCTL_MAIN_OSC_DIS flags, respectively.
//! The external oscillator must be enabled in order to use an external clock
//! source. Note that attempts to disable the oscillator used to clock the
//! device is prevented by the hardware.
//!
//! To clock the system from an external source (such as an external crystal
//! oscillator), use b SYSCTL_USE_OSC b | b SYSCTL_OSC_MAIN. To clock the
//! system from the main oscillator, use b SYSCTL_USE_OSC b |
//! b SYSCTL_OSC_MAIN. To clock the system from the PLL, use
//! b SYSCTL_USE_PLL b | b SYSCTL_OSC_MAIN, and select the appropriate
//! crystal with one of the b SYSCTL_XTAL_xxx values.
//!
//! note This function should only be called on TM4C123 devices. For
//! all other devices use the SysCtlClockFreqSet() function.
//!
//! note If selecting the PLL as the system clock source (that is, via
//! b SYSCTL_USE_PLL), this function polls the PLL lock interrupt to
//! determine when the PLL has locked. If an interrupt handler for the
//! system control interrupt is in place, and it responds to and clears the
//! PLL lock interrupt, this function delays until its timeout has occurred
//! instead of completing as soon as PLL lock is achieved.
//!
//! return None.
//
//*****************************************************************************
void
SysCtlClockSet(uint32_t ui32Config)
[
uint32_t ui32Delay, ui32RCC, ui32RCC2;
//
// Get the current value of the RCC and RCC2 registers.
//
ui32RCC = HWREG(SYSCTL_RCC);
ui32RCC2 = HWREG(SYSCTL_RCC2);
//
// Bypass the PLL and system clock dividers for now.
//
ui32RCC |= SYSCTL_RCC_BYPASS;
ui32RCC &= ~(SYSCTL_RCC_USESYSDIV);
ui32RCC2 |= SYSCTL_RCC2_BYPASS2;
//
// Write the new RCC value.
//
HWREG(SYSCTL_RCC) = ui32RCC;
HWREG(SYSCTL_RCC2) = ui32RCC2;
//
// See if the oscillator needs to be enabled.
//
if((ui32RCC & SYSCTL_RCC_MOSCDIS) && !(ui32Config & SYSCTL_MAIN_OSC_DIS))
[
//
// Make sure that the required oscillators are enabled. For now, the
// previously enabled oscillators must be enabled along with the newly
// requested oscillators.
//
ui32RCC &= (~SYSCTL_RCC_MOSCDIS | (ui32Config & SYSCTL_MAIN_OSC_DIS));
//
// Clear the MOSC power up raw interrupt status to be sure it is not
// set when waiting below.
//
HWREG(SYSCTL_MISC) = SYSCTL_MISC_MOSCPUPMIS;
//
// Write the new RCC value.
//
HWREG(SYSCTL_RCC) = ui32RCC;
//
// Timeout using the legacy delay value.
//
ui32Delay = 524288;
while((HWREG(SYSCTL_RIS) & SYSCTL_RIS_MOSCPUPRIS) == 0)
[
ui32Delay--;
if(ui32Delay == 0)
[
break;
]
]
//
// If the main oscillator failed to start up then do not switch to
// it and return.
//
if(ui32Delay == 0)
[
return;
]
]
//
// Set the new crystal value and oscillator source. Because the OSCSRC2
// field in RCC2 overlaps the XTAL field in RCC, the OSCSRC field has a
// special encoding within ui32Config to avoid the overlap.
//
ui32RCC &= ~(SYSCTL_RCC_XTAL_M | SYSCTL_RCC_OSCSRC_M);
ui32RCC |= ui32Config & (SYSCTL_RCC_XTAL_M | SYSCTL_RCC_OSCSRC_M);
ui32RCC2 &= ~(SYSCTL_RCC2_USERCC2 | SYSCTL_RCC2_OSCSRC2_M);
ui32RCC2 |= ui32Config & (SYSCTL_RCC2_USERCC2 | SYSCTL_RCC_OSCSRC_M);
ui32RCC2 |= (ui32Config & 0x00000008) << 3;
//
// Write the new RCC value.
//
HWREG(SYSCTL_RCC) = ui32RCC;
HWREG(SYSCTL_RCC2) = ui32RCC2;
//
// Set the PLL configuration.
//
ui32RCC &= ~SYSCTL_RCC_PWRDN;
ui32RCC |= ui32Config & SYSCTL_RCC_PWRDN;
ui32RCC2 &= ~SYSCTL_RCC2_PWRDN2;
ui32RCC2 |= ui32Config & SYSCTL_RCC2_PWRDN2;
//
// Clear the PLL lock interrupt.
//
HWREG(SYSCTL_MISC) = SYSCTL_MISC_PLLLMIS;
//
// Write the new RCC value.
//
if(ui32RCC2 & SYSCTL_RCC2_USERCC2)
[
HWREG(SYSCTL_RCC2) = ui32RCC2;
HWREG(SYSCTL_RCC) = ui32RCC;
]
else
[
HWREG(SYSCTL_RCC) = ui32RCC;
HWREG(SYSCTL_RCC2) = ui32RCC2;
]
//
// Set the requested system divider and disable the appropriate
// oscillators. This value is not written immediately.
//
ui32RCC &= ~(SYSCTL_RCC_SYSDIV_M | SYSCTL_RCC_USESYSDIV |
SYSCTL_RCC_MOSCDIS);
ui32RCC |= ui32Config & (SYSCTL_RCC_SYSDIV_M | SYSCTL_RCC_USESYSDIV |
SYSCTL_RCC_MOSCDIS);
ui32RCC2 &= ~(SYSCTL_RCC2_SYSDIV2_M);
ui32RCC2 |= ui32Config & SYSCTL_RCC2_SYSDIV2_M;
if(ui32Config & SYSCTL_RCC2_DIV400)
[
ui32RCC |= SYSCTL_RCC_USESYSDIV;
ui32RCC2 &= ~(SYSCTL_RCC_USESYSDIV);
ui32RCC2 |= ui32Config & (SYSCTL_RCC2_DIV400 | SYSCTL_RCC2_SYSDIV2LSB);
]
else
[
ui32RCC2 &= ~(SYSCTL_RCC2_DIV400);
]
//
// See if the PLL output is being used to clock the system.
//
if(!(ui32Config & SYSCTL_RCC_BYPASS))
[
//
// Wait until the PLL has locked.
//
for(ui32Delay = 32768; ui32Delay > 0; ui32Delay--)
[
if((HWREG(SYSCTL_PLLSTAT) & SYSCTL_PLLSTAT_LOCK))
[
break;
]
]
//
// Enable use of the PLL.
//
ui32RCC &= ~(SYSCTL_RCC_BYPASS);
ui32RCC2 &= ~(SYSCTL_RCC2_BYPASS2);
]
//
// Write the final RCC value.
//
HWREG(SYSCTL_RCC) = ui32RCC;
HWREG(SYSCTL_RCC2) = ui32RCC2;
//
// Delay for a little bit so that the system divider takes effect.
//
SysCtlDelay(16);
]
举报

李秀容

2020-8-26 14:04:03
引用: guigui_7044 发表于 2020-8-26 13:52
SysCtlClockSet(SYSCTL_SYSDIV_64|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
SYSCTL_SYSDIV_64改变这个配置来修改其频率
SYSCTL_XTAL_16MHZ 这个参数只是你外部接的晶振频率 

Maka:
您好,
您的意思指的是在不改变分频数的情况下,修改外接晶振频率是无法改变时钟频率的吗?请问是否就意味着输出时钟频率要么是16MHz要么是锁相环的200MHz?
谢谢!
举报

刘丽艳

2020-8-26 14:21:13
引用: kuangbendetuzi 发表于 2020-8-26 14:04
Maka:
您好,
您的意思指的是在不改变分频数的情况下,修改外接晶振频率是无法改变时钟频率的吗?请问是否就意味着输出时钟频率要么是16MHz要么是锁相环的200MHz?

问题是你的晶振频率在物理上改变没有
                                                                         Holly
举报

李秀容

2020-8-26 14:26:20
引用: ctx1129 发表于 2020-8-26 14:21
问题是你的晶振频率在物理上改变没有
                                                                         Holly

HG:
您好,
我只是在程序上去选择外接的晶振(可以这样说吗?),用SysCtlClockSet选择不同的外接。您说晶振频率在物理上的改变是像更换晶振这类的吗?
谢谢
举报

更多回帖

发帖
×
20
完善资料,
赚取积分