|
//* file name: CANinit.c // 本文件是用于初始化 CAN 模块
#include "DSP281x_Device.h"
void DisableDog(void) { EALLOW; SysCtrlRegs.WDCR= 0x0068;//禁止看门狗,并使看门狗时钟为晶振时钟的1/512。 /*--------------------------------------------------------------------------------- WDCR:Watchdog control register bit definitions bit 15-8 00000000: reserved bit 7 0: WDFLAG---看门狗复位状态标志位,如果该位置1,表示 看门狗复位满足了条件;如果等于0,表示是上电 复位条件或外部器件复位条件;写1可以将该位清零 bit 6 1: WDDIS----写1,屏蔽看门狗;写0,使能看门狗。只有当SCSR2的 WDOVERRIDE位等于1时,才能改变WDDIS的值, 器件复位后看门狗模块被使能 bit 5-3 101: WDCHK----WDCHK必须写101,写其他值都会引起器件内核复位 bit 2-0 000: WDPS-----配置看门狗计数时钟(WDCLK)相对于OSCCLK/512的倍率 000-WDCLK=OSCCLK/512/1 001- WDCLK=OSCCLK/512/1 010-WDCLK=OSCCLK/512/2 011- WDCLK=OSCCLK/512/4 100-WDCLK=OSCCLK/512/8 101- WDCLK=OSCCLK/512/16 110-WDCLK=OSCCLK/512/32 111- WDCLK=OSCCLK/512/64 ----------------------------------------------------------------------------------*/ EDIS; }
//-------------------------------------------------------------------------- // Example: InitPeripheralClocks: //--------------------------------------------------------------------------- // This function initializes the clocks to the peripheral modules. // First the high and low clock prescalers are set // Second the clocks are enabled to each peripheral. // To reduce power, leave clocks to unused peripherals disabled // Note: If a peripherals clock is not enabled then you cannot // read or write to the registers for that peripheral
void InitPeripheralClocks(void) { EALLOW; // HISPCP/LOSPCP prescale register settings, normally it will be set to default values SysCtrlRegs.HISPCP.all = 0x0001; //配置高速外设时钟相对于SYSCLKOUT的1/2 /*------------------------------------------------------------------------- HISPCP:高速外设时钟寄存器,配置高速外设时钟相对于SYSCLKOUT的倍频系数 bit 15-3: reserved bit 2-0: 000-高速时钟=SYSCLKOUT/1 001-高速时钟=SYSCLKOUT/2(复位时默认) 010-高速时钟=SYSCLKOUT/4 011-高速时钟=SYSCLKOUT/6 100-高速时钟=SYSCLKOUT/8 101-高速时钟=SYSCLKOUT/10 110-高速时钟=SYSCLKOUT/12 111-高速时钟=SYSCLKOUT/14 ---------------------------------------------------------------------------*/ SysCtrlRegs.LOSPCP.all = 0x0002; /*------------------------------------------------------------------------- LOSPCP:低速外设时钟寄存器,配置低速外设时钟相对于SYSCLKOUT的倍频系数 bit 15-3: reserved bit 2-0: 000-低速时钟=SYSCLKOUT/1 001-低速时钟=SYSCLKOUT/2(复位时默认) 010-低速时钟=SYSCLKOUT/4 011-低速时钟=SYSCLKOUT/6 100-低速时钟=SYSCLKOUT/8 101-低速时钟=SYSCLKOUT/10 110-低速时钟=SYSCLKOUT/12 111-低速时钟=SYSCLKOUT/14 ---------------------------------------------------------------------------*/ // Peripheral clock enables set for the selected peripherals. SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; //使能EV-A外设内部的高速时钟。对于低功耗模式,可以通过软件或者复位清零 SysCtrlRegs.PCLKCR.bit.EVBENCLK=1; //使能EV-B外设内部的高速时钟? SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1; //使能SCI-A外设内部的低速时钟? SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1; //使能SCI-B外设内部的低速时钟? SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=1;//使能McBSP外设内部的低速时钟? SysCtrlRegs.PCLKCR.bit.SPIENCLK=1; //使能SPI外设内部的低速时钟? SysCtrlRegs.PCLKCR.bit.ECANENCLK=1; //使能CAN总线的系统时钟? SysCtrlRegs.PCLKCR.bit.ADCENCLK=1; //使能ADC外设内部的高速时钟? EDIS; }
//--------------------------------------------------------------------------- // Example: InitPll: //--------------------------------------------------------------------------- // This function initializes the PLLCR register.
void InitPll(Uint16 val) { volatile Uint16 iVol; if (SysCtrlRegs.PLLCR.bit.DIV != val) { EALLOW; SysCtrlRegs.PLLCR.bit.DIV = val; /*DIV是PLLCR的3-0bit。 DIV=0000,CLKIN=OSCCLK/2; DIV=0001,CLKIN=(OSCCLK*1.0)/2; DIV=0010,CLKIN=(OSCCLK*2.0)/2; DIV=0011,CLKIN=(OSCCLK*3.0)/2; DIV=0100,CLKIN=(OSCCLK*4.0)/2; DIV=0101,CLKIN=(OSCCLK*5.0)/2; DIV=0110,CLKIN=(OSCCLK*6.0)/2; DIV=0111,CLKIN=(OSCCLK*7.0)/2; DIV=1000,CLKIN=(OSCCLK*8.0)/2; DIV=1001,CLKIN=(OSCCLK*9.0)/2; DIV=1010,CLKIN=(OSCCLK*10.0)/2; DIV=1011,1100,1101,1110,1111,保留 -----------------------------------------------------------------*/ 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 switch time is 131072 CLKIN cycles as of Rev C silicon. // // 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. // If this function is run from waitstated memory, then the loop count can // be reduced as long as the minimum switch time is still met.
// iVol is volatile so the compiler will not optimize this loop out // // The watchdog should be disabled before this loop, or fed within // the loop. DisableDog(); // Wait lock cycles. // Note, This loop is tuned to 0-waitstate RAM memory. If this // function is run from wait-stated memory such as Flash or XINTF, // then the number of times through the loop can be reduced // accordingly. for(iVol= 0; iVol< ( (131072/2)/12 ); iVol++) { } } }
void InitEcan(void) { long i; struct ECAN_REGS ECanaShadow; asm(" EALLOW"); DisableDog();//屏蔽看门狗 InitPeripheralClocks();//初始化外设时钟 InitPll(0xA);//设置锁相环的倍频系数 for(i=0;i<100000;i++) { asm(" NOP"); } // For this example, configure CAN pins using GPIO regs here EALLOW; GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1; EDIS;
// 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 DSP281x_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 DSP281x_DefaultIsr.c. // This function is found in DSP281x_PieVect.c. InitPieVectTable();
// Step 4. Initialize all the Device Peripherals: // This function is found in DSP281x_InitPeripherals.c // InitPeripherals(); // Not required for this example
// Configure the eCAN RX and TX pins for eCAN transmissions EALLOW; ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all; ECanaShadow.CANTIOC.bit.TXFUNC = 1; ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all; ECanaShadow.CANRIOC.bit.RXFUNC = 1; ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all; EDIS; EALLOW; ECanaRegs.CANMIM.all=0xFFFFFFFF; // Request permission to change the configuration registers ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.CCR = 1; ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; EDIS; // Wait until the CPU has been granted permission to change the // configuration registers // Wait for CCE bit to be set.. do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 1 ); // Configure the eCAN timing EALLOW; ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all;
ECanaShadow.CANBTC.bit.BRPREG = 9; // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock ECanaShadow.CANBTC.bit.TSEG2REG = 5 ; // to the CAN module. (150 / 10 = 15) ECanaShadow.CANBTC.bit.TSEG1REG = 7; // Bit time = 15 ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.CCR = 0; ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; EDIS;
// Wait until the CPU no longer has permission to change the // configuration registers do { ECanaShadow.CANES.all = ECanaRegs.CANES.all; } while(ECanaShadow.CANES.bit.CCE != 0 );
// Configure the eCAN for self test mode // Enable the enhanced features of the eCAN. EALLOW; ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; ECanaShadow.CANMC.bit.STM = 0; // Configure CAN for self-test mode ECanaShadow.CANMC.bit.SCB = 1; // eCAN mode (reqd to access 32 mailboxes) ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; EDIS; // Disable all Mailboxes // Since this write is to the entire register (instead of a bit // field) a shadow register is not required. ECanaRegs.CANME.all = 0;
}
================================================================
================================================================
//FILE NAME:TXLOOP1.C // 用于发送邮箱信息 /*============================================*/
#include "DSP281x_Device.h" #define TXCOUNT 10000
long loopcount=0;
void InitEcan(void);
void main() { struct ECAN_REGS ECanaShadow; long i=0; InitEcan(); ECanaShadow.CANTRR.all=ECanaRegs.CANTRR.all; ECanaShadow.CANTRR.bit.TRR5=1; ECanaRegs.CANTRR.all=ECanaShadow.CANTRR.all; do { ECanaShadow.CANTRS.all=ECanaRegs.CANTRS.all; }while(ECanaShadow.CANTRS.bit.TRS5==1); ECanaShadow.CANME.all=ECanaRegs.CANME.all; ECanaShadow.CANME.bit.ME5=0; ECanaRegs.CANME.all=ECanaShadow.CANME.all; ECanaMboxes.MBOX5.MSGCTRL.bit.RTR=0; ECanaMboxes.MBOX5.MSGCTRL.bit.DLC=8; ECanaMboxes.MBOX5.MSGID.all=0x00140000; ECanaShadow.CANMD.all=ECanaRegs.CANMD.all; ECanaShadow.CANMD.bit.MD5=0; ECanaRegs.CANMD.all=ECanaShadow.CANMD.all; ECanaShadow.CANME.all=ECanaRegs.CANME.all; ECanaShadow.CANME.bit.ME5=1; ECanaRegs.CANME.all=ECanaShadow.CANME.all; ECanaMboxes.MBOX5.MDL.all=0x01234567; ECanaMboxes.MBOX5.MDH.all=0x89ABCDEF; //for(i=0;i<TXCOUNT;i++) while(1) { ECanaShadow.CANTRS.all=ECanaRegs.CANTRS.all; ECanaShadow.CANTRS.all=0; ECanaShadow.CANTRS.bit.TRS5=1; ECanaRegs.CANTRS.all=ECanaShadow.CANTRS.all; do { ECanaShadow.CANTA.all=ECanaRegs.CANTA.all; }while(ECanaShadow.CANTA.bit.TA5!=1); ECanaShadow.CANTA.bit.TA5=1; ECanaRegs.CANTA.all=ECanaShadow.CANTA.all; loopcount++; } }
|