在我的
第一篇文章中,我谈到了这个控制器家族;虽然不是本文的主题,但有十几个人在PM中给我写了一些问题。 人们断然不想去谷歌,谈论的是缺乏信息。 我有些惊讶,并决定进行检查-的确,在俄语中,C2000系列几乎没有任何东西(相对于AVR,STM的背景),最重要的是没有明确的入门指南。 信息可以用英文找到,但仍然不够。 对我来说,这有点奇怪,因为这个家庭还没有几岁。 因此,决定尽其所能影响局势。
原则上谁需要这些控制器?您想组装焊接逆变器吗? 不间断电源? 电镀浴矫直机? 频率? 替代能源的逆变器? 数控机床? 如果关于您至少有一点,那么这篇文章就是为您准备的!
其他读者也将对“新旧”控制器的学习,为什么需要它以及如何使用它感兴趣。 这个系列非常简单(比STM,LPC和其他Cortex简单得多),石头易于购买(也有Ali),它们使您能够实施高度可靠的工业解决方案,在此基础上,您可以构建几乎任何工业控制系统。
您是否已经确定该控制器是您的梦想,并准备着手战斗? 然后,我们以17美元的价格购买F28027-LaunchPad的以下调试:
你买了吗 现在您可以开始战斗了。 如果问题出在哪里买“更好”和“更便宜”,那么我们去官方商店。 我们在
这里看到价格为$ 17。 为此,您将收到原始的调试费和快递到门。 我在中国订购了一次送达服务,结果却是16美元,上面有折扣和优惠券,还有一次去邮局的“优惠”旅行。 因此,我推荐它是官方的。 走吧
C2000系列概述
您可以在
官方网站上以英语详细阅读所有内容的详细信息。 我将简短地讨论它,并表达我对应用程序的想法。 请注意,这仅是我的推测,他们并不主张事实。
首先,简要介绍一下C2000。 该系列的独特功能与其主要的电动机控制目的有关,即HRPWM(高精度PWM)和CLA(协处理器)的存在。 最年轻的Piccolo TMS320F2802x确实没有后者,但是在那里并不需要它,主要是HRPWM。 这是什么... HRPWM本身是常规的PWM,它非常准确,并且新占空比的记录和设置时间明显更快。 这样就可以在DC / AC逆变器中获得完美形状的正弦波,或者以非常高的精度控制CNC机器中的步进电机。
CLA本质上是成熟的内核,但是它无权访问外围设备,而只能访问主内核和内存。 它可以减轻计算的主要核心负担。 这个协处理器非常容易并且自然地提取浮点数据,这在实现各种算法,过滤器等时非常重要。

