如何理解这个DSP编程代码?

时间:2015-11-19 21:07:23

标签: c embedded signal-processing microcontroller processor

我的"数字信号处理器简介"当然是使用C2000 Piccolo Launchpad教授数字信号处理器。

目前,我完全迷失了。 Coz,我的导师似乎没有兴趣为我们提供在家学习的任何材料。

例如,

以下代码来自Texas Instrument的controlSUITE包。

//########################################################################
//
//  File:   f2802x_examples/timed_led_blink/Example_F2802xLedBlink.c
//
//  Title:  F2802x LED Blink Getting Started Program.
//
//  Group:          C2000
//  Target Device:  TMS320F2802x
//
//! \addtogroup example_list
//!  <h1>LED Blink</h1>
//!
//!   This example configures CPU Timer0 for a 500 msec period, and toggles 
//!   the GPIO0-4 LEDs  once per interrupt. For testing purposes, this example
//!   also increments a counter each time the timer asserts an interrupt.
//!
//!   Watch Variables:
//!   - interruptCount
//!
//!   Monitor the GPIO0-4 LEDs blink on (for 500 msec) and off (for 500 msec) 
//!   on the 2802x0 control card.
//
//  (C) Copyright 2012, Texas Instruments, Inc.
//#############################################################################
// $TI Release: PACKAGE NAME $
// $Release Date: PACKAGE RELEASE DATE $
//#############################################################################

#include "DSP28x_Project.h"   // Device Headerfile and Examples Include File

#include "f2802x_common/include/adc.h"
#include "f2802x_common/include/clk.h"
#include "f2802x_common/include/flash.h"
#include "f2802x_common/include/gpio.h"
#include "f2802x_common/include/pie.h"
#include "f2802x_common/include/pll.h"
#include "f2802x_common/include/timer.h"
#include "f2802x_common/include/wdog.h"

// Prototype statements for functions found within this file.
__interrupt void cpu_timer0_isr(void);

uint16_t interruptCount = 0;

ADC_Handle myAdc;
CLK_Handle myClk;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
TIMER_Handle myTimer;

void main(void)
{

    CPU_Handle myCpu;
    PLL_Handle myPll;
    WDOG_Handle myWDog;

    // Initialize all the handles needed for this application    
    myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
    myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
    myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
    myTimer = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
    myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    // Perform basic system initialization    
    WDOG_disable(myWDog);
    CLK_enableAdcClock(myClk);
    (*Device_cal)();

    //Select the internal oscillator 1 as the clock source
    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

    // Setup the PLL for x10 /2 which will yield 50Mhz = 10Mhz * 10 / 2
    PLL_setup(myPll, PLL_Multiplier_10, PLL_DivideSelect_ClkIn_by_2);

    // Disable the PIE and all interrupts
    PIE_disable(myPie);
    PIE_disableAllInts(myPie);
    CPU_disableGlobalInts(myCpu);
    CPU_clearIntFlags(myCpu);

    // If running from flash copy RAM only functions to RAM   
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif      

    // Setup a debug vector table and enable the PIE
    PIE_setDebugIntVectorTable(myPie);
    PIE_enable(myPie);

    // Register interrupt handlers in the PIE vector table
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_7, (intVec_t)&cpu_timer0_isr);

    // Configure CPU-Timer 0 to interrupt every 500 milliseconds:
    // 60MHz CPU Freq, 50 millisecond Period (in uSeconds)
    //    ConfigCpuTimer(&CpuTimer0, 60, 500000);
    TIMER_stop(myTimer);
    TIMER_setPeriod(myTimer, 50 * 500000);
    TIMER_setPreScaler(myTimer, 0);
    TIMER_reload(myTimer);
    TIMER_setEmulationMode(myTimer, TIMER_EmulationMode_StopAfterNextDecrement);
    TIMER_enableInt(myTimer);

    TIMER_start(myTimer);    

    // Configure GPIO 0-3 as outputs
    GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_1, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_2, GPIO_0_Mode_GeneralPurpose);
    GPIO_setMode(myGpio, GPIO_Number_3, GPIO_0_Mode_GeneralPurpose);

    GPIO_setDirection(myGpio, GPIO_Number_0, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_1, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Output);
    GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Output);

    GPIO_setLow(myGpio, GPIO_Number_0);
    GPIO_setHigh(myGpio, GPIO_Number_1);
    GPIO_setLow(myGpio, GPIO_Number_2);
    GPIO_setHigh(myGpio, GPIO_Number_3);

    // Enable CPU INT1 which is connected to CPU-Timer 0:
    CPU_enableInt(myCpu, CPU_IntNumber_1);

    // Enable TINT0 in the PIE: Group 1 interrupt 7
    PIE_enableTimer0Int(myPie);

    // Enable global Interrupts and higher priority real-time debug events
    CPU_enableGlobalInts(myCpu);
    CPU_enableDebugInt(myCpu);

    for(;;){
        __asm(" NOP");
    }

}    

__interrupt void cpu_timer0_isr(void)
{
    interruptCount++;

    // Toggle GPIOs
    GPIO_toggle(myGpio, GPIO_Number_0);
    GPIO_toggle(myGpio, GPIO_Number_1);
    GPIO_toggle(myGpio, GPIO_Number_2);
    GPIO_toggle(myGpio, GPIO_Number_3);

    // Acknowledge this interrupt to receive more interrupts from group 1
    PIE_clearInt(myPie, PIE_GroupNumber_1);
} 

