TMS320F28335开发板之时钟和看门狗模块

一.时钟模块

    28335 DSP的额定工作时钟频率是150MHz。高的时钟频率必然会带来电磁干扰,为了减少电磁干扰,必须减小晶振的输出频率。这里引出了“分频和倍频”的概念,正是有了分频和倍频才更容易获得各种频率。28335 分频和倍频的倍数从0.25~10倍之间,而自带晶振是30MHz(我的是这样,大家的可能有所不同),要想获得150MHz,可以先二分频,再十倍频,就可以得到150MHZ。这样做的好处不仅可以有效减少电磁干扰,同是降低晶振的制造成本。有些人会问,必须用30MHz的晶振吗,用其他的晶振(例如20MHz)可以吗?理论上是可以的,但是分频一般是1/2的n次幂,倍频一般是整数,所以挑选最合适的晶振就行。

  1.  时钟电路是微处理器电路系统中重要的组成部分,是其运行的基准。TMS320F2833x DSP得处理器内部的各模块使用的时钟源是不同的,主要有5种类型的时钟信号:

  • 外部晶体(晶振):通过引脚X1、X2或外部时钟通过XCLKIN/X1提供的时钟信号,该时钟信号记为OSCCLK。
  • OSCCLK通过锁相环(PLL)模块后或直接送至CPU,这个时钟信号为CPU时钟输入,记为CLKIN。
  • CLKIN输入CPU后,CPU将其输出,称为CPU时钟输出或系统输出时钟,记为SYSCLKOUT。SYSCLKOUT与CLKIN频率相同。
  • 片内外设所使用的高速外设时钟HSPCLK。这个时钟信号通过对CPU时钟SYSCLKOUT分频得到。
  • 片内外设所使用的低速外设时钟LSPCLK。这个时钟信号通过对CPU时钟SYSCLKOUT分频得到。

2.时钟模块的组成:

  • 锁相环PLL(Phased Lock Loop);
  • 晶振(Crystal Oscillator);
  • 时钟监视电路(Clock Monitor Circuit);
  • 时钟使能电路(Clock Enable Circuit)。

3.晶体振荡器与PLL模块

    F2833x系列DSP可以通过外置晶体振荡器胡外部时钟信号提供时钟,并通过内部锁相环回路倍频后提供给系统。用户可以根据实际运行频率计算所需的倍频系数,并通过软件设置PLL的倍频系数。下图为片上外设时钟的产生。

QQæªå¾20160113130637.png

4.基于PLL的时钟模块

F2833x芯片都有一个片上基于PLL的时钟模块,该模块有一个4位比例控制寄存器,可以为CPU选择不同的时钟频率。下面是振荡器和PLL模块结构图:

4510474a-a849-42e7-9c87-b75a04b8b6cd.jpg

 基于PLL的时钟模块可以提供一下两种操作模式:

1)晶体振荡器操作。片上振荡器允许使用外部晶体振荡器为芯片提供时间基准,该晶体振荡器与X1、X2引脚相连,并且XCLKIN引脚拉低。

2)外部时钟源操作。如果没有使用片上振荡器,该模式允许内部振荡器被旁路,芯片时钟来自X1引脚或XCLKIN引脚的外部时钟源产生。

QQæªå¾20160113134932.png

  • PLL控制寄存器PLLCR

QQæªå¾20160113142413.png

QQæªå¾20160113144850.png

  • 外设时钟控制寄存器PCLKCR0、1、3

    PCLKCR0/1/3寄存器使能/禁止各种外设模块的输入时钟信号。PCLKCR0/1/3寄存器的写操作会产生2个SYSCLKOUT周期的延迟。由于外设GPIO是复用的,所有的外设不能让你同时使用;然而同时使能外设的时钟是可能的,但是这样的配置是无效的。

  • 高速外设时钟预定标寄存器(HISPCP)

  • 低速外设时钟预定标寄存器(LOSPCP)

  • PLL状态寄存器(PLLSTS)

  • 低功耗模式控制寄存器(LPMCR0)

二.看门狗模块

1.看门狗的功能:

    看门狗(WatchDog,WD)常用来监控程序的执行。只要8位的看门狗计数器达到其最大值,该模块就会产生中断或使其处理器复位。为了避免以上情况发生,用户必须禁用计数器或在程序中按时把0x55和0xAA两个数据先后写入(顺序不能颠倒)看门狗的关键字寄存器(“喂狗”),使看门狗计数器复位。

