⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 the_dsp28_header_files.txt

📁 这是DSP F2812芯片的头文件
💻 TXT
📖 第 1 页 / 共 2 页
字号:
CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1
CpuTimer1RegsFile : > CPU_TIMER1, PAGE = 1
CpuTimer2RegsFile : > CPU_TIMER2, PAGE = 1
……
}
The required memory allocations and section assignments are shown in the EzDSP_RAM_lnk.cmd linker
command file.
5. Include .c files for the PIE. If you are going to use the PIE block, you will probably want to include the PIE
support .c files to help with initializing the PIE. The shell ISR functions can be used directly or you can remap
your own function into the PIE vector table provided.
6. If you want to use the example .c files, then include them in your project as well.
7. Follow the steps outlined in the DSP28_Example.c file for initializing peripherals and the PIE block.
Accessing Peripheral Registers
As described earlier, the peripheral register structure defined in the .h files for each peripheral will be linked into
memory at the address where those registers are located. Therefore the variables can be used to access the
registers directly via c-code. This section describes how this works in greater detail.
Taking a closer look at the CPU Timer example. Recall the variables defined are of the type
struct CPUTIMER_REGS.
volatile struct CPUTIMER_REGS CpuTimer0Regs;
volatile struct CPUTIMER_REGS CpuTimer1Regs;
volatile struct CPUTIMER_REGS CpuTimer2Regs;
Lets take a closer look at what this structure looks like. It can be found in the DSP28_CpuTimers.h file:
//----------------------------------------------------
// CPU Timer Register File:
//
struct CPUTIMER_REGS {
union TIM_GROUP TIM; // Timer counter register
union PRD_GROUP PRD; // Period register
union TCR_REG TCR; // Timer control register
Uint16 rsvd1; // reserved
union TPR_REG TPR; // Timer pre-scale low
union TPRH_REG TPRH; // Timer pre-scale high
};
Notice:
‰ The register names within the structure are in the same order as the registers are arranged in
memory. You can observe this by comparing the CPU Timer registers shown in the datasheet to the
above structure.
‰ Locations that are reserved in memory are held within the structure by a reserved variable (rsvd1,
rsvd2, rsvd3 etc). These locations are not used other then to hold the space.
‰ Uint16 is a typedef for an unsigned 16-bit value or, in the case of the ‘28x, an unsigned int. This is
done for portability and the typedef statement can be found in the DSP28_Device.h file.
‰ Registers that are often accessed more then one way (ie by bit, or 16-bits or 32-bits) are defined
using unions. Note: Some registers do not have unions defined since it does not make sense to
access them as bit fields.
Consider an example using the CPU Timer control register. First, all the bits within the register are
defined using a bit field structure as defined in the DSP28_CpuTimer.h file and shown:
struct TCR_BITS { // bits description
Uint16 OUTSTS:1; // 0 Current state of TOUT
Uint16 FORCE:1; // 1 Force TOUT
Uint16 POL:1; // 2 Output polarity
Uint16 TOG:1; // 3 Output toggle mode
Uint16 TSS:1; // 4 Timer Start/Stop
Uint16 TRB:1; // 5 Timer reload
Uint16 FRCEN:1; // 6 Force enable
Uint16 PWIDTH:3; // 9:7 BitTOUT output pulse width
Uint16 SOFT:1; // 10 Emulation modes
Uint16 FREE:1; // 11
Uint16 rsvd:2; // 12:13 reserved
Uint16 TIE:1; // 14 Output enable
Uint16 TIF:1; // 15 Interrupt flag
};
This bit field definition allows the user to identify any bit within the register. But the user may have a
reason to access more then one bit at a time or the whole register at once. To accomplish this, a
union is used to define the register more then one way. For example:
union TCR_REG {
Uint16 all;
struct TCR_BITS bit;
};
Notice that this union was included in the CPUTIMER_REGS definition. Now the user can
access the bit fields by using the .bit element or the whole register by using the .all element. When
accessing bit fields in this manner, a decimal number should be used. For example:
Start CPU-Timer 0:
// CPU Timer0 clear the TSS bit in the TCR register
CpuTimer0Regs.TCR.bit.TSS = 0;
Stop CPU-Timer 1:
// CPU Timer1: Set the TSS bit in the TCR register
CpuTimer1Regs.TCR.bit.TSS = 1;
Reload CPU-Timer 2 Period:
// CPU Timer2: Set the TRB bit in the TCR register
CpuTimer2Regs.TCR.bit.TRB = 1;
When using Code Composer Studio, the editor will prompt you with a list of possible structure/bit field
elements as you type. This auto completion feature makes it easier to code without having to refer to
documentation for the register and bit field names.
If you make a number of accesses to one register using the .bit field, it may result in more code then
using .all to write to the register all at once. For example:
CpuTimer0Regs.TCR.bit.POL = 0; // 0 = Pulse Low
CpuTimer0Regs.TCR.bit.TOG = 0; // 0 = No Toggle
CpuTimer0Regs.TCR.bit.TSS = 1; // 1 = Stop timer
CpuTimer0Regs.TCR.bit.TRB = 1; // 1 = reload timer
CpuTimer0Regs.TCR.bit.FRCEN = 0; // Force output enable (not used)
CpuTimer0Regs.TCR.bit.PWIDTH = 7; // 7+1 = 8 SYSCLKOUT pulse width
CpuTimer0Regs.TCR.bit.SOFT = 1;
CpuTimer2Regs.TCR.bit.FREE = 1; // Timer Free Run
CpuTimer2Regs.TCR.bit.TIE = 1; // 1 = Enable Timer Interrupt
Results in very readable code that is very easy to modify. The penalty is slight code overhead. If
code size is more of a concern then use the .all directive to write to the register all at once.
CpuTimer0Regs.TCR.all = 0x1234
Note: Most of the example code included uses the .bit field structures to access registers. This is
done to help the user learn how to use the device. Using the bit fields will result in a slight code
overhead but makes the examples more readable and easy to change. In addition, for these
examples the compiler optimizer has not been turned on.
Troubleshooting Tips
‰ EALLOW Protection: The EALLOW bit protects some registers from spurious writes by the CPU. If your
program seems unable to write to a register, then check to see if it is EALLOW protected. If it is, then enable
access using the EALLOW instruction. For example:
void WatchDogDisable()
{
EALLOW; // Allow access
SysCtrlRegs.WDCR = 0x0068; // Disable watchdog module
EDIS; // Disallow access
}
‰ The eCAN control registers require 32-bit write accesses. The compiler will instead make a 16-bit write
accesses if it can in order to improve codesize and/or performance. This can result in unpredictable results.
One method to avoid this is to create a duplicate copy of the eCAN control registers in RAM. Use this copy
as a shadow register. First copy the contents of the eCAN register you want to modify into the shadow
register. Make the changes to the shadow register and then write the data back as a 32-bit value.
For example:
volatile struct ECAN_REGS ECanaRegs; // eCAN Control
struct ECAN_REGS ShadowEcana; // Shadow Registers
ShadowEcana.CANME = ECanaRegs.CANME; // Copy to the shadow registers
ShadowEcana.CANME.ME13 = 1; // Set the desired bit
ECanaRegs.CANME = ShadowEcana.CANME; // Write the 32-bit value back
‰ Effects of read-modify-write instructions. When writing any code, whether it be C or assembly, keep in
mind the effects of read-modify-write instructions.
The ‘28x DSP will write to registers or memory locations 16 or 32-bits at a time. Any instruction that seems to
write to a single bit is actually reading the register, modifying the single bit, and then writing back the results.
This is referred to as a read-modify-write instruction. For most registers this operation does not pose a
problem. A notable exception is:
Registers with multiple flag bits in which writing a 1 clears that flag.
For example, consider the PIEACK register. Bits within this register are cleared when writing a 1 to that bit. If
more then one bit is set, performing a read-modify-write on the register may clear more bits then intended.
Incorrect, this solution will write a 1 to any bit set and thus clear all of them:
PieCtrl.PIEAck.bit.Ack1 = 1; // May clear more bits!!!
A better solution is to instead write a mask value to the register in which only the intended bit will have a 1
written to it:
CORRECT: #define PIEACK_GROUP1 0x0001
……
PieCtrl.PIEACK.all = PIEACK_GROUP1;
Registers with Volatile Bits.
Some registers have volatile bits that can be set by external hardware.
Consider the PIEIFRx registers. An atomic read-modify-write instruction will read the 16-bit register, modify
the value and then write it back. During the modify portion of the operation a bit in the PIEIFRx register could
change due to an external hardware event and thus the value may get corrupted during the write.
The rule for registers of this nature is to never modify them during runtime. Let the CPU take the interrupt and
clear the IFR flag.
Variable Names and Data Sections
This section is a summary of the variable names used and data sections allocated by the
DSP28_GlobalVariableDefs.c file.
If you want to use these definitions in your c files then include DSP28_GlobalVariableDefs.c in your
project as well.
#pragma DATA_SECTION(SysCtrlRegs,"SysCtrlRegsFile");
volatile struct SYS_CTRL_REGS SysCtrlRegs; // System Control
#pragma DATA_SECTION(CsmRegs,"CsmRegsFile");
volatile struct CSM_REGS CsmRegs; // Code Security Module
#pragma DATA_SECTION(CsmPwl,"CsmPwlFile");
volatile struct CSM_PWL CsmPwl; // CSM password locations
#pragma DATA_SECTION(FlashRegs,"FlashRegsFile");
volatile struct FLASH_REGS FlashRegs; // Flash registers
#pragma DATA_SECTION(CpuTimer0Regs,"CpuTimer0RegsFile");
volatile struct CPUTIMER_REGS CpuTimer0Regs; // CPU Timer 0
#pragma DATA_SECTION(CpuTimer1Regs,"CpuTimer1RegsFile");
volatile struct CPUTIMER_REGS CpuTimer1Regs; // CPU Timer 1
#pragma DATA_SECTION(CpuTimer2Regs,"CpuTimer2RegsFile");
volatile struct CPUTIMER_REGS CpuTimer2Regs; // CPU Timer 2
#pragma DATA_SECTION(GpioDataRegs,"GpioDataRegs");
volatile struct GPIO_DATA_REGS GpioDataRegs; // GP I/O Data
#pragma DATA_SECTION(GpioMuxRegs,"GpioMuxRegs");
volatile struct GPIO_MUX_REGS GpioMuxRegs; // GP I/O Mux
#pragma DATA_SECTION(ECanaRegs,"ECanaRegsFile");
volatile struct ECAN_REGS ECanaRegs; // eCAN Control
#pragma DATA_SECTION(ECanaMboxes,"ECanaMboxesFile");
volatile struct ECAN_MBOXES ECanaMboxes; // eCAN Mailboxes
#pragma DATA_SECTION(McbspaRegs,"McbspaRegsFile");
volatile struct MCBSP_REGS McbspaRegs; // McBSP
#pragma DATA_SECTION(SpiaRegs,"SpiaRegsFile");
volatile struct SPI_REGS SpiaRegs; // SPI-A
#pragma DATA_SECTION(SciaRegs,"SciaRegsFile");
volatile struct SCIA_REGS SciaRegs; // SCI-A
#pragma DATA_SECTION(EvaRegs,"EvaRegsFile");
volatile struct EVA_REGS EvaRegs; // Event Manager A
#pragma DATA_SECTION(EvbRegs,"EvbRegsFile");
volatile struct EVB_REGS EvbRegs; // Event Manager B
#pragma DATA_SECTION(XintfRegs,"XintfRegsFile");
volatile struct XINTF_REGS XintfRegs; // External Interface
#pragma DATA_SECTION(AdcRegs,"AdcRegsFile");
volatile struct ADC_REGS AdcRegs; // ADC
#pragma DATA_SECTION(XIntruptRegs,"XIntruptRegsFile");
volatile struct XINTRUPT_REGS XIntruptRegs; // External Interrupts
#pragma DATA_SECTION(PieCtrlRegs,"PieCtrlRegsFile");
volatile struct PIE_CTRL_REGS PieCtrlRegs; // PIE Control Registers
#pragma DATA_SECTION(PieVectTable,"PieVectTable");
struct PIE_VECT_TABLE PieVectTable; // PIE Vector Table
DSP28_Device.h - Main Include File
This file can be included in all other .c files. By doing so, all of the other peripheral and interrupt definitions will be
included in the project.
This DSP28_Device.h includes:
‰ Common definitions for ‘28xx devices.
‰ Interrupt mask definitions.
‰ Typedef statements for common data type sizes. Use these to help keep code portable:
? typedef int int16;
? typedef long int32;
? typedef unsigned int Uint16;
? typedef unsigned long Uint32;
‰ Include statements for all provided peripheral and system .h files. These .h files include register bit
definitions for each peripheral.
? #include "DSP28_SysCtrl.h" // System Control/Power Modes
? #include "DSP28_DevEmu.h" // Device Emulation Registers
? #include "DSP28_Xintf.h" // External Interface Registers
? #include "DSP28_CpuTimers.h" // 32-bit CPU Timers
? #include "DSP28_PieCtrl.h" // PIE Control Registers
? #include "DSP28_PieVect.h" // PIE Vector Table
? #include "DSP28_DefaultIsr.h" // Software Prioritization for PIE Interrupts
? #include "DSP28_Spi.h" // SPI Registers
? #include "DSP28_Sci.h" // SCI Registers
? #include "DSP28_Mcbsp.h" // McBSP Registers
? #include "DSP28_ECan.h" // Enhanced eCAN Registers
? #include "DSP28_Gpio.h" // General Purpose I/O Registers
‰ Assembly inline statements for common operations such as enable/disable global interrupts
? extern cregister volatile unsigned int IFR;
? extern cregister volatile unsigned int IER;
? #define EINT asm(" clrc INTM")
? #define DINT asm(" setc INTM")
? #define ERTM asm(" clrc DBGM")
? #define DRTM asm(" setc DBGM")
? #define EALLOW asm(" EALLOW")
? #define EDIS asm(" EDIS")
? #define ESTOP0 asm(" ESTOP0") 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -