3080|2

23

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

C28X CPU的DSP开发C语言要点 [复制链接]

本帖最后由 hmily99 于 2016-1-25 15:07 编辑

其姊妹篇:
如何将寄存器与实际地址链接起来
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=483139&fromuid=415813
(出处: 电子工程世界-论坛)

一般的单片机开发过程或者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的执行命令和直接都整个寄存器进行与(或)操作是一样的效果。

最新回复

我觉得多此一举,因为这些大多都是在初始化的配置过程才进行这类的操作。  详情 回复 发表于 2016-1-25 15:22
点赞 关注
 

回复
举报

2700

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
我觉得多此一举,因为这些大多都是在初始化的配置过程才进行这类的操作。
个人签名作为一个水军,就是尽量的多回帖,因为懂的技术少,所以回帖水分大,见谅!
EEWORLD开发板置换群:309018200,——电工们免费装β的天堂,商家勿入!加群暗号:喵
 
 

回复

23

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
elvike 发表于 2016-1-25 15:22
我觉得多此一举,因为这些大多都是在初始化的配置过程才进行这类的操作。

呵呵,这个操作不会,怎么能用好芯片?
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表