我将谈论您可能会遇到的两个主要家庭:
- 短笛。 最年轻的控制器,但也最便宜。 我的TMS320F28027来自这个家庭。 如果您决定开发用于商业目的的电力电子产品,这些将是您的主要要点-它们非常便宜,价格合理(LQFP,QFN,TSSOP),几乎可以实现所有功能。 例如,它们的性能足以满足两相PFC,用于太阳能电池板的逆变器,具有矢量控制功能的最高10 kW的变频器等的要求。 如您所见,这是普通人和企业购买的一部分产品,这意味着它的需求量很大。 主要限制是60 MHz的频率,有限数量的PWM通道。
- 德尔菲诺 从意识形态上讲,它们都是相同的短笛,只是充了美登。 这表示的是-频率高达200 MHz,在较老的石头上已经有2个成熟的内核+ 2个协处理器,大型情况下,因此有许多支路,许多PWM通道,许多ADC以及通常很多。 也就是说,在较旧的宝石中,我们有4个核心,频率为200 MHz,性能为800 MIPS,这非常令人印象深刻。 这样的功率可以以不同的方式使用,但是主要应用是算法复杂的系统,例如,Vienne整流器或其他。 同样在一个这样的控制器上,您可以为CNC机床实现整个控制系统,例如金属的铣削或火焰切割。
完成调试板
当您收到带有调试板的包装盒时,会发现缺少的石英和电容器。 它们不是必需的,但建议进行掺杂。 我不再在HC-49中使用石英,所以我不得不向朋友借钱。 他选择了AVR和STM,因此只找到了8 MHz。 焊接。 我从旧内存中添加了22 pF电容器,就像我在学校的大型存储器中那样。
该解决方案不是最佳解决方案,它与PLL配置有关。 PLL的最大乘数为x12(可以,但不建议使用更大的倍数,并且歪曲)。 最大频率为60 MHz。 PLL输出处的分频器最大值为3。石英的频率为8 MHz。 我无法将8乘以整数得到60。我们正在寻找最接近的总值,在这种情况下为240。也就是说,将8乘以30,然后除以4得到的确是令人垂涎的60 MHz,但是麻烦的是x30 PLL乘法器是不可接受的,分频器/ 4也不可用。 有2种方法:
- 不好:将8 MHz的频率乘以7,再除以1,得到56 MHz。 您可以乘以8以获得64 MHz,它将稳定地工作,但是在两种情况下,频率都不是最大60 MHz。 perfect,完美主义还不够。 我有一个这样的选择,焊接8 MHz,频率为56 MHz。
- 好:去买10或20 MHz(好于10)的石英,再乘以6,好,再除以1,得到珍贵的60 MHz。 我住在市区外,说实话,我懒得去当地的商店逛逛,因为那里没有10 MHz的石英。 当然,内部RC电路和8 MHz石英将用于培训,但是在您将来的项目中,请使用10 MHz石英,而不是HC-49包装中的猛ma变种。
架构和外围功能
接下来将发生的所有事情都适用于TMS320F28027控制器。 首先,让我们来看一下
数据表中的结构:

