- 本课程为精品课,您可以登录eeworld继续观看:
- (4) - 外设寄存器操作
- 登录
- 课程目录
- 课程笔记
大家好
本章节我们将要讨论的是外设寄存器的头文件
我们先会了解F2837xD寄存器
C代码头文件的使用
并且学会怎样去编程这些外设的寄存器
然后知道寄存器结构体
是如何以 Linker.cmd 进行映射的
首先我们看一个传统的底层驱动的C代码示例
在这个例子里
我们是通过宏定义的方式
将一个地址强制指针类型转化
将它赋给一个标号或者说寄存器的名字
然后在代码里就可以对该地址直接进行操作
比如赋一个值
或者仅对其内容的某一个位
进行某个逻辑运算等等
这个方法的优点其实是非常明显的 简单粗暴
然而它的缺点也一样明显
那就是当仅需要操作某一个位的时候
用户需要去设定一个独立的 mask
仅对该位进行处理
而且逻辑或和逻辑与需要两个不同的 mask
同时在调试的时候
不能很容易地在窗口里看到某些位的状态
最重要的一点是在很多的情况下
它编译生成的代码会比较累赘 效率很低
从而影响代码的执行时间
另一种办法是使用结构体的方式进行编程
如这个示例
将同一个外设的所有寄存器定义在一个结构体里
然后在一个寄存器里定义一个联合体
分别对应它的全部和某些位
以支持不同类型需要的操作
在生成代码的寻址方面
由于将统一外设的寄存器放在一起
而且物理上也确实是相连的
就可以只需要找到第一个寄存器的地址
然后通过 offset 偏移量的方式快速定位
从而提高效率
当然它的优缺点也非常明显
可以很容易的操作某个位
然后可以在调试窗口看到
最重要是可以生成更高效的代码
但是由于结构体本身和寄存器名比较长
不易记住且不易介入
从而会影响开发效率
下面我们先来看看细节的几个点
这是调试窗口可以看到的位的值可能发生的变化
而如果使用explorer功能介入
或者拷贝结构体名
然后展开加号
就可以看到所有的位置和整个寄存器的值
那么代码是否会真的更高效呢
我们可以通过一个例子生成的汇编代码
来比较看一看
这个例子要做的事情是先停止定时器
然后 load 一个新的周期到PRD
再重新开启定时器
可以看到生成的汇编代码里
首先有一个DP配置的赋值
查找到该定时器所在组的寄存器起始地址
然后对其偏移地址为4的元素
也就是 XAR4 寄存器进行一个逻辑或运算
实现停止定时器的功能
然后直接赋值周期值
到cpu寄存器 XAR4
再由他赋给偏移地址为二的元素
也就是PRD寄存器
最后重新开启定时器
直接继续逻辑与运算
操作偏移地址为四的元素 TCR 寄存器
总计用时为五条指令
代码量为 5 word 通用指令数可以计算为
n*2-m+1
m 是逻辑运算的个数
如果使用传统的 define 的方式
完成相同任务的C代码对应的汇编代码
又是怎样的呢
可以看到生成的汇编代码里
每个操作都是先取址
然后对其地址内的内容进行逻辑运算
或者赋值运算
最后再把值重新写到该地址
三条指令完成一个动作
对应三个动作就是九条指令
所以代码量为九个 word
而实际的通用指令数是 n*3
远远大于前面的方法
所以无论是从代码空间还是执行效率来看
结构体操作的方式都应该是最优的
使用结构体的方式进行编程
并不需要每个用户
自己去编写底层代码的头文件定义
因为TI已经做好了相应的工作
用户直接加入到应用程序中使用就可以了
TI提供的外设寄存器头文件结构体
有完整的命名规则
便于记忆和使用
简单来说就是结构体的名字就是外设名字
采取每个单词首字母大写
其它字母小写的方式
并由TI来定义
而寄存器名就是该外设的对应的寄存器的名字
与用户手册上的完全匹配
同样采取大小写规则
然后是位选择或者是全寄存器选择
由小写字母or或是bit决定
最后是选择为位的时候
位域名与用户手册上的位定义完全匹配
采取同样的大小写规则
这样每个外设的头文件合在一起
就组成了整个 F2837xD 芯片的
所有外设头文件
接下来这页我们将看到的是自动完成功能
它主要针对的是寄存器名太长
不易记忆和不易介入的问题
通过光标移动选择对应的寄存器
和位以及位域名就可以快速完成介入工作
这里是使用外设寄存器的头文件的例子
所有的外设寄存器的头文件
TI 已经打包并放在一起
对应在 F2837xD_headers\include 文件夹下
除此之外它还包含之前提到过的
Linker.cmd file 的应用例程
外设使用的基本程序和相关使用说明文档
统一封装并放置在 controlsuite 之下
用户可以下载并安装后
在以下的路径中查找到
C\TI\controlsuite\device support
这里是使用外设寄存器的头文件的例子
要使用哪一个外设
用户需要包含对应外设的头文件
由于外设众多
TI 已经将所有外设的头文件编写好
并且由另外一个总的头文件 F2837xD_Device.h
对他们进行了包含
因此用户在实际使用过程中
只需要在使用到任意外设的原文件中
包含 F2837xD_Device.h 即可
那其实仅仅是包含头文件还是不够
因为对于编译器来说
这些外设寄存器所在的结构体
始终还是个变量
那么就还需要像上一章节提到的那样
将这些变量映射到实际的物理内存上去
否则就是虚无缥缈不可操作的东西
好在TI也已经完成了这一部分的工作
用户只需要添加一个点C源文件
F2837xD_GlobalVariableDefs.c 和一个.cmd文件
F2837xD_nonBIOS.cmd
或者 F2837xD_BIOS.cmd 即可
前者是使用 pragma DATA_SECTION 预编译的方式
将所有寄存器结构体变量
指定到各自的一个标号
后者会将该标号一一对应的映射到
这些寄存器本身所在的芯片的物理地址上
完成了最后的连接
这样在编译的时候
整个过程就可以顺利的完成
最后我们看一下
除了外设寄存器的头文件之外
TI 还提供了每个外设的使用实例
既可以用来参考做底层驱动的设计
也可以作为标准来验证外设本身是否存在问题
最后我们总结一下
本章节我们讲解了
两种不同风格的底层驱动的编程
并分析了它们各自的优缺点
以及我们为什么使用结构体的方式
然后这些工作都已经由 TI 完成
用户需要怎样去配置和使用
接下来我们会开始涉及芯片本身
从系统到外设
下一章节将是复位和中断作为开始
课程介绍
共计28课时,4小时27分22秒
C2837x入门指南
TI C2000 MCU PWM F2837xD ADC DAC DMA CLA C2837x CMP SDFM CAP QEP c28x
F2837x系列的最新 C2000™ Delfino™ 32 位 F2837xD 微控制器 (MCU),为工业实时控制实现最新创新,并设定了全新性能标准。这些最新 MCU 支持双核 C28x 处理功能与双实时控制加速器(也称为控制律加速器或 CLA),可提供 800 MIPS 浮点性能,从而可帮助设计人员为计算要求严格的控制应用开发低时延系统。此外,设计人员还可通过将多个嵌入式处理器整合在单个 MCU 中以降低复杂性,充分满足高级伺服驱动器、太阳能中央逆变器以及工业不间断电源 (UPS) 等需要实时信号分析的应用需求。
猜你喜欢
换一换
推荐帖子
- 一种基于Matlab的DSP调试及直接代码生成方法
- Matlab作为一种有效的信号处理工具,已经渗透到DSP的设计当中。开发者在将一个新的数字信号处理算法应用于实际前,一般是先用Matlab进行模拟验证,当模拟结果满意时再把算法修改成C或DSP汇编语言通过CCS在目标DSP上实现,并比较实际应用与模拟的结果以发现误差,如此反复进行。在较新版本的Matlab(6.0以上)中提供了Matlab与DSP的统一集成环...
-
灞波儿奔
DSP 与 ARM 处理器
- 【TI 无线主题征集】无线温度采集系统
- 一个小制作,单总线18b20的无线温度采集项目 仅占用1个IO口,采集多个温度数据 可以通过sn上线时间自行判断18B20所在位置并关联相关数据 无线部分采用TI的CC2530,蜂鸟科技出的模块 PCB画得比较cute,呵呵 基本框图: 核心器件采用的基本上都是TI的IC 传输距离500米即是采用CC2530的无线模块完成 485总线也做了相应改造,适合单总线数据传输 用VB...
-
ljj3166
无线连接
- 蓝牙协议分析_协议架构
- 1. 前言 在“蓝牙协议分析_基本概念”的基础上,从整体架构的角度,了解蓝牙协议的组成,以便加深对蓝牙的理解。 2. 协议层次 蓝牙协议是通信协议的一种,为了把复杂问题简单化,任何通信协议都具有层次性,特点如下: 从下到上分层,通过层层封装,每一层只需要关心特定的、独立的功能,易于实现和维护; 在通信实体内部,下层向上层提供服务,上层是下层的用...
-
Aguilera
无线连接
- TI CC6678数字信号处理器 (DSP) 的五种用法
- 基于KeyStone™ 的TMS320C6678,一款8内核C66x DSP特别有意思,这是因为这款器件是市面上较早的高性能多核DSP之一。虽然有超过100名客户已经在他们的产品中采用了C6678 DSP,但是我可以很肯定地说,对于定点和浮点C6678 DSP来说,至少有50种不同的使用方法!不过也别担心,我不会将这个冗长的列表直接抛给你,我只是...
-
Jacktang
DSP 与 ARM 处理器