本系列文章链接


本文主要介绍TMS320C6455的GPIO和定时器相关的内容,参考文档为:

GPIO

  C6455总共16个GPIO,主要有一些基本的读写和中断的功能。

GPIO基本操作

  有四个基本的寄存器,OUT_DATA、SET_DATA、CLR_DATA和IN_DATA。
  当一个GPIO作为输出使用时,可以直接改OUT_DATA寄存器中的特定bit来改变GPIO的输出,也可以往SET_DATA或者CLR_DATA寄存器中的对应bit写1来达到置一或者清零的目的。
  当一个GPIO作为输入使用时,读SET_DATA和CLR_DATA寄存器会返回OUT_DATA寄存器中的值,但这个值并不是GPIO端口上的值。真正的端口上的值只能通过读IN_DATA寄存器获取。

GPIO中断

  每个GPIO都是和一个特定的中断号绑定的,中断号51-66分别对应GPIO0-0GPIO15的外部中断。
  BINTEN寄存器中的第0bit控制GPIO中断的使能,如果要用GPIO中断,一定要将它置一。
  中断触发条件由CPU内的RIS_TRIG和FAL_TRIG两个bit确定。这两个bit用户无法直接访问,但是可以通过四个寄存器SET_RIS_TRIG、CLR_RIS_TRIG、SET_FAL_TRIG和CLR_FAL_TRIG对它们进行更改。读SET_RIS_TRIG或CLR_RIS_TRIG寄存器能够得到RIS_TRIG的值,FAL_TRIG的值也是一样。

RIS_TRIG FAL_TRIG 触发方式
0 0 中断禁用
0 1 下降沿触发
1 0 上升沿触发
1 1 双边沿触发

  有一个比较有意思的地方是,某个GPIO如果配置为输出模式,并且使能了中断。那么在这个GPIO上输出符合中断触发条件的信号时,也能够触发中断和EDMA事件。CSL的GPIO例程就是做了这样一件事。

GPIO的CSL

  CSL_gpioInit()同样没有实际的作用。
  CSL_gpioOpen()获取GPIO相关寄存器的基地址,得到相应的Object,这个GPIO的Object和handler一般都创建成全局变量,方便在不同函数中调用。
  CSL_gpioHwSetup()也是没有实际作用。GPIO的配置通过CSL_gpioHwControl()函数的CSL_GPIO_CMD_CONFIG_BIT命令来完成。包括对GPIO的置位、清零、读取等操作都可以通过CSL_gpioHwControl()这个函数完成。

Timer

  C6455有两个定时器,是一样的。都有三种工作模式:64bit的定时器,两个32bit的定时器和WDT模式。其中两个32bit的模式还可以细分为级联的和非级联的。

  上图是定时器的整体框图,在使用定时器前需要明确时钟源,可以选择内部时钟或外部时钟,内部时钟就是主频的六分频,可以据此计算需要定时的时间。
  不管定时器工作在哪种工作模式,关键的寄存器就那么几个。CNTHI和CNTLO是计数器的部分,PRDHI和PRDLO是计数周期。然后就是两个控制寄存器TCR和TGCR。
  TCR中的ENMODE_HI和ENMODE_LO,一方面是让定时器开始工作,同时另一方面也是选择定时器的工作模式,就是定时器工作一个周期还是连续地工作。另外还可以在TCR中配置定时器输出脉冲还是时钟信号,脉冲还可以设置脉冲宽度,所谓时钟信号就是在计数一个周期后,定时器输出反转。还有选择时钟源、输入时钟反相、输出反相、定时器输出状态查看等等都是在TCR寄存器完成。
  TGCR,全局的定时器控制寄存器,控制寄存器的工作模式,还有复位,还有独立的32bit模式工作时的高32bit计数器的预分频值都是在这里设置。
  还有和在线仿真有关的一个寄存器EMUMGT_CLKSPD、一个看门狗控制寄存器WDTCR,感觉不是很重要,有需要大家可以自行查阅手册。
  一个定时器的高32bit和低32bit都能够产生中断事件,C6455的67-70的中断号分别对应Tmier0和Timer1的低32bit定时器和高32bit定时器产生的中断。

64bit模式

  64bit的定时器,计数寄存器由高32位的CNTHI和低32位的CNTLO组成,即使是用1GHz的系统主频,这个计数器也需要记好几百年才能从0计到2^64^,所以完全能满足平时的计数需求。

级联的32bit模式

  级联的32bit模式中,原来的高32bit作为预分频的计数器。预分频计数器计数满一个周期时,CNTLO就会加一。

独立的32bit模式

  独立的32bit模式就能得到两个独立的32bit定时器。其中的高32bit会自带一个4bit的预分频器,这个预分频的值能够在TGCR中设置。而低32bit也是一个独立的定时器,而且不带预分频。

Timer的CSL

  Timer的CSL用起来也很方便
  CSL_tmrInit()同样是一个没有实际作用的函数。
  CSL_tmrOpen()获取指定的定时器的基地址,因为有两个Timer,所以需要给定定时器编号。
  CSL_tmrHwSetup()对定时器的工作模式、输出类型、计数周期进行配置。
  CSL_tmrHwControl()启动定时器即可。
  要用定时器中断,可以在“soc.h”找到对应的中断号的宏。然后用CSL_intcOpen(),创建中断控制器的对象,对中断控制器进行配置即可。