首先要注意的是RAM分为3个扇区:M0,M1和SARAM。 在我们的情况下,这些存储扇区的容量为1k,1k和4k。 值得注意的是,在这种情况下,字不是8位,而是16位,也就是说,以更常见的形式,它是2 kB + 2 kB + 8 kB。 该模块的独特之处在于,扇区M0和M1比剩余的8 kB RAM快。 正式地,您可以将此作为缓存。 扇区M0和M1通常存储最常用的数据以及对内存性能最关键的数据。 默认情况下,我们可以使用链接器指定存储的内容和位置,但是在本文中我不会提出这个主题,这里至少需要另外一篇文章。
第二个重要功能是所有外围设备均从系统总线提供时钟,即从60 MHz(在我的情况下为56 MHz)开始。 举例来说,我将提供STM32微控制器,其中F4的核心频率为180 MHz,但是外围设备通过一系列分频器提供时钟。 我自己称这种方法为“假兆赫兹”,尽管这是非常夸张的。 因此,TMS320F28的60 MHz和stm32的180 MHz差别不大,如果您回想起CLA的存在,那么60 + 60 MHz至少是可比的。 显然,这样的比较是不正确的,但是很清楚地表明,不仅兆赫兹被反馈了。
还有一点很有趣-请注意以下一般结构:HRPWM,ADC,带有内部DAC的比较器,编码器处理模块(eCAP)...现成的变频器,具有纯形式的矢量控制! 这就是这个家庭的全部精髓-极简主义。 一方面,与Cortex相比,外围设备相当差,但另一方面,实现变频器,dc / dc,dc / ac和步进电机驱动器就足够了。 因此,使用TMS320F28控制器非常简单,易于理解,并且不会因不必要的操作而过载。 但是,如果您突然需要3个UART,并为他们提供了一对i2c和3个以上的SPI,那么这些控制器绝对不适合您-它们具有不同的任务。
开发环境
您看过初始徽标吗? 记住她。 如果您决定在文章英雄的开发中开始使用文章,那么此软件就是您的全部,并且如您所见,该
软件称为controlSUITE 。
该应用程序是为C2000系列控制器开发软件所需的一切的集合和库。 首先安装此应用程序,并查看其组成,它包含:
- 所有现有控制器和基于它们的调试板的描述。 电路,印刷电路板,BOM的来源主要在Altium Designer中
- 印刷电路板的电路和设计示例
- 用于固件开发的核心库
- 数学和DSP库,包括与CLA一起使用
- 每种外设类型的软件项目示例
- 用于执行大多数算法的大量apnout,这些算法用于控制引擎,dc / dc转换器,MPPT控制器和其他系统
- 一组程序,可让您仅使用图形环境即可创建引擎管理系统,而无需进行任何编程
- IDE本身,将被开发
我上面描述的所有内容都非常简短适度。 您将需要几个星期才能看到并至少沿对角线滚动。 当然,一开始您将不需要大量的这种数据量,但是如果您觉得有些不可理解并且很奇怪,那么您需要记住应该去哪里。
现在,我们今天将使用的是IDE,其图形部分基于众所周知的Eclipse。 该编译器不是GCC,而是德克萨斯州提供的GCC,在我看来,绝对比第一个要好。 尽管有人怀疑这是完全相同的gcc掺杂的。 开发环境称为
Code Composer Studio (当前版本7.4)。
项目创建
首先,我想实现与第一篇文章相同的任务,即画一个正弦图。 原则上,在一篇文章的框架内,可以做到这一点,而在框架内留下大量的小东西,但是如您所知,本质就是小东西。 互联网上的TMS上有几篇文章,但它们都非常肤浅,可以归结为“复制并一切正常”的类型,也就是说,根本不考虑过程和意识形态。 因此,在本文的框架中,我们将创建一个项目,从不必要的组件中清除它,在控制器的闪存中配置固件,并学习如何使用GPIO,在这里,它们非常有趣。
从制造商的网站下载CCS7,以通常的方式安装并开始创建项目:
文件→新建→CCS项目...我们看到此窗口,在其中我们需要选择我们感兴趣的控制器,在我的情况下是TMS320F28027,指示项目的名称并规定将其存储的路径。 首先,您需要创建一个用于存储项目的文件夹。 项目名称和文件夹名称可能不匹配。 单击
完成按钮,我们的项目就创建了。
现在,您需要用内容填充我们的项目并进行连接。 在此之前,要改善项目的结构,请创建以下文件夹集:
- inc-包含所有头文件的文件夹
- system_inc-此部分将存储标准库的头文件,我们自己创建的文件(例如main.c)位于inc文件夹中。 这不会破坏某物或去除不必要的东西
- src-所有来源的文件夹
- system_src-包含标准库源文件的文件夹
请注意,这种结构不是某种教条,而只是我的订购想法。 尽管我会向经验最少的人推荐它,但是随着时间的流逝,您将对其进行更改以适合您的世界观,但是现在这将使门框的数量减至最少。
现在在inc文件夹中创建main.h文件,并将其连接到main.c。 通过它将连接基础库。 在开始传输库和其他文件之前,让我们写下到将来的头文件将存储在项目设置中的文件夹的路径。 为此,请在项目树中的项目(测试)上单击鼠标右键,然后单击底部的“
属性” ,或者只需按
Alt + Enter即可 。 在打开的窗口中,转到
Build→C2000 Compiler→Include Options ,此处我们需要两个现有路径-将路径注册到inc和system_inc文件夹。 单击“
添加” ,然后单击“
工作区” ,然后单击到所需的inc文件夹,然后执行相同的操作并紧贴第二个文件夹。 因此,我们规定了相对路径;在传输项目时,您无需重新配置任何内容。 结果,我们得到了这样的图片,然后单击“
确定” :

现在,我们有了一个空项目,其中包含指定的路径和其他设置,仅将其填充库即可。 唯一要做的就是检查所有内容是否已连接。 从理论上讲,您应该获得这样的代码和图片,编译项目。 为此,请按
CTRL + B或转到顶部的“
项目”→“全部构建” 。 该项目应编译无误,外观如下所示(图片可点击):

