AiBOM
首页 > 文章 > TMS320F28335PGFA > DSP 基础学习 2:GPIO与第一个实验:流水LED灯
为您找到相关搜索
TEXAS INSTRUMENTS  TMS320F28335PGFA.  芯片, 数字信号控制器(DSC), 浮点
德州仪器公司(Texas Instruments,简称:TI)位于美国德克萨斯州达拉斯城,是一家全球性的半导体公司,是世界领先的数字信号处理和模拟技术的设计商、供应商,是推动电子数字化进程的引擎。公司在30多个国家设有工厂、分公司或办事处。设有以下几个业务部门: 半导体部:1997年半导体收入占总收入的83%。主要产品是DSP方案,此外还有微控制器和ASIC。 教育产品事业部:目前TI公司在便携教育技术方面居领先地位。 材料控制:该部门服务于汽车、气候控制、电子、通讯、光学、飞行器市场。 公司的主要产品有:数字信号处理、模拟和混合信号器件、数字逻辑、ASIC、微控制器、语音和图形处理器、PLC可编程逻辑控制器、军用器件等。公司主要业务有:设计和制造模拟、数字信号处理和DLP芯片技术,帮助客户开发相关产品。从连接更多人的经济实惠的手机到支持远程学习的教室投影仪到可信度、灵活度和自由度更高的修复器械-TI技术均采用了新的理念,产生了更好的解决方案。 德州仪器的半导体产品几乎占了其收入的85%(2003年数据)。在包括数字信号处理器、数字模拟转换器、模拟数字转换器、能源管理、模拟集成电路等不同产品领域都占据领先位置。无线通信也是德州仪器的一个焦点,全球有大约50%的移动电话都装有德州仪器生产的芯片。同时它也生产针对应用的集成电路以及单片机等。 德州仪器一直保持着半导体销售前十的名次。在2005年,它仅次于英特尔和三星,排在它之后的是东芝、意法半导体等。德州仪器主要竞争对手包括微型芯片技术公司、Cypress半导体公司、集成设备技术公司、三星电子以及Xilinx公司。 TI 自1986年进入中国大陆以来,一直高度关注中国市场的发展。经过公司董事会批准的TI中国发展战略于1996年正式实施。此战略的目标是帮助中国建立合理的电子产品结构,并且提高高科技产品的设计能力,力求以全球领先的DSP技术支持中国高科技产业走向世界。为贯彻此战略,TI除在中国建立了庞大的半导体代理商销售网外,还在北京、上海、深圳及香港设立了办事处及技术支持队伍,提供许多独特的产品及服务,包括DSP和模拟器件产品、硬件和软件开发工具以及设计咨询服务等。
查看详情
微控制器是将微型计算机的主要部分集成在一个芯片上的单芯片微型计算机。微控制器诞生于20世纪70年代中期,经过20多年的发展,其成本越来越低,而性能越来越强大,这使其应用已经无处不在,遍及各个领域。例如电机控制、条码阅读器/扫描器、消费类电子、游戏设备、电话、HVAC、楼宇安全与门禁控制、工业控制与自动化和白色家电(洗衣机、微波炉)等。
查看详情
热门推荐
STM32f103ZET6 学习资料 (连载3 存储器和总线构架 )
STM32f103ZET6 学习资料 (连载3 存储器和总线构架 )
元器件的Datasheet PDF数据手册如何阅读?如何快速掌握产品引脚图及功能等关键信息?
元器件的Datasheet PDF数据手册如何阅读?如何快速掌握产品引脚图及功能等关键信息?
基于STC15w408AS的电子时钟的设计
基于STC15w408AS的电子时钟的设计

DSP 基础学习 2:GPIO与第一个实验:流水LED灯

未过河的卒 2020-01-14 06:02 1618次阅读 TMS320F28335PGFA 微控制器

1 实验准备

1.1 实验简介

1.2 GPIO介绍

2 代码解读

2.1 准备工作

2.2 LED.h

2.3 LED.c

3 结尾细节


  鄙人使用的DSP是TMS320F28335PGFA,开发板是pop28335(师兄遗留的,开发板大同小异,貌似POP现在倒闭了?),仿真器是XDS100V3。电脑系统为windows8.1,CCS软件版本是6.0.1。

--------------------------------------------------------------------------------

  本着以做为主的原则,这一篇就要做出第一个实验:流水LED灯。为了做出这个实验,还得学习GPIO相关的内容。本篇用到的资源在以下这个链接里下载。

  https://download.csdn.net/download/huagengpai1994/10875803

  里面有四个文件夹,分别是例程、数据手册、用户手册和应用手册。