2.看门狗时钟

    外部的振荡时钟信号(OSCCLK)经过512分频器后,再经过看门狗分频器WDPS(2:0)分频产生WDCLK信号,即看门狗时钟信号。

    如果看门狗控制寄存器WDCR中的WDDIS位为0,则WDCLK将作为看门狗计数器寄存器WDCNTR的计数时钟,使其计数。当该8位计数器达到最大值时,看门狗会产生一输出脉冲(/WDRST)或(/WDINT)中断信号(其宽度为512个OSCCLK时钟周期)。

3.看门狗的组成

  • 定时器(计数器)WD Counter
  • 看门狗重启管理器WD Reset Register
  • 看门狗时钟发生器
  • 看门狗状态位

QQ截图20160113161652.png

4.看门狗复位、中断模式

    看门狗计数器达到最大值时,看门狗将输出复位信号(/WDRST)或中断信号(/WDINT)。前者将引起锌片复位,后者将发出中断请求.

    1)复位模式。当看门狗计数器达到最大值时,将输出(/WDRST)复位信号,该信号将芯片复位引脚(/XRS)拉低并维持512个OSCCLK周期。

    2)中断模式。当看门狗计数器达到最大值时,将输出(/WDINT)中断信号,该信号将被拉低并维持512个OSCCLK周期;若在PIE中断中使能了该中断,则WAKEPIE将被PIE响应。看门狗中断由/WDINT信号的下降沿触发,因此若在/WDINT信号变为无效之前,又使能了WAKEINT中断,程序将不会立即进入下一个WAKEINT中断;下一个WAKEINT中断将发生在下一次看门狗溢出时发生。

    若在/WDINT仍然有效时,将看门狗从中断模式配置成复位模式,则会立即引起设备的复位。再将看门狗重新配置成复位模式之前,可通过读取SCSR寄存器的WDINTS位来判断当前/WDINT信号是否仍处于有效状态。

5.相关寄存器

  • 系统控制和状态寄存器(SCSR)

WDINTS:看门狗中断状态位 ;WDENINT:看门狗中断使能位 ;WDOVERRIDE:看门狗受保护位

  • 看门狗计数寄存器(WDCNTR)

  • 看门狗复位关键字寄存器(WDKEY)

  • 看门狗控制寄存器(WDCR)

*************************************************************************************************************************************************

硬件部分结束,下面是软件部分

1.Example_2833xWatchdog.c 【看门狗实验】

// TI File $Revision: /main/9 $
// Checkin $Date: April 21, 2008 15:43:50 $
//###########################################################################
//
// FILE: Example_2833xWatchdog.c
//
// TITLE: DSP2833x Watchdog interrupt test program.
//
// ASSUMPTIONS:
//
// This program requires the DSP2833x header files.
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 2833x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// $Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// PU PU PU PU
// ==========================================
// 1 1 1 1 Jump to Flash
// 1 1 1 0 SCI-A boot
// 1 1 0 1 SPI-A boot
// 1 1 0 0 I2C-A boot
// 1 0 1 1 eCAN-A boot
// 1 0 1 0 McBSP-A boot
// 1 0 0 1 Jump to XINTF x16
// 1 0 0 0 Jump to XINTF x32
// 0 1 1 1 Jump to OTP
// 0 1 1 0 Parallel GPIO I/O boot
// 0 1 0 1 Parallel XINTF boot
// 0 1 0 0 Jump to SARAM <- "boot to SARAM"
// 0 0 1 1 Branch to check boot mode
// 0 0 1 0 Boot to flash, bypass ADC cal
// 0 0 0 1 Boot to SARAM, bypass ADC cal
// 0 0 0 0 Boot to SCI-A, bypass ADC cal
// Boot_Table_End$
//
// DESCRIPTION:
//
// This program exercises the watchdog.
//
// First the watchdog is connected to the WAKEINT interrupt of the
// PIE block. The code is then put into an infinite loop.
//
// The user can select to feed the watchdog key register or not
// by commenting one line of code in the infinite loop.
//
// If the watchdog key register is fed by the ServiceDog function
// then the WAKEINT interrupt is not taken. If the key register
// is not fed by the ServiceDog function then WAKEINT will be taken.
//
// Watch Variables:
// LoopCount for the number of times through the infinite loop
// WakeCount for the number of times through WAKEINT
//
//###########################################################################
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#include "DSP2833x_Device.h" // Headerfile Include File
#include "DSP2833x_Examples.h" // Examples Include File
// Prototype statements for functions found within this file.
interrupt void wakeint_isr(void); //若PIE模块使能,看门狗中断模式时中断信号的中断子程序;
// Global variables for this example
Uint32 WakeCount;
Uint32 LoopCount;
void main(void) //主函数
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
InitSysCtrl(); 这部分重点看一下 //看门狗只有用到的时候才会在初始化程序中,这里有必要看一看,“Open Definitions”,下面是我拿过来的初始化函数,大家可以分析一下。
void InitSysCtrl(void)
{
// Disable the watchdog
DisableDog(); //关闭看门狗
// Initialize the PLL control: PLLCR and DIVSEL
// DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h
InitPll(DSP28_PLLCR,DSP28_DIVSEL); //初始化PLL模块,初始化这部分大家看看上面理论部分的PLL修改流程图,然后看看Initpll()函数内部.这里也稍作解释,DSP28_PLLCR变量和DSP28_DIVSEL变量可以用“Open Declarations”来看,DSP28_PLLCR=10,DSP28_DIVSEL=2,即对OSCCLK系统时钟进行10倍频和2分频获得150MHz的SYSCLKOUT或CLKIN给看门狗使用。
// Initialize the peripheral clocks
InitPeripheralClocks(); //初始化外设时钟,可以“Open Definitions”看看函数的作用。我这里直接写出来:将高速外设时钟=SYSCLKOUT/2,低速外设时钟=SYSCLKOUT/4,这部分也能使能/禁止所有外设的时钟
}