现在让我们谈谈链接器。 最初,在创建项目时,IDE会生成文件
28027_RAM_lnk.cmd ,它将在调试和固件过程
中将程序放入RAM中。 这在我们调试时很方便,因为 不会浪费闪存资源,并且在RAM中进入调试的速度要快得多。 但是,如果我们想缝制闪光灯怎么办? 为此,还有另一个链接文件会将我们的程序置于闪存中。 我将显示此选项。
首先,删除文件
28027_RAM_lnk.cmd 。 如我所说
-controlSUITE是我们的一切。 我们打开它。 现在进入
英语→设备→Piccolo F2802x→支持库→F28027x的头文件 。 在右侧,我们看到文件夹-这些是标准库以及所有需要的库,包括链接器。 现在,我们转到文件夹
f2802x_common→cmd ,在这里我们看到了该行中所有石头的一组链接器。 不难猜测_RAM文件用于将代码上传到RAM,并且没有此标记即可通过Flash上传。 我们获取文件
F28027.cmd并将其复制到我们的项目中,而不是旧的远程链接器中。
现在是时候迁移库本身了。 我们转到文件夹
f2802x_common→源 ,看到一堆文件。 库有两种类型:标准寄存器(类似于CMSIS)和某种SPL。 在这种情况下,我们只对第一个视图感兴趣,即,前缀为
f2802x_的文件。 当然,您可以将所有这些拖到我们的项目中,但是如果我们不使用所有内容,为什么还要阻塞它呢? 如果您需要某些东西,那么将来我们只添加它即可。 目前,我们将自己限制为以下文件集:
- f2802x_codestartbranch.asm
- f2802x_defaultisr.c
- f2802x_piectrl.c
- f2802x_pievect.c
- f2802x_sysctrl.c
我们复制数据文件并将其粘贴到我们的
system_src文件夹中。 现在,我们转到文件夹
f2802x_headers→源,并从那里获取文件
F2802x_GlobalVariableDefs.c ,然后再次将其复制到我们的
system_src文件夹中。 接下来,转到
f2802x_headers→cmd文件夹,然后将
F2802x_Headers_nonBIOS.cmd文件从此处复制到同一文件夹。 这样就完成了对
system_src文件夹的填充,并转到标题。
我们进入文件夹
f2802x_headers→include并将所有文件从那里复制到我们的
system_inc文件夹中。 现在,我们转到文件夹
f2802x_common→源并从那里复制文件:
- f2802x_examples.h
- f2802x_globalprototypes.h
- f2802x_i2c_defines.h
- f2802x_epwm_defines
- f2802x_swprioritizedisrlevels.h
- f2802x_defaultisr.h
我们应该在项目树中得到这张图片:
现在您需要连接基本库,
main.h文件采用以下形式:
#pragma once #include "F2802x_Device.h" #include "F2802x_examples.h"
我们正在尝试编译。 如果项目编译时没有错误和警告,则所有内容均正确连接。 如果没有发生,那么请仔细检查所有10次,如果根本
无法解决 ,请写信给
PM-正如Owl所说,我会帮忙:
“ Baz-woz-mEz-bottom,也就是说,一无是处 。
”控制器和时钟系统的初始化
在本节中,我们将编写一个函数初始化看门狗定时器和中断向量,并将中断标志设置为零。 我们还设置了时钟系统,因此,外部石英而不是内部RC链将成为时钟源,配置PLL并为所有外设启用时钟。
为了确保代码的准确性,我建议将所有基本初始化放入一个单独的文件中,该文件的前端将是函数
void InitStartSystem(void) 。 为此,请创建文件
systemInitStart.h和
systemInitStart.c 。 我将立即编写一个函数,然后我们只需分析其内容:
void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLCR, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); }
InitStartSystem()中调用的所有函数都是标准函数。 我建议您详细了解它们的实现方式,为此,您可以按住CTRL并单击感兴趣的功能。 看了吗 现在短暂地过去...
- DisableDog() -该功能关闭“狗”。 在设置关键外围设备(例如时钟系统)的主要部分时,这是必不可少的步骤。 在库代码中,您经常会看到这一点,它将被重复复制
- XtalOscSel() -此函数实现从内部时钟源到外部石英的切换。 重要的一点! 该函数的标准库中有一个错误-未声明。 我们转到文件f2802x_globalprototypes.h ,除其他外,我们添加行extern void XtalOscSel(void)