1.1 实验简介

  实验达到的效果是让led灯间歇依次高亮,也就是流水LED灯。

  LED灯属于外设,要想控制外设就得知道硬件是怎么连接的,所以看原理图是必要的第一步。

  在开发板原理图上可以找到LED灯部分,如下图。

TMS320F28335PGFA GPIO流水LED灯实验

  可以看到有8个LED灯,一端通过限流电阻接在3.3V高电压上,D3.3表示直流3.3V。另一边分别接在GPIO60,GPIO61,GPIO2,GPIO3,GPIO4,GPIO5,GPIO6,GPIO7。

  GPIO全称是:General Purpose Input Output (通用输入/输出)。它是DSP芯片用来与外界电路进行信息互换的端口。只要让GPIO输出低电压,那么对应的LED灯支路就会有电流通过,该LED灯被点亮,反之不亮。所以关键在于GPIO的使用。


1.2 GPIO介绍


  DSP28335一共88个IO口分为3组

  A组:GPIO0~GPIO31

  B组:GPIO32~GPIO63

  C组:GPIO64~GPIO87

  下图是核心板原理如上DSP的部分,可以看到有很多GPIO口。

TMS320F28335PGFA GPIO流水LED灯实验

  TI官方给出了一些手册用来说明芯片的使用。我这里有用户手册,数据手册和应用手册,下载链接在本文开头给出了。在用户手册的《sprufb0d(TMS320x2833x, 2823x System Control and Interrupts)》第六章General-Purpose Input/Output (GPIO)中详细说明了GPIO。这里就不挨个解读了,建议将该章通读一遍,虽然是英文的但应该都能看明白。


2 代码解读

  把上篇的模板拷贝过来一份,直接使用该模板进行开发。

  鄙人的本程序也是参考别人的例程开发的(买板子的时候店家给的,不知道是不是官方的),该例程只有一个main.c文件。所有例程都在资料里,本篇的相关的内容应该是例程17。


2.1 准备工作

TMS320F28335PGFA GPIO流水LED灯实验

  在Hello DSP 文件夹下新建文件夹APP,然后在其中新建LED文件夹,接着在LED文件夹下新建LED.C和LED.h两个文件。APP是用来保存外设的文件,LED是一个外设。新建public.c和public.h,用来包含公共的头文件,否则main.c的内容过于多。这样是基于模块化的编程,将功能分离,逻辑上更简洁。

  在public.c中写入以下代码:

TMS320F28335PGFA GPIO流水LED灯实验

  在public.h中写入以下代码:

TMS320F28335PGFA GPIO流水LED灯实验

  第1,2,7行代码是固定程式,在这里就是这样去写。C语言里这叫条件编译,是为了防止重定义。

  第4,5行,表示包含这两个头文件,第一个头文件是为了包含DSP系统的基本文件,包含它相当于包含了另两个文件。第二个就是包含我们编写的外设文件,LED.h。


2.2 LED.h

  在LED.h中写入一下代码。

#ifndef LED_H
#define LED_H

#include "DSP28x_Project.h"

/**************************************宏定义************************************************/
#define LED1_OFF GpioDataRegs.GPBSET.bit.GPIO60 = 1 //LED D10 点亮
#define LED1_ON GpioDataRegs.GPBCLEAR.bit.GPIO60 = 1 //LED D10 熄灭
#define LED2_OFF GpioDataRegs.GPBSET.bit.GPIO61 = 1 //LED D11 点亮
#define LED2_ON GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1 //LED D11 熄灭
#define LED3_OFF GpioDataRegs.GPASET.bit.GPIO2 = 1 //LED D12 点亮
#define LED3_ON GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 //LED D12 熄灭
#define LED4_OFF GpioDataRegs.GPASET.bit.GPIO3 = 1 //LED D13 点亮
#define LED4_ON GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 //LED D13 熄灭
#define LED5_OFF GpioDataRegs.GPASET.bit.GPIO4 = 1 //LED D14 点亮
#define LED5_ON GpioDataRegs.GPACLEAR.bit.GPIO4 = 1 //LED D14 熄灭
#define LED6_OFF GpioDataRegs.GPASET.bit.GPIO5 = 1 //LED D15 点亮
#define LED6_ON GpioDataRegs.GPACLEAR.bit.GPIO5 = 1 //LED D15 熄灭
#define LED7_OFF GpioDataRegs.GPASET.bit.GPIO6 = 1 //LED D16 点亮
#define LED7_ON GpioDataRegs.GPACLEAR.bit.GPIO6 = 1 //LED D16 熄灭
#define LED8_OFF GpioDataRegs.GPASET.bit.GPIO7 = 1 //LED D17 点亮
#define LED8_ON GpioDataRegs.GPACLEAR.bit.GPIO7 = 1 //LED D17 熄灭

