This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TIVA TM4C123G LaunchPad学习(配合MSEK)

Other Parts Discussed in Thread: TM4C123GH6PM, EK-TM4C123GXL

TIVA TM4C123G LaunchPad学习过程

第一章开发工具

CCS开发环境是必不可少的,相关的资料比较多,这里不再介绍。在进行TIVA系列芯片学习的时候TIVA开发工具包是一定要安装的,里面集成几乎在开发过程中用到的所有函数库,相关下载安装的说明资料比较多,请自行查阅。好像现在最新的版本是2.1(在官网上有最新的下载)。不过现在很多的代码例程以1.0版本居多(也可能是我用的太少)。正常2.1版本兼容1.0,不过我就遇到过不兼容的案例,现在也没有找到原因(可能是经验不足)。

安装好开发环境CCS、开发工具包、及相应的驱动,再找一开发套件就可以学习了。

第二章开发工具包的应用

要想使用函数库,必须把包含这些函数库的相应开发工具包添加到工程文件中。添加方法:右键工程文件名→Properties→Build→ARMCompiler→IncludeOptions,在Adddirto#includesearchpath中添加你安装开发工具包,添加后相应的路径会出现在下方。例如:"C:\ti\TivaWare_C_Series-1.0",这个是1.0版本的工具包。

个人觉得这样就应该可以使用这个工具包中的函数库中的函数了,但是在实际应用中,出现了一些错误,需要再添加一个路径:右键工程文件名→Properties→ARMLinker→FileSearchPath,在Includelibraryfileorcommandfileasinput中添加链接"C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib"这个应该编译后的一类函数库。

不知是什么原因,请那位大虾有空科普下。

另外,还有一个问题:在添加这个链接后,如把源文件添加到工程中,对一些函数或变量会提示重复定义的错误。

(这方面的问题在后面有实例再说吧)

第三章时钟设置

在进行开发时,第一步要做的应该就是时钟设置了。关于时钟设置在相应芯片手册中有详细说明,我看一段时间,参数说明之后就是各种寄存器的配置,一个字“晕”,感觉这个东西作为查询手册用可能效果更好。

其实,关于时钟配置用一个API函数就可以配置了:SysCtlClockSet()。

这个函数在TIVA开发工具包中,路径:…...\driverlib\sysctl.c,打开后可以看到源代码。关于这个函数的说明,查看路径:…..\docs\SW-DRL-UG-1.0.pdf,(安装版本不同,文件名会有区别)。

这里举例说明这个函数的使用方法:

在使用这个函数之前要添加头文件:#include"driverlib/sysctl.h"

之后就可以直接调用这个函数了,调用方法如下:

SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ)

这里对其中的变量时行说明:

SYSCTL_SYSDIV_5:分频系统,这里表示5分频;

SYSCTL_USE_PLL:锁相环至400MHz;

SYSCTL_OSC_MAIN:外部主晶振输入;

SYSCTL_XTAL_16MHZ:外部晶振是16MHz(这个要与硬件电路匹配)。

这个函数定义结果,外部输入16MHz,经PLL至400MHz,再2分频(芯片自带)至200MHz,再5分频至40MHz。因此这个设置的结果为主频40MHz。

如想更改主频设置,只须修改相应的变量即可,关于各变量的写法与定义,可以查阅文件:SW-DRL-UG-1.0.pdf,里面有详细说明。以后有空再加几个例程吧,这样对理解会更有帮助,欢迎大家自主补充。

第四章GPIO设置

这里先说下GPIO设置的步骤:

1)   配置系统时钟(这个在第三章已经介绍);

2)   打开与此GPIO端口对应的端口时钟。

3)   将端口配置为数字输入输出的GPIO功能,而不是端口的其它复用功能

4)   配置GPIO端口驱动电流大小和上下拉电阻的模式

5)   设置管脚的输入输出方向。

6)   设置管脚输出是高电平还是低电平。

同样TIVA函数库为我们提供了相应的API函数,下面举例进行介绍。

在配置之前别忘记加头文件:

#include <stdint.h>

#include <stdbool.h>

#include "inc/hw_types.h"

#include "inc/hw_memmap.h"

#include "driverlib/sysctl.h"

#include "driverlib/gpio.h"

1) 首先配置系统时钟:

//Setupthesystemclocktorunat50MhzfromPLLwithcrystalreference

SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

2) 使能PORTF端口

//EnableandconfiguretheGPIOportfortheLEDoperation.

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