第二个重点! 转到XtalOscSel函数并删除延迟函数。

第三要点! 我们转到文件f28027x_exmaples.h并注释掉延迟实现功能。

- InitPll(TMS320_PLLMUL,TMS320_DIVSEL) -该功能配置PLL。 2个值被传送给它:乘数和除数。 它们的值在头文件中指定。 重要的一点! 我们在库中打开此函数,您需要在最底部注释掉延迟

- InitPll(TMS320_PLLMUL,TMS320_DIVSEL) -该功能配置PLL。 2个值被传送给它:乘数和除数。 它们的值在头文件中指定。 重要的一点! 我们在库中打开此函数,您需要在最底部注释掉延迟
- InitPeripheralClocks() -此函数只是为整个外围设备启用时钟。 是的,所有人。 C2000不是电池供电的密封套的解决方案,
这种数百千瓦的功率和可怜的2-3 mA的解决方案在这里将不起作用。 好吧,您不必每次为某种SPI打开时钟时都可以记住 - InitPieCtrl() -该函数关闭所有中断并重置中断标志
- InitPieVectTable() -函数使用中断向量填充表
实际上,这都是初始化。 我认为许多人已经注意到与
Delay函数相关的“重要点”。 我们为什么要在葡萄树上切呢? 是的,一切都很简单-这是拐杖。
TI工程师在最近的更新中添加了这些完全不必要的延迟到某些功能。 为什么-不只是我一个谜。 寄存器和其他重要条目已经受到保护,因此不会使我们的控制器变得愚蠢。 顺便说一下,在电力电子设备初始化时,根本不可能“变钝”,否则会很麻烦。 因此,永远不要忘记
延迟功能和其他异常功能! 仅出于某些教育目的才允许延迟,例如,使用LED快速闪烁。
为了验证代码是否正常工作,我们在main,compile,flash和
挂钩GPIO18示波器中调用了初始化函数。 该引脚类似于STM32的MCO,表示它输出系统频率。 示波器应能看到56 MHz频率的信号。 如果示波器是好的,那么您会看到蜿蜒的曲折;如果中文(甚至是好的),那么很有可能会更接近正弦。 在
InitPeripheralClocks()函数中可以看到将
GPIO18设置为输出系统频率。 首先,您需要将gpio“连接”到频率输出,然后将分频器设置为1:
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;
GPIO设置
要使用该系列,我们只需要参考手册,TI开发人员将其分为几个文件,每个文件都描述了一定的外围设备,这非常方便。 在
此处下载数据表
,然后转到第126页的“
文档支持”部分。在这里,我们看到一组带有简短说明的文档链接:勘误表,启动引擎管理的指南和每个外围设备的指南。 我们对名为
TMS320F2802x / TMS320F2802xx Piccolo系统控制和中断参考指南的文档感兴趣,该文档包含GPIO的描述以及我们感兴趣的其他基本系统设置。 我们看一下GPIO框图:

我们看到了设备输入/输出端口的相当熟悉的图片。 这里以及打开内部悬挂器的功能,以及通过GPIO使用信号进行中断和其他娱乐的能力。 C2000中此外围设备的主要特征是可以抑制硬件干扰,例如,按钮机械触点的嘎嘎作响。 让我们看一个有趣的图:

它显示了读取输入状态的原理。 在大多数控制器中,使用该外设的时钟频率读取输入状态,即在我们的情况下默认为56 MHz,对于较老系列的相同stm,这些频率甚至更高。 我认为每个人都知道,在这样的频率下,控制器有时间“看到”任何干扰和噪声。 有时需要这种频率,例如,如果我们需要轮询按钮,则有时不需要。 为什么我们每18 ns采访一次她? 因此,我们意识到可以使用
CTRL寄存器和
QUALPRDx位来降低特定端口的时钟频率的可能性,其中X取0到3的值:QUALPRD0负责GPIO0 ... 7,QUALPRD1负责GPIO8 ... 15等等。 实际上,这是系数为1到510的普通分频器。