//===========================================================================
// No more.
//===========================================================================

我可以看到,这里有很多事情要发生。但是,我找不到学习C2000编码基础知识的地方。

我有一些基本问题:

(1)__interrupt__asm关键字的作用是什么?我在哪里可以找到这些关键字的参考?

(2)我怎么知道我需要多少手柄?例如,对于此LED闪烁应用程序,它们已声明9个句柄。为什么呢?

(3)什么是&#34;基地址&#34;?

(4)为什么禁用WachDog?为什么PIE和CPU及其中断被禁用?

(5)什么是计时器 - 预分类?

(6)什么是timer-emulation-mode?

(7)GPIO_setmode做什么?模式是什么?

(8)我在哪里可以开始学习所有这些细节?

这是一个好的材料开始还是浪费时间? http://www.ti.com/lit/ug/spru430f/spru430f.pdf

3 个答案:

答案 0 :(得分:1)

  1. __interrupt和__asm关键字有什么作用?我在哪里可以找到这些关键字的参考?
  2. __interrupt告诉编译器用适合平台的代码包装函数,通常用于保存和恢复函数使用的寄存器,以便中断的代码不受影响,并返回“从中断返回”指令而不是“从子程序返回”指令

    __asm告诉编译器在将编译器的输出发送到汇编器之前在编译器的输出中插入一个机器级指令

    1. 我怎么知道我需要多少把手?例如,对于此LED闪烁应用程序,它们已声明9个句柄。为什么?
    2. 因为代码使用了这9个硬件子系统,如TI库和头文件所定义的

      1. 什么是“基地址”?
      2. 在硬件中,有一组控制器可以控制硬件功能,例如I / O,定时器等。每组寄存器都分配一个存储器范围,从基址开始。可能有几个相同的组,例如几个计时器。通过为每个组使用基地址,可以在所有实例之间共享处理该功能的代码,例如计时器。

        1. 为什么禁用WachDog?为什么PIE和CPU及其中断被禁用?
        2. 我怀疑无论执行什么初始化都需要比看门狗间隔更长的时间,因此它被禁用以防止看门狗重置CPU

          1. 什么是计时器 - 预分类?
          2. 它是定时器源时钟的分频器,用于为定时器

            创建适当的分辨率和范围
            1. 什么是timer-emulation-mode?

              我不知道。也许这只是“模式”的奇怪名称。或者它可能是传统模式。

              1. GPIO_setmode做什么?什么是模式?
              2. GPIO硬件必须具有选项,例如,将中断附加到边沿,或改变转换速率或迟滞,或任何一种情况。

                1. 我在哪里可以开始学习所有这些细节?
                2. C2000 Piccolo参考手册 C2000 Piccolo数据表 编译器文档 controlSUITE包文档

答案 1 :(得分:1)

您提出的所有问题都与此代码编写的处理器的具体细节有关。因此,获得问题答案的最佳方法是查看C2000 Piccolo TMS320F28027 MCU的数据表。因为这是C2000 Piccolo Launchpad评估平台使用的微控制器。数据表可以通过以下链接直接从德州仪器的网页下载:http://www.ti.com/tool/launchxl-f28027

基于我对微控制器的一般了解,我将对您的一些问题提供一些简短的答案。我不保证这些信息是正确的,正如我之前所写,为了确保您必须阅读数据表。本文档还应该可以帮助您入门:http://www.ti.com/lit/ug/spruhh2a/spruhh2a.pdf

1: __interrupt关键字可能会将标记函数设置为指定中断的中断服务程序(ISR),请参阅https://en.wikipedia.org/wiki/Interrupt_handler

__asm关键字激活内联汇编,使您可以直接在C代码中编写处理器特定的汇编指令。

3: 基址可能是指存储器映射的i / o设备和控制寄存器的存储器地址。

4: 看门狗是一种定时器,您必须定期重置。如果不这样做,则表明您的程序可能被冻结,在这种情况下看门狗可以触发微控制器的软复位。中断可能只是因为这个演示应用程序不需要它们而被禁用。

8: 如果你只是google一点,网上有很多资源;) 我首先要阅读“技术文件”中列出的所有材料。在这里:http://www.ti.com/tool/launchxl-f28027

答案 2 :(得分:1)

1

__interrupt__asm是代码标记,用于表示中断函数cpu_timer0_isr(中断服务程序)和汇编程序代码。

2

这取决于您想要达到的目标,您需要从设备中读取什么。

3

...BASE_ADDR是存储器中读取/写入驱动器设备的地址。特别是ADC_BASE_ADDR defines模数转换器(ADC)寄存器的基址。

4

Watchdogs用于监控某些活动。在TMS320F2802x和TMS320F2802xx系列中

  

每个设备都包含两个看门狗:监视核心的CPU-Watchdog   和NMI-Watchdog是一个缺少时钟检测电路。用户   软件必须定期重置CPU内的看门狗计数器   一定的时间范围;否则,CPU监视器会产生复位   处理器。必要时可以禁用CPU监视器。该   NMI-Watchdog仅在发生时钟故障时才会启动,并且可以   产生中断或设备复位。

NMI代表不可屏蔽中断:

cat /proc/interrupts
在Linux上

在每个CPU上查看他们的计数器。

5

请阅读Doug's answer了解其余答案。