SysCtlPeripheralEnable这个函数在…...\driverlib\sysctl.c中,相关函数说明在…..\docs\SW-DRL-UG-1.0.pdf中。

变量SYSCTL_PERIPH_GPIOF定义在driverlib/sysctl.h中。

3)使PORTF为输出

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,RED_LED|BLUE_LED|GREEN_LED);

GPIOPinTypeGPIOOutput这个函数在…...\driverlib\gpio.c中,相关函数说明在…..\docs\SW-DRL-UG-1.0.pdf中。

4)下面是LED控制循环程序

//LoopForever

while(1)

       {

              // Turn on the Red LED

              GPIOPinWrite(GPIO_PORTF_BASE,

                                   RED_LED|BLUE_LED|GREEN_LED, RED_LED);

              // Delay for a bit

              SysCtlDelay(200000);

              // Turn on the Blue LED

              GPIOPinWrite(GPIO_PORTF_BASE,

                                   RED_LED|BLUE_LED|GREEN_LED, BLUE_LED);

              // Delay for a bit

              SysCtlDelay(200000);

              // Turn on the Green LED

              GPIOPinWrite(GPIO_PORTF_BASE,

                                   RED_LED|BLUE_LED|GREEN_LED, GREEN_LED);

              // Delay for a bit

              SysCtlDelay(200000);

       }

GPIOPinWrite这个函数在…...\driverlib\gpio.c中,相关函数说明在…..\docs\SW-DRL-UG-1.0.pdf中。另外,关于这个函数,网站的视频课件说的也非常详细可以看一下,视频做得非常好,只是在线看网络不绘图,下载无数次,成功次数没有突破0.

SysCtlDelay这个函数在…...\driverlib\sysctl.c中,相关函数说明在…..\docs\SW-DRL-UG-1.0.pdf中。

这就是一个完整的GPIO配置,控制LED的程序。

注意事项:

1) 本程序用到了几个函数库,所以在起始时一定要添加这些函数库的头文件。

2) 要按第二章介绍,配置工程,即添加引用函路径和链接函数库,实例如下:

右键工程文件名→Properties→Build→ARMCompiler→IncludeOptions,在Adddirto#includesearchpath中添加你安装开发工具包,添加后相应的路径会出现在下方。例如:"C:\ti\TivaWare_C_Series-1.0",这个是1.0版本的工具包。

右键工程文件名→Properties→ARMLinker→FileSearchPath,在Includelibraryfileorcommandfileasinput中添加链接"C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib"。

 

***下面说下第二章提到的问题:

1)在第四章是利用已经编译好的库函数,直接调用,可以正确的运行程序。但是如想查看相应API函数源代码,你必须先知道这个函数在那个库,然后自主去打开(上面已经介绍相对应位置)。

如想直接查看,需要把相应的函数库添加到工程中,添加方法:

右键工程-----add files-----选择相应的源码文件

然后选择函数,按F3即可查看源代码。但是这样就出现了一个问题,在运行时会提示一堆错误,主要是重复定义错误。相应提示如下:(只是节选一部分,应该有代表性)

Description     Resource Path Location  Type

#10056 symbol "SysCtlADCSpeedGet" redefined: first defined in "./sysctl.obj"; redefined in "C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib<sysctl.obj>"    gpiostudy                   C/C++ Problem

#10056 symbol "SysCtlADCSpeedSet" redefined: first defined in "./sysctl.obj"; redefined in "C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib<sysctl.obj>"    gpiostudy                   C/C++ Problem

#10056 symbol "SysCtlClockSet" redefined: first defined in "./sysctl.obj"; redefined in "C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib<sysctl.obj>"    gpiostudy                   C/C++ Problem

#10056 symbol "bNewPLL" redefined: first defined in "./sysctl.obj"; redefined in "C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib<sysctl.obj>"    gpiostudy                   C/C++ Problem

#10056 symbol "SysCtlClockGet" redefined: first defined in "./sysctl.obj"; redefined in "C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib<sysctl.obj>"    gpiostudy                   C/C++ Problem

关于这个问题,困惑了我很长时间,现在还没能准确理解个中原因,解决办法就是把添加到工程中的函数文件删除。但是这样想查看源文件代码就比较麻烦,不知这个问题能不能解决。

2)对于上面的问题,我尝试一种解决方法,但是不可行,还在研究中,下面说下方法过程。

根据上面错误提示,应该是重复定义冲突(个人理解),如果把函数库链接取消,即把