查询按钮通常没有任何意义,因此我们将分压器调整为510,即最大。 我们再次查看该图,可以看到只有在6个滴答声中信号电平不变时,该信号才被认为是稳定的。 固定所需的措施数量可以是1、3或6。
分频器越大,我们固定的周期越多,则防止颤动的稳定性就越高。 当有一个颤动的触点时,首先是从0到1的混沌过渡,反之亦然,当颤动通过且信号停止并且在6个时钟周期内没有变化时,这意味着已按下按钮。 一切精巧都是简单的。
现在让我们看一下主要寄存器,我们不会碰中断,而只会碰到端口本身的设置。 首先,您需要说寄存器分为两种类型:
设置 寄存器和
数据寄存器 。 前者负责属性的配置,例如此输入或输出。 第二组负责写入和读取端口状态。
设置寄存器:- GPxCTRL-用于写入时钟分频器的寄存器。 代替字母“ x”,我们用字母“ A”代替-如果我们具有GPIO0 ... 31,则代替字母“ B”-如果我们采用GPIO32 ... 63,依此类推
- GPAQSELx-用于设置刻度数的寄存器,用于将数值固定在输入上
- GPAMUX1是用于选择连接的外设的寄存器,例如,它表示GPIO或UART,或者可能是PWM。
- GPADIR -GPIO方向选择寄存器:输入或输出。 默认情况下,所有端口都配置为输入。
- GPAPUD是负责将内部悬挂器连接到VCC的寄存器。
值得注意的是,默认情况下,对于某些端口,上拉处于关闭状态,而在某些情况下,其处于打开状态。
要记住这一点很重要!
数据寄存器:- GPADAT-输出状态寄存器。 如果将输出配置为输入,则从中读取输入状态。 如果将其配置为输出,那么我们可以记下该输出应采用的值,即0或1
- GPASET-寄存器将输出设置为“ 1”。 要设置为“ 1”,必须写“ 1”,写“ 0”时将忽略该命令
- GPACLEAR-寄存器将输出设置为“ 0”。 要设置为“ 0”,必须写“ 1”,写“ 0”时将忽略该命令
- GPATOGGLE是一个寄存器,用于反转输出状态的当前值。 要反转该值,请写“ 1”;写“ 0”时,将忽略该命令
这是一组如此简单的寄存器。 即使从上面的描述中,您已经可以了解配置端口所需要做的事情,但是TI的审慎工程师或技术撰稿人又做了另外的逐步说明:

我马上要说,步骤6和7对我们来说不是必需的,因为 本文中既不使用狗也不使用打扰。 我将简要介绍在学校学习德语的其余步骤:
- 第1步 -确定输出功能:它将是输入或输出,
GPIO或输出到其他外围设备和东西 - 第2步 -启用或禁用内部上拉
- 步骤3-为特定端口配置时钟和跳动保护
- 步骤4-选择所需的功能:gpio或外设
- 第5步 -设置输出方向:输入或输出
如您所见,这就是整个设置,它是基本且逻辑清晰的。 我要立即指出,没有必要按此顺序进行设置,例如,您可以在第一步中设置方向(输入或输出)。 没关系
超级重要!使用C2000系列中的寄存器时,有必要考虑保护它们的时刻。 下文所述的所有内容主要适用于配置组的寄存器。 如果仔细查看标准函数,可能会在其中看到奇怪的命令:
EALLOW; 和
EDIS; 。
EALLOW命令-删除保护并提供对使用系统寄存器的访问权限。
EDIS命令-启用反向保护并提供对系统寄存器的访问权限。 也就是说,任何使用系统寄存器的操作都应始终如下所示:
EALLOW;
如果使用数据寄存器,则不需要执行此操作,例如,如果使用
GPxSET寄存器将输出设置为“ 1”,则无需从中删除保护,然后重新打开它。 到处都有文档说明需要保护什么,什么不应该保护,例如:

