实验板:STM32F28335普中科技开发板
在配置好的项目里从main.c文件中修改寄存器配置
具体操作如下:
源代码:
main.c
/** main.c** Created on: 2018-3-21* Author: Administrator*/#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,通过循环占用CPU,达到延时功能
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void delay(void)
{Uint16 i;Uint32 j;for(i=0;i<32;i++)for (j = 0; j < 100000; j++);
}/*******************************************************************************
* 函 数 名 : LED_Init
* 函数功能 : LED初始化函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void LED_Init(void)
{EALLOW;//关闭写保护SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 开启GPIO时钟//LED1端口配置GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;//设置为通用GPIO功能GpioCtrlRegs.GPCDIR.bit.GPIO68=1;//设置GPIO方向为输出GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻GpioDataRegs.GPCSET.bit.GPIO68=1;//设置GPIO输出高电平EDIS;//开启写保护
}/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{InitSysCtrl();//系统时钟初始化,默认已开启F28335所有外设时钟LED_Init();while(1){GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;//设置GPIO输出翻转信号delay();}}
选择:
InitSysCtrl();//系统时钟初始化,默认已开启F28335所有外设时钟
按住ctrl+鼠标左键(单击)
进入:
DSP2833x_SysCtrl.c文件
//###########################################################################
//
// FILE: DSP2833x_SysCtrl.c
//
// TITLE: DSP2833x 的系统控制模块进行初始化。
//
// 作者:
//
//释放日期:
//###########################################################################
// DSP2833x 头文件
//############################################################################include "DSP2833x_Device.h" // Headerfile Include File
#include "DSP2833x_Examples.h" // Examples Include File//将InitFlash函数映射到CMD文件中的ramfuncs段,在CMD文件中ramfuncs段被分配到RAM里面#pragma CODE_SECTION(InitFlash, "ramfuncs");//---------------------------------------------------------------------------
// InitSysCtrl:
//---------------------------------------------------------------------------
// 这段函数的功能就是将系统控制寄存器初始化到想要的状态;
//具体步骤可以分成四部分:
// - 禁止看门狗电路
// - 给PLLCR寄存器赋值以获得想要的系统时钟频率
// - 给高、低速外设时钟预定标寄存器赋值以获得想要的高、低速外设时钟频率
// - 对需要使用的外设时钟进行使能void InitSysCtrl(void)
{// Disable the watchdogDisableDog();// Initialize the PLL control: PLLCR and DIVSEL// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.hInitPll(DSP28_PLLCR,DSP28_DIVSEL);// Initialize the peripheral clocksInitPeripheralClocks();
}//---------------------------------------------------------------------------
// 初始化FLASH函数
//---------------------------------------------------------------------------
// 此函数初始化FLASH控制寄存器// 注意
// 此函数必须在RAM中运行,如果在OTP/FLASH中运行的话讲产生不可预料的后果void InitFlash(void)
{EALLOW;//Enable Flash Pipeline mode to improve performance//of code executed from Flash.FlashRegs.FOPT.bit.ENPIPE = 1;// CAUTION//Minimum waitstates required for the flash operating//at a given CPU rate must be characterized by TI.//Refer to the datasheet for the latest information.
#if CPU_FRQ_150MHZ//Set the Paged Waitstate for the FlashFlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;//Set the Random Waitstate for the FlashFlashRegs.FBANKWAIT.bit.RANDWAIT = 5;//Set the Waitstate for the OTPFlashRegs.FOTPWAIT.bit.OTPWAIT = 8;
#endif#if CPU_FRQ_100MHZ//Set the Paged Waitstate for the FlashFlashRegs.FBANKWAIT.bit.PAGEWAIT = 3;//Set the Random Waitstate for the FlashFlashRegs.FBANKWAIT.bit.RANDWAIT = 3;//Set the Waitstate for the OTPFlashRegs.FOTPWAIT.bit.OTPWAIT = 5;
#endif// CAUTION//ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USEDFlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;EDIS;//Force a pipeline flush to ensure that the write to//the last register configured occurs before returning.asm(" RPT #7 || NOP");
}//---------------------------------------------------------------------------
//喂狗函数
//---------------------------------------------------------------------------
// 这个函数复位看门狗定时器void ServiceDog(void)
{EALLOW;SysCtrlRegs.WDKEY = 0x0055;SysCtrlRegs.WDKEY = 0x00AA;EDIS;
}//---------------------------------------------------------------------------
// 禁止看门狗函数
//---------------------------------------------------------------------------
// 此函数的作用是禁止看门狗定时器void DisableDog(void)
{EALLOW;SysCtrlRegs.WDCR= 0x0068;EDIS;
}//---------------------------------------------------------------------------
// PLL相关寄存器初始化函数
//---------------------------------------------------------------------------
// 此函数初始化PLLSTS[CLKINDIV]和PLLCR控制寄存器void InitPll(Uint16 val, Uint16 divsel)
{// Make sure the PLL is not running in limp modeif (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0){// Missing external clock has been detected// Replace this line with a call to an appropriate// SystemShutdown(); function.asm(" ESTOP0");}// DIVSEL MUST be 0 before PLLCR can be changed from// 0x0000. It is set to 0 by an external reset XRSn// This puts us in 1/4if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;EDIS;}// Change the PLLCRif (SysCtrlRegs.PLLCR.bit.DIV != val){EALLOW;// Before setting PLLCR turn off missing clock detect logicSysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;SysCtrlRegs.PLLCR.bit.DIV = val;EDIS;// Optional: Wait for PLL to lock.// During this time the CPU will switch to OSCCLK/2 until// the PLL is stable. Once the PLL is stable the CPU will// switch to the new PLL value.//// This time-to-lock is monitored by a PLL lock counter.//// Code is not required to sit and wait for the PLL to lock.// However, if the code does anything that is timing critical,// and requires the correct clock be locked, then it is best to// wait until this switching has completed.// Wait for the PLL lock bit to be set.// The watchdog should be disabled before this loop, or fed within// the loop via ServiceDog().// Uncomment to disable the watchdogDisableDog();while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1){// Uncomment to service the watchdog// ServiceDog();}EALLOW;SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;EDIS;}// If switching to 1/2if((divsel == 1)||(divsel == 2)){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;EDIS;}// If switching to 1/1// * First go to 1/2 and let the power settle// The time required will depend on the system, this is only an example// * Then switch to 1/1if(divsel == 3){EALLOW;SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;DELAY_US(50L);SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;EDIS;}
}//--------------------------------------------------------------------------
// 函数名:初始化外设时钟
//---------------------------------------------------------------------------
//这个是用来初始化外设模块的时钟,具体分2个步骤:
//首先设置高、低速外设预定标寄存器;
//第二是对各个外设时钟进行有选择的使能;
//为了降低功耗,尽量不使能不用的外设模块时钟;
//
//注:如果某一外设时钟没使能,则不能对其相关的寄存器进行读写;void InitPeripheralClocks(void)
{EALLOW;// HISPCP/LOSPCP prescale register settings, normally it will be set to default valuesSysCtrlRegs.HISPCP.all = 0x0001;SysCtrlRegs.LOSPCP.all = 0x0002;//Lowspeedclock=SYSCLKOUT/4=150/4=37.5MHZ;// XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT// XTIMCLK = SYSCLKOUT/2XintfRegs.XINTCNF2.bit.XTIMCLK = 1;// XCLKOUT = XTIMCLK/2XintfRegs.XINTCNF2.bit.CLKMODE = 1;// Enable XCLKOUTXintfRegs.XINTCNF2.bit.CLKOFF = 0;// Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2833x derivates.
// Refer to the datasheet for your particular device.
//
// This function is not written to be an example of efficient code.SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC// *IMPORTANT*// The ADC_cal function, which copies the ADC calibration values from TI reserved// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the// Boot ROM. If the boot ROM code is bypassed during the debug process, the// following function MUST be called for the ADC to function according// to specification. The clocks to the ADC MUST be enabled before calling this// function.// See the device data manual and/or the ADC Reference// Manual for more information.ADC_cal();SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2CSysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-ASysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-BSysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1; // SCI-CSysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-ASysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-ASysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-BSysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-ASysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1; // eCAN-BSysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // eCAP3SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // eCAP4SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // eCAP5SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // eCAP6SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // eCAP2SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA ClockSysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLKSysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clockEDIS;
}//---------------------------------------------------------------------------
// Example: CsmUnlock:
//---------------------------------------------------------------------------
// This function unlocks the CSM. User must replace 0xFFFF's with current
// password for the DSP. Returns 1 if unlock is successful.#define STATUS_FAIL 0
#define STATUS_SUCCESS 1Uint16 CsmUnlock()
{volatile Uint16 temp;// Load the key registers with the current password. The 0xFFFF's are dummy// passwords. User should replace them with the correct password for the DSP.EALLOW;CsmRegs.KEY0 = 0xFFFF;CsmRegs.KEY1 = 0xFFFF;CsmRegs.KEY2 = 0xFFFF;CsmRegs.KEY3 = 0xFFFF;CsmRegs.KEY4 = 0xFFFF;CsmRegs.KEY5 = 0xFFFF;CsmRegs.KEY6 = 0xFFFF;CsmRegs.KEY7 = 0xFFFF;EDIS;// Perform a dummy read of the password locations// if they match the key values, the CSM will unlocktemp = CsmPwl.PSWD0;temp = CsmPwl.PSWD1;temp = CsmPwl.PSWD2;temp = CsmPwl.PSWD3;temp = CsmPwl.PSWD4;temp = CsmPwl.PSWD5;temp = CsmPwl.PSWD6;temp = CsmPwl.PSWD7;// If the CSM unlocked, return succes, otherwise return// failure.if (CsmRegs.CSMSCR.bit.SECURE == 0) return STATUS_SUCCESS;else return STATUS_FAIL;}//===========================================================================
// End of file.
//===========================================================================
直接位置在:
void InitSysCtrl(void)
{// Disable the watchdogDisableDog();// Initialize the PLL control: PLLCR and DIVSEL// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.hInitPll(DSP28_PLLCR,DSP28_DIVSEL);// Initialize the peripheral clocksInitPeripheralClocks();
}
在:
里面:
DSP28_PLLCR是倍频
DSP28_DIVSEL是分频
我们的开发板使用的是内部时钟,外接晶振是30MHZ
系统默认10倍频,二分频,也就是系统时钟为(30*10)\2=150MHZ
我们继续:crtl+鼠标左击:DSP28_PLLCR
程序跳转到:
DSP2833x_Examples.h
// TI File $Revision: /main/7 $
// Checkin $Date: August 13, 2007 16:57:59 $
//###########################################################################
//
// FILE: DSP2833x_Examples.h
//
// TITLE: DSP2833x Device Definitions.
//
//###########################################################################
// $TI Release: DSP2833x Header Files V1.01 $
// $Release Date: September 26, 2007 $
//############################################################################ifndef DSP2833x_EXAMPLES_H
#define DSP2833x_EXAMPLES_H#ifdef __cplusplus
extern "C" {
#endif/*-----------------------------------------------------------------------------Specify the PLL control register (PLLCR) and divide select (DIVSEL) value.
-----------------------------------------------------------------------------*/
//#define DSP28_DIVSEL 0 // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL 1 // Disable /4 for SYSCKOUT
#define DSP28_DIVSEL 2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL 3 // Enable /1 for SYSCLKOUT#define DSP28_PLLCR 10
//#define DSP28_PLLCR 9
//#define DSP28_PLLCR 8
//#define DSP28_PLLCR 7
//#define DSP28_PLLCR 6
//#define DSP28_PLLCR 5
//#define DSP28_PLLCR 4
//#define DSP28_PLLCR 3
//#define DSP28_PLLCR 2
///#define DSP28_PLLCR 1
//#define DSP28_PLLCR 0 // PLL is bypassed in this mode
//----------------------------------------------------------------------------/*-----------------------------------------------------------------------------Specify the clock rate of the CPU (SYSCLKOUT) in nS.Take into account the input clock frequency and the PLL multiplierselected in step 1.Use one of the values provided, or define your own.The trailing L is required tells the compiler to treatthe number as a 64-bit value.Only one statement should be uncommented.Example 1:150 MHz devices:CLKIN is a 30MHz crystal.In step 1 the user specified PLLCR = 0xA for a150Mhz CPU clock (SYSCLKOUT = 150MHz).In this case, the CPU_RATE will be 6.667LUncomment the line: #define CPU_RATE 6.667LExample 2: 100 MHz devices:CLKIN is a 20MHz crystal.In step 1 the user specified PLLCR = 0xA for a100Mhz CPU clock (SYSCLKOUT = 100MHz).In this case, the CPU_RATE will be 10.000LUncomment the line: #define CPU_RATE 10.000L
-----------------------------------------------------------------------------*/
#define CPU_RATE 6.667L // for a 150MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 7.143L // for a 140MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 8.333L // for a 120MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 10.000L // for a 100MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 13.330L // for a 75MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 20.000L // for a 50MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 33.333L // for a 30MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 41.667L // for a 24MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 50.000L // for a 20MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 66.667L // for a 15MHz CPU clock speed (SYSCLKOUT)
//#define CPU_RATE 100.000L // for a 10MHz CPU clock speed (SYSCLKOUT)//----------------------------------------------------------------------------/*-----------------------------------------------------------------------------Target device (in DSP2833x_Device.h) determines CPU frequency(for examples) - either 150 MHz (for 28335 and 28334) or 100 MHz(for 28332). User does not have to change anything here.
-----------------------------------------------------------------------------*/
#if DSP28_28332 // DSP28_28332 device only#define CPU_FRQ_100MHZ 1 // 100 Mhz CPU Freq (20 MHz input freq)#define CPU_FRQ_150MHZ 0
#else#define CPU_FRQ_100MHZ 0 // DSP28_28335||DSP28_28334#define CPU_FRQ_150MHZ 1 // 150 MHz CPU Freq (30 MHz input freq) by DEFAULT
#endif//---------------------------------------------------------------------------
// Include Example Header Files:
//#include "DSP2833x_GlobalPrototypes.h" // Prototypes for global functions within the// .c files.#include "DSP2833x_ePwm_defines.h" // Macros used for PWM examples.
#include "DSP2833x_Dma_defines.h" // Macros used for DMA examples.
#include "DSP2833x_I2C_defines.h" // Macros used for I2C examples.
#include "LED.h" //为7段数码管实验使用的头文件#define PARTNO_28335 0xFA
#define PARTNO_28334 0xF9
#define PARTNO_28332 0xF8// Include files not used with DSP/BIOS
#ifndef DSP28_BIOS
#include "DSP2833x_DefaultISR.h"
#endif// DO NOT MODIFY THIS LINE.
#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)#ifdef __cplusplus
}
#endif /* extern "C" */#endif // end of DSP2833x_EXAMPLES_H definition//===========================================================================
// End of file.
//===========================================================================
其中的:
//#define DSP28_DIVSEL 0 // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL 1 // Disable /4 for SYSCKOUT
#define DSP28_DIVSEL 2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL 3 // Enable /1 for SYSCLKOUT#define DSP28_PLLCR 10
//#define DSP28_PLLCR 9
//#define DSP28_PLLCR 8
//#define DSP28_PLLCR 7
//#define DSP28_PLLCR 6
//#define DSP28_PLLCR 5
//#define DSP28_PLLCR 4
//#define DSP28_PLLCR 3
//#define DSP28_PLLCR 2
///#define DSP28_PLLCR 1
//#define DSP28_PLLCR 0 // PLL is bypassed in this mode
没有被注释掉的就是系统默认倍频和分频
分别为10和2
那我们注释掉10和2,选择1和4
那么如代码所示:
//#define DSP28_DIVSEL 0 // Enable /4 for SYSCLKOUT
#define DSP28_DIVSEL 1 // Disable /4 for SYSCKOUT
//#define DSP28_DIVSEL 2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL 3 // Enable /1 for SYSCLKOUT//#define DSP28_PLLCR 10
//#define DSP28_PLLCR 9
//#define DSP28_PLLCR 8
//#define DSP28_PLLCR 7
//#define DSP28_PLLCR 6
//#define DSP28_PLLCR 5
//#define DSP28_PLLCR 4
//#define DSP28_PLLCR 3
//#define DSP28_PLLCR 2
#define DSP28_PLLCR 1
//#define DSP28_PLLCR 0 // PLL is bypassed in this mode
那么时钟频率变为30*1\4=7.5MHZ
如果原来时钟频率通过延时等点亮熄灭间隔1秒
新的系统时钟频率降低,延时增加为原来的150\7.5=20倍
间隔时间成为20s
注意:修改代码后需要全部保存文件,再运行调试,才会出现新的结果,不保存所有文件默认代码未被修改
做完实验记得把时钟频率改回来,成为最佳默认频率
同时,在点击Debug后,代码自动下载到开发板里,成为调试状态,这时候千万不可以断电或者复位,否则芯片就锁死了,只有最后下载的代码,不可以再保存新代码了,新的代码只有调试作用,不会被下载到开发板里保存了,也就是即使下载了新的代码,也不会保存,一重启,重启同时会复位,还是锁死前的最后一个代码
视频如下:
STM32F28335系统时钟分频实验