| 
 
| C28X CPU的DSP开发C语言要点 
 
 一般的单片机开发过程或者ARM9等裸机开发的C语言对寄存器的定义规则如下,这样子如果我们要读写寄存器的某一位则需要进行麻烦的与(或)操作:
 
 #define Uint16 unsigned int
 #define Uint32 unsigned long
 // Memory Map
 // Addr Register
 #define SCICCRA (volatile Uint16 *)0x7050 // 0x7050 SCI-A Communications Control
 #define SCICTL1A (volatile Uint16 *)0x7051 // 0x7051 SCI-A Control Register 1
 #define SCIHBAUDA (volatile Uint16 *)0x7052 // 0x7052 SCI-A Baud Register, High Bits
 #define SCILBAUDA (volatile Uint16 *)0x7053 // 0x7053 SCI-A Baud Register, Low Bits
 #define SCICTL2A (volatile Uint16 *)0x7054 // 0x7054 SCI-A Control Register 2
 #define SCIRXSTA (volatile Uint16 *)0x7055 // 0x7055 SCI-A Receive Status
 #define SCIRXEMUA (volatile Uint16 *)0x7056 // 0x7056 SCI-A Receive Emulation Data Buffer
 #define SCIRXBUFA (volatile Uint16 *)0x7057 // 0x7057 SCI-A Receive Data Buffer
 #define SCITXBUFA (volatile Uint16 *)0x7059 // 0x7059 SCI-A Transmit Data Buffer
 #define SCIFFTXA (volatile Uint16 *)0x705A // 0x705A SCI-A FIFO Transmit
 #define SCIFFRXA (volatile Uint16 *)0x705B // 0x705B SCI-A FIFO Receive
 #define SCIFFCTA (volatile Uint16 *)0x705C // 0x705C SCI-A FIFO Control
 #define SCIPRIA (volatile Uint16 *)0x705F // 0x705F SCI-A Priority Control
 #define SCICCRB (volatile Uint16 *)0x7750 // 0x7750 SCI-B Communications Control
 #define SCICTL1B (volatile Uint16 *)0x7751 // 0x7751 SCI-B Control Register 1
 #define SCIHBAUDB (volatile Uint16 *)0x7752 // 0x7752 SCI-B Baud Register, High Bits
 #define SCILBAUDB (volatile Uint16 *)0x7753 // 0x7753 SCI-B Baud Register, Low Bits
 #define SCICTL2B (volatile Uint16 *)0x7754 // 0x7754 SCI-B Control Register 2
 #define SCIRXSTB (volatile Uint16 *)0x7755 // 0x7755 SCI-B Receive Status
 #define SCIRXEMUB (volatile Uint16 *)0x7756 // 0x7756 SCI-B Receive Emulation Data Buffer
 #define SCIRXBUFB (volatile Uint16 *)0x7757 // 0x7757 SCI-B Receive Data Buffer
 #define SCITXBUFB (volatile Uint16 *)0x7759 // 0x7759 SCI-B Transmit Data Buffer
 #define SCIFFTXB (volatile Uint16 *)0x775A // 0x775A SCI-B FIFO Transmit
 #define SCIFFRXB (volatile Uint16 *)0x775B // 0x775B SCI-B FIFO Receive
 #define SCIFFCTB (volatile Uint16 *)0x775C // 0x775C SCI-B FIFO Control
 #define SCIPRIB (volatile Uint16 *)0x775F // 0x775F SCI-B Priority Control
 
 而TI的DSP则采取了比较少见的位域式结构体的定义,如下:
 
 struct SCI_REGS {
 union SCICCR_REG SCICCR; // Communications control register
 union SCICTL1_REG SCICTL1; // Control register 1
 Uint16 SCIHBAUD; // Baud rate (high) register
 Uint16 SCILBAUD; // Baud rate (low) register
 union SCICTL2_REG SCICTL2; // Control register 2
 union SCIRXST_REG SCIRXST; // Receive status register
 Uint16 SCIRXEMU; // Receive emulation buffer register
 union SCIRXBUF_REG SCIRXBUF; // Receive data buffer
 Uint16 rsvd1; // reserved
 Uint16 SCITXBUF; // Transmit data buffer
 union SCIFFTX_REG SCIFFTX; // FIFO transmit register
 union SCIFFRX_REG SCIFFRX; // FIFO receive register
 union SCIFFCT_REG SCIFFCT; // FIFO control register
 Uint16 rsvd2; // reserved
 Uint16 rsvd3; // reserved
 union SCIPRI_REG SCIPRI; // FIFO Priority control
 };
 
 这样子我们就可以通过如下的方式直接操作寄存器的单个位:
 
 SciaRegs.SCICTL1.bit.SWRESET = 0;
 SciaRegs.SCICTL1.bit.SWRESET = 1;
 SciaRegs.SCIFFCT.bit.ABDCLR = 1;
 SciaRegs.SCIFFCT.bit.CDC = 1;
 
 但是需要注意,这样子虽然方便了我们对寄存器单个位的操作,但是这样子却又增加了CPU的负担,因为最终CPU对单个位操作都需要占用一个机器周期,这样子如果我们要对一组寄存器的多个位操作的话会导致CPU多做了很多无用功。于是可以采取影子寄存器的方式来操作寄存器CPU,如下所示:
 
 
 union PCLKCR0_REG shadowPCLKCR0;
 EALLOW; 3F82A7 EALLOW
 shadowPCLKCR0.bit.rsvd1 = 0; 3F82A8 MOV @AL,#0x47D8
 shadowPCLKCR0.bit.TBCLKSYNC = 0; 3F82AA MOVW DP,#0x01C0
 shadowPCLKCR0.bit.ADCENCLK = 1; // ADC 3F82AC MOV @28,AL
 shadowPCLKCR0.bit.I2CAENCLK = 1; // I2C 3F82AD EDIS
 shadowPCLKCR0.bit.rsvd2 = 0;
 shadowPCLKCR0.bit.SPICENCLK = 1; // SPI-C
 shadowPCLKCR0.bit.SPIDENCLK = 1; // SPI-D
 shadowPCLKCR0.bit.SPIAENCLK = 1; // SPI-A
 shadowPCLKCR0.bit.SPIBENCLK = 1; // SPI-B
 shadowPCLKCR0.bit.SCIAENCLK = 1; // SCI-A
 shadowPCLKCR0.bit.SCIBENCLK = 0; // SCI-B
 shadowPCLKCR0.bit.rsvd3 = 0;
 shadowPCLKCR0.bit.ECANAENCLK= 1; // eCAN-A
 shadowPCLKCR0.bit.ECANBENCLK= 0; // eCAN-B
 SysCtrlRegs.PCLKCR0.all = shadowPCLKCR0.all;
 
 EDIS;
 
 
 这样子经过编译器优化后,我们编程时可以对单个位进行操作,而经过编译器优化后CPU的执行命令和直接都整个寄存器进行与(或)操作是一样的效果。
 
 | 
 |