基于以上所有内容,我们将GPIO0 ... 3配置为带LED的输出。 我建议将所有GPIO设置都放在
InitLEDgpio函数中并编写:
void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; }
默认情况下,我们的GPIO已配置为GPIO, 所有寄存器的值都被清除,这意味着GPAMUX1寄存器已被写入“ 0”。 对于GPIO0 ... 11,上拉默认为禁用,因此我们只能使用GPADIR来确定输出的工作方向。 如果您还记得的话,LED通过阴极连接到控制器,这意味着在初始化之后它们将立即发光。 让我们直接在初始化函数中将这些结论设置为“ 1”:
void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; }
如您所见,我不使用
GPADAT寄存器进行写入,而是使用
SET,CLEAR,TOGGLE 。 另请注意,我在受保护区域之外(即在
EDIS命令之后)创建了该条目。 现在,在相同的功能中,配置GPIO12以使用该按钮并添加我们的功能:
void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF; GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; }
首先,我通过在
GPAPUD寄存器中写入“ 1”来关闭内部拧紧,因为 默认情况下,它由GPIO12启用。 如我先前所写,初始化后的所有端口都配置为输入,如下所示 零被写入
GPADIR寄存器,在此不进行配置。
仍然需要配置防反弹保护,为此,我们将分频器
0xFF划分为对应的值/ 510。 在寄存器
GPAQSEL1中,我们写入值“ 10”或2,将其设置为6
个小节的样本。 做完了! 为了读取特定输入的值,您只需要从
GPADAT寄存器读取值:
if (GpioDataRegs.GPADAT.bit.GPIO12) {
这就是我们审问必要结论的方式。 现在,让我们在主函数中调用gpio配置函数并获取其最终形式:
void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLMUL, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); InitLEDgpio(); }
现在我们在main的程序主体中调用
InitStartSystem函数,这样就完成了配置。 我们得到以下代码:
#include "main.h" int main (void) { InitStartSystem(); while(1) { } }
现在是时候编写我们的第一个测试程序并测试整个过程了。 算法是这样的:位于GPIO3上的LED闪烁,当您按下GPIO12上的按钮时,我们只需点亮GPIO0 LED。 因此,我们将检查输入和输出端口的操作。 我们编写以下代码:
#include "main.h" int main (void) { InitStartSystem(); while(1) { if (GpioDataRegs.GPADAT.bit.GPIO12) { GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; } else { GpioDataRegs.GPASET.bit.GPIO0 = 1; } GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1; delay(100000); } }
我们进行编译,转到调试器,启动它,然后查看一个LED持续闪烁的方式,当您按下按钮时,另一个LED会亮起。 在本节的最后,我将用此代码附加一个项目,如果无法解决问题,请进行研究。 尤其是对于那些精通文本或不了解所有要点的人,我建议观看此视频,了解如何使用GPIO进行操作,如“ GPIO”部分中所述。 我警告您,该视频长达一个小时,很沉闷,但尽可能详尽,并且所有内容均可见:
文章中的文件
总结
在这个阶段,我正在完成今天的文章。 我认为您了解,如果我立即决定展示DC / AC逆变器的实现,那么本文的内容将是原来的几倍,或者许多重要的细节都将被保留在幕后,在我看来这是不可接受的。
我希望我的文章能帮助所有人开始开发该系列控制器,并开始进行电力电子和机床领域的开发。 将来,我可能会在此主题上写其他一些东西,例如,我想考虑使用PWM或实现某种算法。 最主要的是要有时间。
如果您有任何疑问或无法解决的问题,可以私下给我写信,我会尽力回答您的问题并在研究中提供所有可能的帮助。 祝您培训成功!
UPD 感谢
BelerafonL在
“嵌入式高性能数字控制系统”一书中的提示