基于StarterWare的TMS320C6748裸机程序开发入门详解教程
LED裸机程序开发
本小结将讲解如何利用TI提供的StarterWare软件包开发一个基于DSP C6748的LED流水灯程序,以及如何查找芯片的技术参考手册和数据手册。文章内容主要涵盖LED裸机程序开发、工程建立、添加头文件和库文件、源代码编写和解析和按键中断裸机程序演示和解析等。
关于如何操作CCS、配置仿真器、烧写程序等,请查看《TMS320C6748开发案例使用手册》的内容。本教程只是配合《TMS320C6748开发案例使用手册》对基本的GPIO操作进行指导性的说明。具体程序内容可能因我司案例更新有差异,以实际案例为准。
本篇文章主要讲解硬件开发中,如何使用Matlab生成可供TMS320C6748开发板(测试板卡)使用的算法,内容包含有快速入门、安装Matlab、编写函数M文件、验证算法、生成/使用/测试代码、进阶指南等,欢迎嵌入式开发相关用户阅读与分享。
测试板卡为创龙科技TL6748-EVM开发板,它是一款基于TI TMS320C6748定点/浮点DSP C674x处理器设计的开发板,由核心板和底板组成。核心板经过专业的PCB Layout和高低温测试验证,稳定可靠,可满足各种工业应用环境。开发板接口资源丰富,引出网口、uPP、EMIFA、SATA、USB、LCD、VGA等接口,方便用户快速进行产品方案评估与技术预研。
工程建立
产品资料中提供DSP LED程序镜像和源码,路径为:
GPIO_LED.out:Demo\StarterWare\Binary\GPIO_LED.out //DSP镜像
main.c:Demo\StarterWare\Application\GPIO_LED\main.c //DSP程序源码
在工程建立前,请先使用GEL文件配合仿真器连接DSP核,具体步骤参考《TMS320C6748开发案例使用手册》的开发准备、工程建立、程序加载与固化等等步骤。然后点击“File -> New -> Project -> CCS Project”,然后点击Next,弹出对话框,并修改,如下所示。
图 1
Target:C674x Floating-point DSP->TMS320C6748;选择芯片
Project name:LED;CCS工程名字
在"Empty Projects"下方选择"Empty Project(with main.c)",点击Finish就可以完成工程新建了,弹出如下界面。
图 2
添加头文件和库文件
将StarterWare安装路径下的include目录复制到LED工程的工作目录下。include目录的内容是TMS320C6748开发所需的头文件。LED的工程目录在新建工程时已经设置好工作目录了,例如本例的默认路径,如下图所示。
图 3
在LED工程的工作目录中新建库文件的存放目录library,然后将StarterWare安装路径下的如下文件复制到新建的library目录中。
\binary\c674x\cgt_ccs\c6748\drivers\Debug\drivers.lib
\binary\c674x\cgt_ccs\c6748\system_config\Debug\system_config.lib
drivers.lib是TMS320C6748一般外设开发所需的库文件,其源码在StarterWare的drivers目录下。比如StarterWare的include目录下的头文件“gpio.h”,里面有很多相关函数声明,具体实现都是在StarterWare的drivers目录下的“gpio.c”文件里面。
设置编译参数
右击工程,在弹出的菜单中点击Properties(属性),如下图所示。
图 4
在弹出的对话框中点击General,在“Output format”处选择“abi(ELF)”,表明DSP程序的输出镜像的格式是ELF(StarterWare的库默认编译的是ELF文件),数据存取格式是小端模式,如下图所示。
图 5
点击“Build -> C6000 Compiler -> Include Options”,弹出如下界面。
图 6
点击右边的
符号添加包含的头文件路径,弹出如下对话框。
图 7
在空白处先后两次输入“../include”和“../include/hw”,解析如下。
../include: gpio.h头文件所在路径,工程目录下的include目录,LED程序程序将用到。
../include/hw: hw_types.h和其他头文件所在路径,工程目录下的“include/hw”目录,LED程序程序将用到。
增加后如下图所示。
图 8
点击OK,完成编译参数设置。
源代码编写和解析
将产品资料"Demo\StarterWare\Application\GPIO_LED\"目录下的程序源码main.c的内容复制到工程的main.c文件中,或直接用文件覆盖。CCS中设置为12号字体时,中文注释会比较美观,程序源码解析如下。
/****************************************************************************/
/* */
/* 底板 LED 测试 */
/* */
/* 2014年04月20日 */
/* */
/****************************************************************************/
#include "TL6748.h" // 创龙 DSP6748 开发板相关声明
#include "hw_types.h" // 宏命令
#include "hw_syscfg0_C6748.h" // 系统配置模块寄存器
#include "soc_C6748.h" // DSP C6748 外设寄存器
#include "psc.h" // 电源与睡眠控制宏及设备抽象层函数声明
#include "gpio.h" // 通用输入输出口宏及设备抽象层函数声明
/****************************************************************************/
/* */
/* 宏定义 */
/* */
/****************************************************************************/
// 软件断点
#define SW_BREAKPOINT asm (" SWBP 0 ");
/****************************************************************************/
/* */
/* 全局变量 */
/* */
/****************************************************************************/
/****************************************************************************/
/* */
/* 函数声明 */
/* */
/****************************************************************************/
// 外设使能配置
void PSCInit (void );
// GPIO 管脚复用配置
void GPIOBankPinMuxSet ();
// GPIO 管脚初始化
void GPIOBankPinInit ();
// 延时
void Delay (unsigned int n);
/****************************************************************************/
/* */
/* 主函数 */
/* */
/****************************************************************************/
int main (void )
{
// 外设使能配置
PSCInit();
// GPIO 管脚复用配置
GPIOBankPinMuxSet();
// GPIO 管脚初始化
GPIOBankPinInit();
// 主循环
for (;;)
{
// 延时
Delay(0x00FFFFFF);
GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_LOW); // D10 灭 GPIO0[2]
GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_HIGH); // D7 亮 GPIO0[0]
// 延时
Delay(0x00FFFFFF);
GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_LOW); // D7 灭 GPIO0[0]
GPIOPinWrite(SOC_GPIO_0_REGS, 6, GPIO_PIN_HIGH); // D6 亮 GPIO0[5]
// 延时
Delay(0x00FFFFFF);
GPIOPinWrite(SOC_GPIO_0_REGS, 6, GPIO_PIN_LOW); // D6 灭 GPIO0[5]
GPIOPinWrite(SOC_GPIO_0_REGS, 2, GPIO_PIN_HIGH); // D9 亮 GPIO0[1]
// 延时
Delay(0x00FFFFFF);
GPIOPinWrite(SOC_GPIO_0_REGS, 2, GPIO_PIN_LOW); // D9 灭 GPIO0[1]
GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_HIGH); // D10 亮 GPIO0[2]
}
}
/****************************************************************************/
/* */
/* PSC 初始化 */
/* */
/****************************************************************************/
void PSCInit (void )
{
// 使能 GPIO 模块
// 对相应外设模块的使能也可以在 BootLoader 中完成
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
}
/****************************************************************************/
/* */
/* GPIO 管脚复用配置 */
/* */
/****************************************************************************/
void GPIOBankPinMuxSet (void )
{
// 配置相应的 GPIO 口功能为普通输入输出口
// 底板 LED
GPIOBank0Pin0PinMuxSetup();
GPIOBank0Pin1PinMuxSetup();
GPIOBank0Pin2PinMuxSetup();
GPIOBank0Pin5PinMuxSetup();
}
/****************************************************************************/
/* */
/* GPIO 管脚初始化 */
/* */
/****************************************************************************/
void GPIOBankPinInit (void )
{
// 配置 LED 对应管脚为输出管脚
// OMAPL138 及 DSP C6748 共有 144 个 GPIO
// 以下为各组 GPIO BANK 起始管脚对应值
// 范围 1-144
// GPIO0[0] 1
// GPIO1[0] 17
// GPIO2[0] 33
// GPIO3[0] 49
// GPIO4[0] 65
// GPIO5[0] 81
// GPIO6[0] 97
// GPIO7[0] 113
// GPIO8[0] 129
// 核心板 LED
GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT); // GPIO6[12]
GPIODirModeSet(SOC_GPIO_0_REGS, 110, GPIO_DIR_OUTPUT); // GPIO6[13]
// 底板 LED
GPIODirModeSet(SOC_GPIO_0_REGS, 1, GPIO_DIR_OUTPUT); // D7 GPIO0[0]
GPIODirModeSet(SOC_GPIO_0_REGS, 2, GPIO_DIR_OUTPUT); // D9 GPIO0[1]
GPIODirModeSet(SOC_GPIO_0_REGS, 3, GPIO_DIR_OUTPUT); // D10 GPIO0[2]
GPIODirModeSet(SOC_GPIO_0_REGS, 6, GPIO_DIR_OUTPUT); // D6 GPIO0[5]
}
/****************************************************************************/
/* */
/* 延时 */
/* */
/****************************************************************************/
void Delay (unsigned int n)
{
unsigned int i;
for (i=n;i>0;i--);
}
以上是GPIO_LED流水灯控制程序,对于GPIO的操作,操作步骤如下。
查看评估底板的原理图,找到与LED连接的GPIO编号。评估底板与LED连接的GPIO分别是GPIO0[1]、GPIO0[2]、GPIO0[5],如下图所示。
图 9
首先对处理器的PSC控制进行初始化,使用StarterWare的psc.h头文件提供的PSCModuleControl()来进行控制,因为PSC控制器涉及到较多的内容,这里仅对GPIO_LED这个案例的用法含义做说明,后面各个寄存器说明也是。详细信息请自行查看TMS320C6748的数据手册和技术参考手册。向PSCModuleControl()传入GPIO的PSC寄存器地址,即SOC_PSC_1_REGS,基于HW_PSC_GPIO这个值做一个偏移到实际GPIO的PSC控制位,PSC_POWERDOMAIN_ALWAYS_ON和PSC_MDCTL_NEXT_ENABLE都是使能PSC相关的控制位,如下图所示。
图 10
PSCModuleControl()函数在psc.h头文件有申明其原型,如下图所示。
图 11
SOC_PSC_1_REGS定义了PSC1控制器的基址,可以在产品资料“Datasheet\核心板元器件\CPU\”目录下《TMS320C6748 Fixed- and Floating-Point DSP datasheet (Rev. G)》数据手册查到数据,如下图所示。
图 12
图 13
图 14
PSC中的GPIO控制在PSC1中的LPSC号码是3,HW_PSC_GPIO定义为3,如下图所示。
图 15
图 16
图 17
PSC_POWERDOMAIN_ALWAYS_ON设置PSC控制器PTCMD、PTSTAT相应的位,在技术参考手册有具体说明,如下图所示。
图 18
图 19
图 20
图 21
查看TMS320C6748的数据手册,查找GPIO_LED对应的管脚的PINMUX寄存器的地址,将对应的管脚的寄存器中相应位设置为GPIO的工作模式。为方便用户开发,我司已将GPIO复用等配置操作直接封装成了函数,用户如需使用,可以直接包含"TL6748.h"文件,并将产品资料"Demo\StarterWare\Application\Platform\"下的源码复制到用户当前工程文件夹内即可。这里GPIO复用配置的函数是GPIOBankXPinXPinMuxSetup(),如下图所示。
图 22
本案例中实际是使用StarterWare的库函数HWREG(x)来设置PINMUX的寄存器地址值,用户可以自行查看产品资料"Demo\StarterWare\Application\Platform\GPIO.c",其具体的配置例如:HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1))。
HWREG(x)可以在"include/hw/"目录下中hw_types.h头文件查看定义,如下图所示。
图 23
SOC_SYSCFG_0_REGS是PINMUX的基地址,可以在"include/hw/"目录下的soc_C6748.h头文件查看定义,如下图所示。
图 24
可以看出SOC_SYSCFG_0_REGS的值为0x01C14000,类似的地址都可以在《TMS320C6748 Fixed- and Floating-Point DSP datasheet (Rev. G)》数据手册中找到,下图为数据手册中SYSCFG0寄存器基址、结束地址、长度等信息。
图 25
图 26
SYSCFG0_PINMUX(1)是PINMUX1的偏移地址,可以在"include\hw\"目录下hw_syscfg0_C6748.h头文件查看定义,如下图所示。
图 27
可以算出PINMUX1的偏移地址为0x124,那么可以算出PINMUX1的值为:PINMUX1=(0x01C14000+0x124)=0x01C14124。
具体的地址可以在产品资料“Datasheet\核心板元器件\CPU\”目录下《TMS320C6748 DSP (Rev. C)》技术参考手册查到PINMUX1的值。
图 28
图 29
设置GPIO的方向寄存器。本案例中使用StarterWare的库函数GPIODirModeSet()将GPIO口配置为输出,例如:GPIODirModeSet(SOC_GPIO_0_REGS, 1, GPIO_DIR_OUTPUT)。
GPIODirModeSet()在include目录下gpio.h头文件查看定义,如下图所示。
图 30
SOC_GPIO_0_REGS是GPIO的基地址,在"include\hw\"目录下soc_C6748.h头文件查看定义,如下图所示。
图 31
可以看出SOC_GPIO_0_REGS的值为0x01E26000,类似的地址都可以在《TMS320C6748 Fixed- and Floating-Point DSP datasheet (Rev. G)》数据手册查到数据,下图为数据手册中GPIO基地址的值。
图 32
图 33
第二个参数“1”是GPIO0[0]的编号,以下为各组GPIO第一个管脚的对应值(范围1~144):GPIO0[0~15]=1~16,GPIO1[0~15]=17~32,GPIO2[0~15]=33~48,GPIO3[0~15]=49~64,GPIO4[0~15]=65~80,GPIO5[0~15]=81~96,GPIO6[0~15]=97~112,GPIO7[0~15]=113~128,GPIO8[0~15]=129~144。
GPIO_DIR_OUTPUT定义GPIO的方向为输出,可以在include目录下gpio.h查看定义输出输入的标志,如下图所示。
图 34
配置GPIO的数据寄存器。本案例中使用StarterWare的库函数GPIOPinWrite()来设置GPIO的值,例如:GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_HIGH)。
GPIOPinWrite()可以在include目录下gpio.h头文件查看定义,如下图所示。
图 35
SOC_GPIO_0_REGS是GPIO的基地址,第二个参数“1”是GPIO0[0]的编号。
GPIO的输出值通过GPIO_PIN_HIGH(高电平)和GPIO_PIN_LOW(低电平)来指定,可以在include目录下gpio.h头文件查看定义,如下图所示。
图 36
编译和运行LED控制程序
右击工程,在弹出来的对话框中点击“Build Project”,即可对当前工程编译,如下图所示。
图 37
编译完毕后,可在左侧工程的Binaries下看到生成的可执行led.out文件,如下图所示。
图 38
点击左上角的
load键,选择要加载的led.out文件,如下图所示。
图 39
等待程序加载完成,然后点击
程序运行按钮,可以发现评估底板的LED进行流水灯演示。按F5会进去函数里面,按F6单步运行代码。
按键中断裸机程序演示和解析
本小结将讲解如何利用现成的裸机程序,使用中断方式测试评估底板的按键,并详细解析此按键中断程序。
产品资料中提供按键中断程序镜像和源码,路径为:
GPIO_KEY.out:demo\StarterWare\Binary\GPIO_KEY.out //DSP镜像
main.c:demo\StarterWare\Application\GPIO_KEY\main.c //DSP程序源码
导入工程
在工程导入前,请先使用GEL文件唤醒DSP核,也可参考产品资料用户手册中的《TMS320C6748开发案例使用手册》。然后点击CCS菜单“File -> Import”,弹出如下对话框。
图 40
点击“Code Composer Studio->Existing CCS Eclipse Projects”后,再点击Next,如下图所示。
图 41
在弹出的对话框的“Select search-directory”后面点击“Browse…”选择button的CCS工程的存放路径,选择后如下图所示。
图 42
点击Finish就可以导入现有CCS工程。然后右击工程,在弹出来的对话框中点击“Rebuild Project”,即可对当前工程编译,如下图所示。
图 43
编译完毕后,可在左侧工程的Binaries下看到生成的可执行button.out文件,如下图所示。
图 44
点击左上角的
load键,选择要加载的button.out文件,如下图所示。
图 45
等待程序加载完成,然后点击
程序运行按钮,再按下SW5和SW6按键,可以发现CCS的Console窗口有按键被按下的信息提示,如下图所示。
图 46
源代码解析
以下为按键中断函数的解析。
/****************************************************************************/
/* */
/* 按键中断测试 */
/* */
/* 2014年4月20日 */
/* */
/****************************************************************************/
#include "TL6748.h" // 创龙 DSP6748 开发板相关声明
#include "hw_types.h" // 宏命令
#include "hw_syscfg0_C6748.h" // 系统配置模块寄存器
#include "soc_C6748.h" // DSP C6748 外设寄存器
#include "psc.h" // 电源与睡眠控制宏及设备抽象层函数声明
#include "gpio.h" // 通用输入输出口宏及设备抽象层函数声明
#include "interrupt.h" // DSP C6748 中断相关应用程序接口函数声明及系统事件号定义
/****************************************************************************/
/* */
/* 宏定义 */
/* */
/****************************************************************************/
// 软件断点
#define SW_BREAKPOINT asm (" SWBP 0 ");
/****************************************************************************/
/* */
/* 全局变量 */
/* */
/****************************************************************************/
unsigned char Flag=0;
/****************************************************************************/
/* */
/* 函数声明 */
/* */
/****************************************************************************/
// 外设使能配置
void PSCInit (void );
// GPIO 管脚复用配置
void GPIOBankPinMuxSet ();
// GPIO 管脚初始化
void GPIOBankPinInit ();
// GPIO 管脚中断初始化
void GPIOBankPinInterruptInit (void );
// DSP 中断初始化
void InterruptInit (void );
// 中断服务函数
void USER0KEYIsr (void );
void USER1KEYIsr (void );
/****************************************************************************/
/* */
/* 主函数 */
/* */
/****************************************************************************/
int main (void )
{
// 外设使能配置
PSCInit();
// GPIO 管脚复用配置
GPIOBankPinMuxSet();
// GPIO 管脚初始化
GPIOBankPinInit();
// DSP 中断初始化
InterruptInit();
// GPIO 管脚中断初始化
GPIOBankPinInterruptInit();
unsigned int i;
// 主循环
for (;;)
{
// 亦可以使用查询法查询中断状态
if (Flag)
{
// 核心板 LED
for (i=0x00FFFFFF;i>0;i--); // 延时
GPIOPinWrite(SOC_GPIO_0_REGS, 109, GPIO_PIN_LOW);
GPIOPinWrite(SOC_GPIO_0_REGS, 110, GPIO_PIN_HIGH);
for (i=0x00FFFFFF;i>0;i--); // 延时
GPIOPinWrite(SOC_GPIO_0_REGS, 109, GPIO_PIN_HIGH);
GPIOPinWrite(SOC_GPIO_0_REGS, 110, GPIO_PIN_LOW);
}
}
}
/****************************************************************************/
/* */
/* PSC 初始化 */
/* */
/****************************************************************************/
void PSCInit (void )
{
// 使能 GPIO 模块
// 对相应外设模块的使能也可以在 BootLoader 中完成
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
}
/****************************************************************************/
/* */
/* GPIO 管脚复用配置 */
/* */
/****************************************************************************/
void GPIOBankPinMuxSet (void )
{
// 配置相应的 GPIO 口功能为普通输入输出口
// 核心板 LED
GPIOBank6Pin12PinMuxSetup();
GPIOBank6Pin13PinMuxSetup();
// 底板按键
GPIOBank0Pin6PinMuxSetup();
GPIOBank6Pin1PinMuxSetup();
}
/****************************************************************************/
/* */
/* GPIO 管脚初始化 */
/* */
/****************************************************************************/
void GPIOBankPinInit (void )
{
// 配置 LED 对应管脚为输出管脚
// OMAPL138 及 DSP C6748 共有 144 个 GPIO
// 以下为各组 GPIO BANK 起始管脚对应值
// 范围 1-144
// GPIO0[0] 1
// GPIO1[0] 17
// GPIO2[0] 33
// GPIO3[0] 49
// GPIO4[0] 65
// GPIO5[0] 81
// GPIO6[0] 97
// GPIO7[0] 113
// GPIO8[0] 129
// 核心板 LED
GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT); // GPIO6[12]
GPIODirModeSet(SOC_GPIO_0_REGS, 110, GPIO_DIR_OUTPUT); // GPIO6[13]
// 底板按键
GPIODirModeSet(SOC_GPIO_0_REGS, 7, GPIO_DIR_INPUT); // USER0 KEY GPIO0[6]
GPIODirModeSet(SOC_GPIO_0_REGS, 98, GPIO_DIR_INPUT); // USER1 KEY GPIO6[1]
}
/****************************************************************************/
/* */
/* GPIO 管脚中断初始化 */
/* */
/****************************************************************************/
void GPIOBankPinInterruptInit (void )
{
// 底板按键中断
// 配置 USER0 KEY GPIO0[6] 为下降沿触发
GPIOIntTypeSet(SOC_GPIO_0_REGS, 7, GPIO_INT_TYPE_FALLEDGE);
// 配置 USER1 KEY GPIO6[1] 为上升沿及下降沿触发
GPIOIntTypeSet(SOC_GPIO_0_REGS, 98, GPIO_INT_TYPE_BOTHEDGE);
// 使能 GPIO BANK 中断
GPIOBankIntEnable(SOC_GPIO_0_REGS, 0); // USER0 KEY GPIO0
GPIOBankIntEnable(SOC_GPIO_0_REGS, 6); // USER1 KEY GPIO6
// 注册中断服务函数
IntRegister(C674X_MASK_INT4, USER0KEYIsr);
IntRegister(C674X_MASK_INT5, USER1KEYIsr);
// 映射中断到 DSP 可屏蔽中断
IntEventMap(C674X_MASK_INT4, SYS_INT_GPIO_B0INT);
IntEventMap(C674X_MASK_INT5, SYS_INT_GPIO_B6INT);
// 使能 DSP 可屏蔽中断
IntEnable(C674X_MASK_INT4);
IntEnable(C674X_MASK_INT5);
}
/****************************************************************************/
/* */
/* DSP 中断初始化 */
/* */
/****************************************************************************/
void InterruptInit (void )
{
// 初始化 DSP 中断控制器
IntDSPINTCInit();
// 使能 DSP 全局中断
IntGlobalEnable();
}
/****************************************************************************/
/* */
/* 中断服务函数 */
/* */
/****************************************************************************/
void USER0KEYIsr (void )
{
// 软件断点 方便调试
//SW_BREAKPOINT;
// 禁用 GPIO BANK 0 中断
GPIOBankIntDisable(SOC_GPIO_0_REGS, 0);
// 清除 GPIO BANK 0 中断状态
IntEventClear(SYS_INT_GPIO_B0INT);
if (GPIOPinIntStatus(SOC_GPIO_0_REGS, 7) == GPIO_INT_PEND)
{
// 清除 GPIO0[6] 中断状态
GPIOPinIntClear(SOC_GPIO_0_REGS, 7);
Flag=0;
}
// 使能 GPIO BANK 0 中断
GPIOBankIntEnable(SOC_GPIO_0_REGS, 0);
}
void USER1KEYIsr (void )
{
// 软件断点 方便调试
//SW_BREAKPOINT;
// 禁用 GPIO BANK 6 中断
GPIOBankIntDisable(SOC_GPIO_0_REGS, 6);
// 清除 GPIO BANK 6 中断状态
IntEventClear(SYS_INT_GPIO_B6INT);
if (GPIOPinIntStatus(SOC_GPIO_0_REGS, 98) == GPIO_INT_PEND)
{
// 清除 GPIO6[1] 中断状态
GPIOPinIntClear(SOC_GPIO_0_REGS, 98);
Flag=1;
}
// 使能 GPIO BANK 6 中断
GPIOBankIntEnable(SOC_GPIO_0_REGS, 6);
}
以上是按键中断程序注释,对于按键中断,操作步骤如下。
查看评估底板的原理图,找到与用户按键连接的GPIO编号。评估底板与用户按键连接的GPIO分别是GPIO0[6]、GPIO6[1],如下图所示。
图 47
首先对处理器的PSC控制进行初始化,使用StarterWare的psc.h头文件提供的PSCModuleControl()来进行控制,因为PSC控制器涉及到较多的内容,这里仅对GPIO_KEY这个案例的用法含义做说明,详细信息请自行查看TMS320C6748的数据手册和技术参考手册。
向PSCModuleControl()传入GPIO的PSC寄存器地址,即SOC_PSC_1_REGS,基于HW_PSC_GPIO这个值做一个偏移到实际GPIO的PSC控制位,PSC_POWERDOMAIN_ALWAYS_ON和PSC_MDCTL_NEXT_ENABLE都是使能PSC相关的控制位,如下图所示。
图 48
查看TMS320C6748的数据手册,查找GPIO_LED对应的管脚的PINMUX寄存器的地址,将对应的管脚的寄存器中相应位设置为GPIO的工作模式。
为方便用户开发,我们已将GPIO复用等等配置操作直接封装成函数,用户如需使用,可以直接包含"TL6748.h"文件,并将产品资料"Demo\StarterWare\Application\Platform\"目录下的源码复制到用户当前工程文件夹内即可。这里GPIO复用配置的函数是GPIOBankXPinXPinMuxSetup(),如下图所示。
图 49
本案例中使用StarterWare的库函数HWREG(x)来设置PINMUX的寄存器地址值,例如:HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1))。
HWREG(x)可以在"include\hw\"目录下hw_types.h头文件查看定义,如下图所示。
图 50
SOC_SYSCFG_0_REGS是PINMUX的基地址,可以在"include\hw\"目录下soc_C6748.h头文件查看定义,如下图所示。
图 51
可以看出SOC_SYSCFG_0_REGS的值为0x01C14000,类似的地址值都可以在《TMS320C6748 Fixed- and Floating-Point DSP datasheet (Rev. G)》数据手册查到数据,下图为数据手册中SYSCFG0寄存器基址、结束地址、长度等信息。
图 52
图 53
SYSCFG0_PINMUX(1)是PINMUX1的偏移地址,可以在"include/hw"目录下hw_syscfg0_C6748.h头文件查看定义,如下图所示。
图 54
可以算出PINMUX1的偏移地址为0x124,那么可以算出PINMUX1的值为:PINMUX1=(0x01C14000+0x124)=0x01C14124。
具体的地址可以在产品资料“Datasheet\核心板元器件\CPU\”目录下《TMS320C6748 DSP (Rev. C)》技术参考手册中找到,下图为技术参考手册中PINMUX1的值。
图 55
图 56
设置GPIO复用模式,根据数据手册"10.5.10.2 Pin Multiplexing Control 1 Register (PINMUX1)"章节PINMUX1寄存器的控制位说明,给其写入0x00000080即可配置为GPIO模式。
图 57
图 58
图 59
设置GPIO的方向为输入。
本案例中使用StarterWare的库函数GPIODirModeSet()将GPIO口配置为输出,例如:GPIODirModeSet(SOC_GPIO_0_REGS, 7, GPIO_DIR_INPUT)。
GPIODirModeSet()可以在include目录下gpio.h头文件查看声明,如下图所示。
图 60
SOC_GPIO_0_REGS是GPIO的基地址,可以在"include\hw\"目录下soc_C6748.h头文件查看定义,如下图所示。
图 61
可以看出SOC_GPIO_0_REGS的值为0x01E26000,类似的地址都可以在TMS320C6748 Fixed- and Floating-Point DSP datasheet (Rev. G)》数据手册找到,下图为数据手册查到的GPIO基地址的值。
图 62
图 63
第二个参数“1”是GPIO0[0]的编号,以下为各组GPIO第一个管脚的对应值(范围1~144):GPIO0[0~15]=1~16,GPIO1[0~15]=17~32,GPIO2[0~15]=33~48,GPIO3[0~15]=49~64,GPIO4[0~15]=65~80,GPIO5[0~15]=81~96,GPIO6[0~15]=97~112,GPIO7[0~15]=113~128,GPIO8[0~15]=129~144。
GPIO_DIR_INPUT定义GPIO的方向为输入,可以在include目录下egpio.h头文件查看定义输出输入的标志。在技术参考手册可查看GPIO的控制寄存器说明。如下图所示。
图 64
图 65
图 66
设置GPIO中断,这里需要设置GPIO的中断类型以及使能GPIO中断。gpio.h头文件已声明GPIO中断类型设置和使能的函数,在技术参考手册可以查看下降沿触发中断的设置方式和使能中断设置方法。
图 67
图 68
图 69
图 70
图 71
设置DSP中断控制器。设置DSP中断控制器主要作用是初始化DSP中断控制器和使能全局中断,函数是StarterWare方便用户使用而提供的,用户只需要包含了相关头文件直接调用即可。
中断初始化,使用IntDSPINTCInit()函数;使能全部中断,使用IntGlobalEnable()函数;图 72
配置按键中断。按键中断初始化函数中有以下几个作用:
注册按键中断服务函数,添加中断到中断向量列表。使用IntRegister()函数;映射按键中断对应CPU中断,进入中断后程序会自动跳转到相应入口地址。使用IntEventMap();使能按键对应的CPU中断,使用IntEnable();调用中断服务函数,打印按键被按下的信息,使用USERXKEYIsr();图 73
图 74
图 75
调试仿真。进入仿真后运行程序,按下按键可以看到CCS的Console窗口有打印相对应的按键信息。
图 76
到这里已经介绍完所有的基本GPIO操作的过程及机制,用户可以自行参照这个过程去分析其他案例的具体操作过程。
「学术论文」基于TMS320C6748的多路串行通信接口设计与实现
摘要:
在嵌入式飞行控制系统中,为了满足小型化和集成化的要求,需要控制多个串口与外部设备通信。采用TMS320C6748作为核心处理器,通过EMIF总线实现和异步通信协议芯片TL16C754并行通信,采用3-8译码器74LS138扩展多位片选信号,实现集成扩展多路串行通信接口的功能。底层驱动基于TI的实时操作系统内核SYS/BIOS进行开发,可减小设计的难度,并缩短了开发周期。试验结果表明,该设计方法能够实现多路数据的完整接收,数据传输完整可靠。
中文引用格式: 杨庆国,陈军,肖贵林. 基于TMS320C6748的多路串行通信接口设计与实现[J].电子技术应用,2019,45(7):59-62.
英文引用格式: Yang Qingguo,Chen Jun,Xiao Guilin. Design and implementation of multi-channel serial communication interface based on TMS320C6748[J]. Application of Electronic Technique,2019,45(7):59-62.
0 引言
微处理器DSP是一种为实现数字信号处理算法而生的器件[1],其硬件结构上的特殊性表现在内部存储器采用程序总线和数据总线分开的哈佛结构,具有专门的硬件乘法器[2]。但在嵌入式DSP系统应用领域中,一般需要它同时与多个外部设备进行数据交互和通信[3],其中串行通信接口因其简单可靠,仍是目前广泛采用的技术[4],而当前的DSP的串口较少,满足不了多路串行通信接口能力。本文采用高速浮点处理器DSP作为嵌入式飞行控制系统的核心处理芯片,可实时地完成系统运算和控制,充分发挥DSP在数字信号处理方面的技术优势[5]。设计了一种基于TMS320C6748的多路串行通信接口电路,采用异步通信协议芯片TL16C754和3-8译码器74LS138实现多路串行通信接口的集成与扩展,底层驱动基于TI的实时操作系统内核SYS/BIOS进行开发。不但减小了软件开发难度,而且可以保障系统的稳定性,使得开发周期大大缩短。
1 硬件电路设计
1.1 系统架构设计
基于DSP处理器的多路串行通信接口系统(以下简称接口系统)主要由控制电路和接口电路组成,系统架构如图1所示。其中,控制电路是系统的核心处理模块,主要包括DSP处理器、存储器、复位电路、时钟电路、电源电路和JTAG等辅助电路;接口电路是实现多路串行通信的模块,主要包括协议处理器、译码器、隔离电路和电平转换电路等。
1.2 控制电路设计
核心处理器DSP选用TI的浮点运算低功耗芯片TMS320C6748,其主频为456 MHz,具有高达3 648 MIPS和2 756 MFLOPS的运算能力。
时钟电路采用时钟信号为24 MHz OSC外部时钟晶体输出。
电源电路采用集成电源供电方式,即内核电压和I/O电压通过同一块电源模块供电,内核电压为1.2 V,I/O电压为1.8 V和3.3 V,本系统采用了效率较高的电源管理芯片TPS650061RUK,其效率可以到90%,而且要求的压降小。
复位电路采用基于IPM811复位芯片进行设计,该芯片不仅具有上电复位和手动复位功能,而且还具有电源电压监控功能,可输出最小持续时间为140 ms的低电平有效复位信号。
RAM存储器采用TI的低功耗高速RAMMT47H64M16芯片,可为DSP提供更大的程序执行/数据存储空间。Flash存储器采用SPANSION公司的S29GL128N芯片,用于系统软件的固化存储。
1.3 接口电路设计
协议处理器采用TL16C754芯片,它是一款通用异步串行通信控制器,具有自动软件/硬件流控制能力,具有可以储存、缓冲两个异步时钟之间数据传输[6]的64字节FIFO,并且通过可编程实现不同触发水平来中断;可编制数据为5 bit、6 bit、7 bit或8 bit,用于UART并行数据和串行数据的格式转换。译码器采用3-8译码器74LS138芯片,可进行8 bit数据转换。
系统通过TMS320C6748的EMIF数据总线与16C754A的8 bit数据总线连接,将TL16C754的地址配置在EMIF映射空间内,TMS320C6748的EMIF地址总线通过3-8译码器74LS138用于扩展8 bit片选信号,实现对8路RS422接口信号的选通。
隔离电路采用ADI公司的六通道数字隔离器ADuM7643,实现接口电路的数字隔离。
电平转换电路采用驱动总线收发器MAX490,实现RS422信号收发功能。它是一款低功耗收发器,用于RS422等串行数据接口标准系统中[7],内部有驱动和接收两个模块,最大传输速率为2.5 Mb/s。
在硬件设计中,采用EMIF接口8位数据线与TL16C754端口一一对应,保证DSP与外部设备的正常通信,当外部数据发送过来,会触发DSP的外部中断。在译码器电路中,通过3个地址信号产生8路不同的片选信号,当译码器产生一路选通,对应的并行数据就会传输到总线上,等待接收,接口电路原理图如图2所示。
2 驱动软件实现
DSP驱动软件是基于TI的SYS/BIOS操作系统进行设计开发,开发环境选择CCS5.5(Code Composer Studio)。系统的软件分为:系统初始化模块、UART驱动模块、系统中断模块。利用SYS/BIOS的多线程中断控制来实现多路串行通信接口的功能,系统上电后硬件系统自动将Flash存储器中的程序加载到256 KB的片内存储器中开始运行。
首先,执行对设备的CPU初始化,运行cinit初始化运行环境,调用SYS/BIOS系统函数初始化系统配置;然后调用main函数,完成EMIF总线与时钟等的初始化,完成系统自检、数据结构初始化、UART初始化等工作。在main函数结束返回后,调用BIOS_start,使能硬件中断,开始按优先级检测并执行串口硬件中断服务子程序,软件的功能在这些中断任务的驱动下完成,串口中断主要完成数据的接收。
本系统的软件主要由DSP完成EMIF总线的读写时序和TL16C754的寄存器控制信号。
(1)系统的初始化。初始化主要包括PLL配置,管脚复用控制寄存器(PINMUXReg)的配置,电源控制寄存器(PSC)的配置。因为TMS320C6748的管脚大多是复用的,所以需要根据应用条件配置相应的PINMUX寄存器。PSC是C67x的一大特色,通过配置PSC可独立控制芯片某一部分的供电,可以最大限度地降低功耗。
(2)GPIO中断配置。TMS320C6748没有独立的外部中断引脚,是通过配置GPIO作为中断源信号,在配置中断时应注意配置中断的方向和触发方式。
(3)时序控制。通过配置CE4CFG寄存器对CE4空间的读写操作进行控制。CE4CFG可以控制建立、选通、保持时间和数据宽度。本文将UART扩展在EMIFA的CE4空间商,CE4扩展空间的基地址为0x64000000,对UART进行读写操作时,对0x64000000地址进行操作即可。DSP处理器通过WE、OE和CE4信号控制串口芯片,但需要3 bit地址线和CE4通过译码器片选8路UART信号。DSP对异步接口的读取周期由建立时间、选通时间和保持时间组成。其关键程序设计如下:
EMIFWaitTimingConfig(SOC_EMIFA_0_REGS,CHIP_
SELECT_4,EMIFA_ WAITTIME_CONFIG(1,2,1,1,2,1,0));
(4)多路UART中断控制。TL16C754芯片提供4路中断信号,所以采用8路UART共享一个中断资源的方式,在SYS/BIOS中调用中断4(INT4)并行处理8路UART数据,其中断处理流程如图3所示。
3 系统试验验证
3.1 单路串行接口测试
随机选取一路串口进行试验测试。首先,将接口系统的通信接口与PC的RS232串口相连,PC按指定的配置参数启动串口通信,利用上位机测试软件,向接口系统发送数据。该接口系统采用中断方式对串口数据进行接收,数据接收完整后,接口系统会将数据转发出来,PC收到后将其与原始数据比较,检验是否一致,若一致,上位机测试软件显示串口测试成功,其测试结果如图4所示。试验结果表明,单路串行通信接口数据传输完整可靠。
3.2 双路串行接口测试
现场测试时,随机选取接口系统的两路RS422串口与外部的GPS接收机和IMU的串口连接,接口系统的通信接口与PC的RS232串口连接。利用两个串口同时接收GPS接收机和IMU数据帧,存入相应的数据缓存单元。接口系统DSP内部驱动不断检测是否接收到一帧的GPS和IMU数据,若正确收到,则利用上位机测试软件显示出来,并以数据文件的格式存储下来。试验测试后,打开数据文件,所设计的多路串行通信接口能完整地接收GPS和IMU数据。其测试结果如图5所示。试验结果表明,双路串行通信接口数据传输完整可靠。
4 结论
本文对基于DSP的多路串行通信接口系统进行了设计,该系统硬件接口电路简单,调试方便。采用DSP的EMIF控制方式完成数据的传输,通过异步通信协议芯片和译码器实现接口的集成与扩展,解决了DSP内部存储器与外设之间数据传输的速度问题,减轻了DSP的运算负荷,提高了串行通行的实时性和可靠性。底层驱动基于SYS/BIOS实时操作系统设计开发,不但减小软件开发难度,而且可以保障系统的稳定性,使得开发周期大大缩短。通过试验测试,所设计的多路串行通信接口系统能够接收多路数据,数据传输完整可靠,现已应用于某预研项目中,为其后续的开展提供了有力保障。
参考文献
[1] 于凤芹.TMS320C6000DSP结构原理与硬件设计[M].北京:北京航空航天大学出版社,2008.
[2] 张晓峰,李悦丽,黎向阳,等.一种基于FPGA和SC16C554实现多串口通信的方法[J].电子技术,2009,46(6):34-36.
[3] 李海洋.基于DSP和FPGA的多功能嵌入式导航计算机系统设计[D].南京:南京航空航天大学,2003.
[4] 刘凤新,赵坚固.基于FPGA的多路并行独立串口的实现[J].仪表技术与传感器,2010(11):44-46.
[5] 史晓锋,李铮,蔡志权.基于DSP的高速数据采集与处理系统[J].电子技术应用,2001,27(6):78-80.
[6] 喻少林,韩波,李平.基于FPGA的飞控计算机多路串行通信设计[J].计算机工程,2011,37(20):242-245.
[7] 蒋艳红.基于FPGA的UART设计与应用[J].计算机工程,2008,34(21):225-226.
作者信息:
杨庆国,陈 军,肖贵林
(湖南云箭集团有限公司,湖南 长沙410100)
相关问答
戴尔笔记本关机后电源灯依然亮着-ZOL问答建议一定要安装windows原版操作系统,不要使用Ghost版本的操作系统,因为这类操作系统多为精简系统,稳定性和兼容性非常差,且一般不带AHCI相关驱动无法识别AHCI模...
tms320vc5416替代产品?目前,TI已经停产tms320vc5416,但是该型号的替代产品是tms320c6748,该产品具有更高的处理速度和更多的外设接口,同时也支持更多的通信协议和更多的存储器类型...