#define DELAY_TIME 2000000 //延时时间
/***********************************************************************************/

/*********************************************函数声明*****************************/
void Init_LedGpio(void);
void delay(Uint32 t);
void LED_Start(void);
/******************************************************************************/
#endif
  #ifndef #define #endif 是固定程式的条件编译。
  #include "DSP28x_Project.h"是为了利用DSP自带的库文件。

  宏定义了16个LED灯亮灭,因为GPIO60和GPIO61在B组,所以是在GPBSET和GPBCLEAR。SET置1表示输出高电压,此时LED灯灭。CLEAR置1表示输出低电压,这样LED就亮了。bit表示该组下的一个GPIO口。这种写法是C语言的结构体语法,不懂的话可以去百度学习一下。很显然此处使用一个比较复杂的结构体GpioDataRegs去控制DSP内部寄存器,进而设置想要的GPIO状态。说它复杂是因为该结构体里面又嵌套了结构体,不是有很多小点符号嘛。

  #define DELAY_TIME 2000000 是宏定义了一个变量,用来给出延迟时间。

  最后的三个函数声明是我们要给出的外设函数,.h文件声明,.c文件详细定义,这都是C语言的基本语法。


2.3 LED.c

  在LED.c中写入以下代码:

#include "LED.h"
void Init_LedGpio(void)
{
EALLOW;
//LED D10
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPBSET.bit.GPIO60 = 1;// Load output latch
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO60  = 1;// GPIO11 = output
//LED D11
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPBSET.bit.GPIO61 = 1;// Load output latch
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO61  = 1;// GPIO11 = output
    
//LED D12
GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO2 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;// GPIO11 = output
    
//LED D13
GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO3 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;// GPIO11 = output
    
//LED D14
GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO4 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;// GPIO11 = output
    
//LED D15
GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO5 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO5 = 1;// GPIO11 = output
    
//LED D16
GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO6 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;// GPIO11 = output
    
//LED D17
GpioCtrlRegs.GPAPUD.bit.GPIO7 = 0;// Enable pullup on GPIO11
GpioDataRegs.GPASET.bit.GPIO7 = 1;// Load output latch
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 0;// GPIO11 = GPIO
GpioCtrlRegs.GPADIR.bit.GPIO7 = 1;// GPIO11 = output
EDIS;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
void LED_Start(void)
{
LED1_ON;//LED1 D10 点亮
delay(DELAY_TIME);//延时
LED1_OFF;//LED1 D10 熄灭
LED2_ON;//LED2 D11 点亮
delay(DELAY_TIME);//延时
LED2_OFF;//LED2 D11 熄灭
LED3_ON;//LED3 D12 点亮
delay(DELAY_TIME);//延时
LED3_OFF;//LED3 D12 熄灭
LED4_ON;//LED4 D13 点亮
delay(DELAY_TIME);//延时
LED4_OFF;//LED4 D13 熄灭
LED5_ON;//LED4 D13 点亮
delay(DELAY_TIME);//延时
LED5_OFF;//LED4 D13 熄灭
LED6_ON;//LED4 D13 点亮
delay(DELAY_TIME);//延时
LED6_OFF;//LED4 D13 熄灭
LED7_ON;//LED4 D13 点亮
delay(DELAY_TIME);//延时
LED7_OFF;//LED4 D13 熄灭
LED8_ON;//LED4 D13 点亮
delay(DELAY_TIME);//延时
LED8_OFF;//LED4 D13 熄灭
}
  void Init_LedGpio(void)的作用是对LED初始化。EALLOW和EDIS指令其实是两条汇编指令。
  #define EALLOW asm(" EALLOW")
  #define EDIS asm(" EDIS")

  这样做是因为TI的DSP为了提高安全性能,将很多关键寄存器作了保护处理。通过状态寄存器1(ST1)的位6设置与复位,来决定是否允许DSP指令对关键寄存器进行操作。这些关键寄存器包括:器件仿真寄存器、FLASH寄存器、CSM寄存器、PIE矢量表、系统控制寄存器、GPIOMux寄存器等等。

  DSP由于在上电复位之后,状态寄存器基本上都是清零,而这样的状态下正是上述特殊寄存器禁止改写的状态。为了能够对这些特殊寄存器进行初始化,所以在对上述特殊寄存器进行改写之前,一定要执行汇编指令asm(“EALLOW”)或者宏定义EALLOW来设置状态寄存器1的C6位,在设置完寄存器之后,一定要注意执行汇编指令asm(“EDIS”)或者宏定义EDIS来清除状态寄存器1的C6位,来防止杂散代码或指针破坏寄存器内容。

  总之写上这两个指令,夹在中间的指令才会有效。

  8个LED灯的初始化套路是一致的,所以只解读第一个。

  GpioDataRegs.GPBSET.bit.GPIO60 = 1; 刚才说过了是让LED灯灭,写在这里是为了初始化的时候让它灭。

  GpioCtrlRegs是控制寄存器结构体,刚才说明的GpioDataRegs是数据寄存器结构体。数据寄存器反映的是管脚的状态,控制寄存器是对管脚进行设置。数据寄存器会将指定管脚置0置1就够了,控制寄存器见手册说明如下:

TMS320F28335PGFA GPIO流水LED灯实验

  GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;表示引脚有一个上拉电阻,上拉电阻的原理很简单此处不说明,达到的效果就是默认高电平。可能会有人说我设置该引脚高电平它就是高电平,设置低电平就是低电平,干嘛要默认啊。没有上拉电阻或者下拉电阻,叫悬空状态。悬空状态下管脚的电压很容易忽高忽低,可能你手指头摸摸电路板上的线管脚电压值就变了。所以要上拉稳定在高电平,只有你置低电平它才是低电平。

  GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0; GpioCtrlRegs.GPBMUX2是复用选择器,用来设置IO口的复用功能。DSP只有88个IO口,为了充分利用引脚的功能,大部分引脚都有复用功能,此处我们把引脚当做通用IO口来用,所以此位设置为0。以后碰到复用功能的时候再说明。

  GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1; GpioCtrlRegs.GPBDIR是用来配置是用作输入口(2)还是输出口(1),这里置1,用作输出。

  表中还有一个变量是GPAQSEL,本次实验没有用到,它的作用是输入限定,这个比较复杂,用到的时候再具体说明吧,总的效果就是要限定最大输入消除噪声。

  总的来看,void Init_LedGpio(void)的作用就是将GPIO配置好,完成初始化。

  void delay(Uint32 t),语义很明显了,是让CPU空跑,这样就可以间歇性的闪烁。前面宏定义的DELAY_TIME 2000000,差不多空跑跑这么多就是半秒把。很显然这种方式不仅计时不准还很浪费CPU的资源,最好的做法应该是用定时器定时,时间到了进入中断,不过这个以后再用。

  void LED_Start(void) 的语义也很简单,点亮第一个灯,CPU空跑1秒,再关闭第一个灯同时点亮第二个灯,CPU再空跑1秒,依此进行到第8个灯。LEDx_ON和LEDx_OFF是LED.h中宏定义的函数,前面已经说过了。

  现在外设的函数准备都完成了,下面去写main.c中的代码。

#include "public.h"     // Device Headerfile and Examples Include File
void main(void)
{
   InitSysCtrl();//Initialize System Control
   extern Init_LedGpio();//Initalize GPIO
   
   //Disable Interrupt
   DINT;
   IER = 0x0000;
   IFR = 0x0000;
   InitPieCtrl();//Initialize Pie
   InitPieVectTable();
   while(1)//死循环
  {
   extern LED_Start();
  }
}

  main.c中只需要包含public.h就可以了,具体要包含哪些内容属于public.h公共头文件去写的。

   InitSysCtrl();定义在DSP2833x_SysCtrl.c中,下为其函数具体内容,关闭关门狗,初始化PLL,初始化外设时钟。

  void InitSysCtrl(void)

  {

   // Disable the watchdog

   DisableDog();

   // Initialize the PLL control: PLLCR and DIVSEL

   // DSP28_PLLCR and DSP28_DIVSEL are defined in DSP2833x_Examples.h

   InitPll(DSP28_PLLCR,DSP28_DIVSEL);

  

   // Initialize the peripheral clocks

   InitPeripheralClocks();

  }

  这属于时钟部分,以后会细讲。这里 InitSysCtrl();只要认为是把时钟打开并设置为150MHZ就OK了。

  Init_LedGpio();是我们自己写的初始化LED的函数。

  下面这段代码是初始化的一部分,和中断、向量表等有关,以后再说,先默认这样去初始化。这些函数的定义都可以在包含的系统文件里找到。

  //Disable Interrupt
   DINT;
   IER = 0x0000;
   IFR = 0x0000;
  
   InitPieCtrl();//Initialize Pie
  
   InitPieVectTable();

   最后循环执行LED_Start(),效果就是LED间歇性依此点亮。

  至此,代码讲解完毕。将文件Build后Debug,然后就可以在仿真器里面跑了,然后就可以在板子上看到效果。


3 结尾细节

  如果在main.c中不加那两个extern,Bulid完毕会出现两个Warning:function “Init_LedGpio” declared implicitly;function “LED_Start” declared implicitly。也就是说我们在main.c中调用的两个函数隐含声明。网上说要把该函数声明为全局函数就好,于是鄙人在LED.h里对函数声明加了extern。这样做的道理是如果不声明为extern,那么编译器认为该函数只应该在LED.c中使用,毕竟delay()函数可没有declared implicitly,因为我只在LED.c中用了delay()。这样还是不行,看来该网友的搞法在DSP的CCS里行不通,虽然按照规范写法,编译器应该找不到,但毕竟智能嘛,找到了,程序能跑,不过给你俩warning改去吧。于是我将extern加在main.c函数调用那里,意思是让编译器去其他地方找这俩函数,这次还就通过了,看来这样是对的。

  鄙人在main.c中加了关键字extern,依然会出现这两个warning,但是实验效果达到了,这个以后再研究吧,有懂的可以评论说一下。

  另外,鄙人在跑的时候仿真器连接出了问题,问题如下:

  Error connecting to the target:

  (Error -151 @ 0x0)

  One of the FTDI driver functions used during

  the connect returned bad status or an error.

  竟然显示连接不到仿真器,但我的仿真器灯都亮的好好的呢,设备管理器里也显示连接正常。百度了一下,有人说重新装仿真器驱动就好了。于是我关闭了CCS后,重新装了一下驱动,果然好了。出现这个问题很有可能是仿真器设置错误,即没有选定正确的型号,或者就是仿真器和电脑的接触不好,如果一切正常那么就是驱动出了问题,重装一下就好了。


温馨提示:本文由网友投稿,经网站编辑整理发布,转载请注明出处和本文链接,如有侵犯您的权益,请及时与我们联系,我们将核实情况后进行相关处理!
相关推荐
STM32f103ZET6 学习资料 (连载3 存储器和总线构架 )
STM32f103ZET6 学习资料 (连载3 存储器和总线构架 )
STM32f103ZET6 存储器和总线构架,在互联型产品中的构成,及寄存器和启动配置浅析
STM32F103ZET6 / STM32 / 微控制器 8345
基于STC15w408AS的电子时钟的设计
基于STC15w408AS的电子时钟的设计
DIY电子时钟的详细制作:显示时间+日期+温度;能自动调节亮度;能调节时间+闹铃。
STC15W408AS / 微控制器 1453
单片机控制大功率LED灯(解读)
单片机控制大功率LED灯(解读)
N沟道增强型MOSFET,在电路中像NPN三极管工作在饱和状态一样充当开关,单片机端口输出高电平时,G S间加正向电压大于开启电压,沟道导通,D S 间电压很小(0.45v),3个串联LED上的压降不足,灯灭。反之,端口为低电平时,LED灯亮。
微控制器 / 2N7000 / LM117 883
利用单片机快速实现家庭智能控制平台
利用单片机快速实现家庭智能控制平台
一提到智能家庭,大家可能首先想到的是各种大佬级公司搞的牛逼产品,或者说是创新产品。想想就觉得很复杂,有的用工控机,有的用树莓派,还有的用arduino,不管用什么,都绕不过服务器进行控制,比如yeelink平台,腾讯的智能硬件平台等等。其实,真实实现起来,并没有想想中这么复杂,我们甚至只用一个小的单片机就能实现。
微控制器 / 开发板 416
关注

关注采芯网

回复型号,查元件信息

采芯网 FindIC 用户意见反馈
问题类型
网站页面问题或建议
数据问题或错误
元器件采购询价
其他
意见建议
联系方式
反馈和联系