右键工程文件名→Properties→ARMLinker→FileSearchPath,在Includelibraryfileorcommandfileasinput中添加链接"C:\ti\TivaWare_C_Series-1.0\driverlib\ccs\Debug\driverlib.lib"。

这一步取消,不链接这个已经编译好的函数库。同时把这个工程引用的文件添加到工程中,主要是引用的头文件如下:

#include "inc/hw_types.h"

#include "inc/hw_memmap.h"

#include "driverlib/sysctl.h"

#include "driverlib/gpio.h"

同时把相应的.C文件也添加进来,添加方法如下:

右键工程-----add files-----选择相应的源码文件。

正常这样应该能解决问题了,但是只解决了一半。可以通过选择函数名,按F3,查看源代码,但是在编译的时候出现如下错误提示:

Description     Resource Path Location  Type

unresolved symbol IntDisable, first referenced in ./sysctl.obj      gpiostudy                   C/C++ Problem

unresolved symbol CPUwfi, first referenced in ./sysctl.obj  gpiostudy                   C/C++ Problem

unresolved symbol IntRegister, first referenced in ./sysctl.obj     gpiostudy                   C/C++ Problem

unresolved symbol IntEnable, first referenced in ./sysctl.obj      gpiostudy                   C/C++ Problem

<a href="file:/C:/ti/ccsv5/tools/compiler/dmed/HTML/10234.html">#10234-D</a>  unresolved symbols remain  gpiostudy                   C/C++ Problem

unresolved symbol IntUnregister, first referenced in ./sysctl.obj  gpiostudy                   C/C++ Problem

#10010 errors encountered during linking; "gpiostudy.out" not built  gpiostudy                   C/C++ Problem

请那位大虾科普下,这是什么原因,谢谢。

第五章:中断的使用

第六章:ADC

第七章:DAC

第八章:UART

第九章:I2C