// Step 2. Initalize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to //以上系统初始化;
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.WAKEINT = &wakeint_isr; //将中断子程序的初始地址指向中断向量表(由于中断向量表是被写保护的,所以在开头和结尾要分别加上EALLOW和EDIS)
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
// Step 5. User specific code, enable interrupts:
// Clear the counters
WakeCount = 0; // Count interrupts //记录看门狗中断次数;
LoopCount = 0; // Count times through idle loop //记录看门狗空循环次数;
// Connect the watchdog to the WAKEINT interrupt of the PIE
// Write to the whole SCSR register to avoid clearing WDOVERRIDE bit
EALLOW;
SysCtrlRegs.SCSR = BIT1; //配置看门狗系统控制和状态寄存器,具体BIT的值可以“Open Declarations”,在这里BIT1=0x0002,即看门狗中断使能,看门狗工作在中断模式;
EDIS;
// Enable WAKEINT in the PIE: Group 1 interrupt 8
// Enable INT1 which is connected to WAKEINT:
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block //PIE开中断
PieCtrlRegs.PIEIER1.bit.INTx8 = 1; // Enable PIE Gropu 1 INT8 //看门狗中断信号GROUP1 interrupt 8
IER |= M_INT1; // Enable CPU int1 //使能CPU 通道1
EINT; // Enable Global Interrupts //全局开中断
// Reset the watchdog counter
ServiceDog(); //看门狗程序,想要查看具体函数可以“Open Definitions”,这里是定时向看门狗复位关键字寄存器写入0xAA和0x55
// Enable the watchdog
EALLOW;
SysCtrlRegs.WDCR = 0x0028; //配置看门狗控制寄存器0x0010 1000,看门狗检查位WDCHK,必须为101;写入其他只会导致看门狗立即产生复位或中断
EDIS;
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
LoopCount++;
// Uncomment ServiceDog to just loop here
// Comment ServiceDog to take the WAKEINT instead
ServiceDog(); //“喂狗”程序,在中断(溢出)之前清零看门狗计数器
}
}
// Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:
// If local ISRs are used, reassign vector addresses in vector table as
// shown in Step 5
interrupt void wakeint_isr(void)
{
WakeCount++; //正是因为有“喂狗”程序,所以中断程序应该不会被执行
// Acknowledge this interrupt to get more from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//===========================================================================
// No more.
//===========================================================================

上面编程讲解完之后,下面开始仿真。(具体加载项目请看【第七讲】创建工程那节)

由于这里有“喂狗”程序,会定时清零看门狗计数器,因此不会发出中断信号,中断子程序也不会被执行。我们这里监视变量LoopCount和WakeLoop,正确的现象应该是LoopCount不断自加,WakeCount始终是0.

运行后:

第二次运行:

好啦,本讲结束~


 

来自为知笔记(Wiz)

猜你喜欢

转载自blog.csdn.net/qq_36171263/article/details/89599765