第十章:USB

  • 第五章:中断的使用

    中断各类比较多,这一章里将分别进行学习。

    5.1 外部中断

    TM4C123G 所有的外设接口都可以设置成外部中断源。下面以一个例子来说明。

    下面这个例程PD6和PD7作为中断源,分别接按钮;PF1和PF3分别驱动一个LED灯;当按下其中一个按钮时,可以驱动一个LED灯点亮。

    首先设置时钟,使用LED驱动端全能输出:

        // 设置系统主频

        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN

                | SYSCTL_XTAL_16MHZ);

        // Enable and configure the GPIO port for the LED operation.

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    (似乎用的外设,都必须先使能,这个印象中看到过说明,这些外设默认是不能用,要想用到这些外设,必须先使能)

    下面这个代码是使相应LED驱动端为输出。

        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,RED_LED|BLUE_LED|GREEN_LED);

    下面介绍如何设置外部中断:

    void Init_Int_Key() {

     

        // Make PD6/7 an output.

    使能外部中断源外设:

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    按钮接入端设置为输入:

        GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_DIR_MODE_IN);

    端口设置功率和弱上拉:

        GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_STRENGTH_2MA,    GPIO_PIN_TYPE_STD_WPU);

    中断设置为低电平触发:

        GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_LOW_LEVEL);

    使能相应端口中断

        GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    使能中断:

        IntEnable(INT_GPIOD);

    这个应该是使能全局中断:

        IntMasterEnable();

    (不理解为什么要设置这么多中断)

    下面是清除相应端口中断标志:

        GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    }

    下面这一段是中断响应程序,比较易理解,这里只是贴出。

    void Int_GPIO_D_Handler(void)

    {

           unsigned long ulStatus;

           // 读取中断状态

           ulStatus = GPIOIntStatus(GPIO_PORTD_BASE, true);

           // 清除中断状态

           GPIOIntClear(GPIO_PORTD_BASE, ulStatus);

           // 如果KEY的中断状态有效

           if (ulStatus & GPIO_PIN_7)

           {

                  // 延时约10ms,消除按键抖动

                  SysCtlDelay(10 * (SysCtlClockGet() / 3000));

                  // 等待KEY抬起

                  while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7) == 0x00);

                  // 延时约10ms,消除松键抖动

                  SysCtlDelay(10 * (SysCtlClockGet()  / 3000));

                  //TODO 逻辑处理

    //            if(cur_Col < (NUM_CHAR - 1))

    //                   cur_Col++;

     

                  GPIOPinWrite(GPIO_PORTF_BASE,

                                RED_LED|BLUE_LED|GREEN_LED, RED_LED);

                  // Delay for a bit

                  SysCtlDelay(200000);

           }

     

           if (ulStatus & GPIO_PIN_6)// 如果KEY的中断状态有效

           {

                  // 延时约10ms,消除按键抖动

                  SysCtlDelay(10 * (SysCtlClockGet() / 3000));

                  // 等待KEY抬起

                  while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6) == 0x00);

                  // 延时约10ms,消除松键抖动

                  SysCtlDelay(10 * (SysCtlClockGet()  / 3000));

                  //TODO 逻辑处理

                  //            if(cur_Col > 0)

                  //                   cur_Col--;

     

                  // Turn on the Green LED

                  GPIOPinWrite(GPIO_PORTF_BASE,

                                RED_LED|BLUE_LED|GREEN_LED, GREEN_LED);

                  // Delay for a bit

                  SysCtlDelay(200000);

           }

    }

    下面是主程序代码:

    int main(void) {

    // 设置系统主频

    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN

                         | SYSCTL_XTAL_16MHZ);

    // Enable and configure the GPIO port for the LED operation.

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,RED_LED|BLUE_LED|GREEN_LED);

    Init_Int_Key();

    while(1)

           {

           }

    }

    注意:

    1)        包含头文件路径必须要添加,这个在前面已经说明;

    2)        必须在工程中添加文件:startup_ccs.c(目前还没有完全理解这个文件工作过程,这里只是提示一下,不做解释);

    3)        必须添加一个宏定义:右键工程文件名→Properties→Build→ARMCompiler→Advance Options→Predefined Symbols,在Pre-definge NAME中添加变量:PART_TM4C123GH6PM和TARGET_IS_BLIZZARD_RA1,具体原因我现在还没有完全理解。

  • 5.2 看门狗

    首先要使能看门狗(这个很重要),这个芯片的基础:

    SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG0);

    判断看门狗是否补锁,如锁则解:

    // Check to see if the registers are locked, and if so, unlock them.

    if(WatchdogLockState(WATCHDOG0_BASE) == true)

    {

           WatchdogUnlock(WATCHDOG0_BASE);

    }

    给看门狗设定初值,看门狗从此数值开始减小,直到0,给控制器一个中断,再重新计时,到第二次达到0时,才复位,具体过程现在还没有完全理解。

    // Initialize the watchdog timer.

    WatchdogReloadSet(WATCHDOG0_BASE, SysCtlClockGet());

    使能复位功能

    // Enable the reset.

    WatchdogResetEnable(WATCHDOG0_BASE);

    使能看门狗,应该是从此时开始计时

    // Enable the watchdog timer.

    WatchdogEnable(WATCHDOG0_BASE);

     

    喂狗程序:

    WatchdogReloadSet(WATCHDOG0_BASE, SysCtlClockGet());

     

    注意:

    利用这个代码狗赋值:WatchdogReloadSet(WATCHDOG0_BASE, SysCtlClockGet());

    即初值是系统时钟,这样看门狗理论上是应该1秒产生中断,如果考虑到上面提到的需要两次减计数到0,应该是2秒才产生复位。所以应该是2秒内喂狗即(没有测试过,只是分析)。

  • 有串口的实例吗?

  • 安装TivaWare,然后到这个路径下寻找:

    C:\ti\TivaWare_C_Series-2.1.0.12573\examples\boards\ek-tm4c123gxl\uart_echo

  • 不好使呀,你们试过吗?

  • 你的问题是还没建立起一个工程,简单的说,就是你实际的器件和例程中选择的器件不同,你在pin_map.h中增加你的芯片型号的预定义就可以么

  • tm4c的看门狗是第一次count down的时候会给系统一个提示,然后reload设置的值,当第二次count down后仍然没有喂狗的话就产生看门狗复位或者中断,这个是可以通过函数设置的。

  • 在Pre-definge NAME中添加变量:PART_TM4C123GH6PM和TARGET_IS_BLIZZARD_RA1,这个添加的原因是tm4c是一个系列的片子,Tivaware 是库函数,里边的函数包括了所有片子的功能函数,但是不同的片子引脚和寄存器会有一些不同,通过预先宏定义的方式让编译器区分不同的片子和相对应的函数。 

  • 这一步是最重要的,好多人提示外设没有定义,就是没有进行这一步。

  • 您好,请问续集还有吗?我想了解spwm的产生和一些它的资料,还有AD/DA这些

  • 可以看看杭州艾研科技的官网,里面有spwm的例程和模块