DSP学习笔记(1)——F28335基础知识

本文详细介绍了一位初学者从零开始学习数字信号处理(DSP)的过程,涵盖了DSP的基础知识、开发环境搭建、TMS320F28335芯片特性、时钟与看门狗配置等核心内容。适合对DSP感兴趣的新手阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

❤ 2019.3.6

    今天开始学习DSP,over。

    我用的版本是德州仪器的TMS320F28335,用的开发板是研旭的TMS320F28335至尊开发板,到底有多至尊我也不知道,不过看起来教材和资料挺全的。

 

〇 基础知识

● DSP的历史

    略(自己看书百度去)

 

● 数字信号处理特点

 

● DSP主要特点

 

● TI的芯片系列

F28335系列属于C2000系列,在TI看来不属于DSP,属于MCU,但是我们就当成DSP学(?)

 

● C2000系列简介

 

● DSP系统开发

 

● 如何成为一个优秀的DSP工程师

(真的假的?)

 

● 教程总纲

 

 

〇 DSP开发环境介绍

● CCS介绍

● CCS安装

(略)

● 仿真器

○ CCS6如何连接仿真器(这个手册上面有)

1、建立target configuration file

2、输入名字

3、选择仿真器、芯片,然后点save

♣ 经常会在工程文件里生成一个target configuration 文件

 

❤ 2019.3.22

〇 DSP开发流程

 

 

 

○ CMD文件(配置文件)

    指定DSP内部的硬件存储器的一些相关地址以及长度。

    包含两部分:MEMORY以及SECTIONS

    MEMORY:指定DSP内部的ram和flash的首地址以及长度

    SECTIONS:指定程序组成部分对应内存的储存部分(MEMORY中设定的部分)。

 

〇 TMS320F28335介绍

 

 

〇 时钟与看门狗

 

● 内部时钟

 

❤ 2019.3.23

 

● 外设时钟

 

● 看门狗

 

● 时钟及看门狗寄存器(英文版System Control and Interrupts Reference Guide P34)(中文版见《手把手》P83)

♣ System Control and Interrupts Reference Guide:官方下载地址

 

● 关于看门狗及时钟的初始化例子

    打开官方例程的时钟配置文件

    观察系统时钟初始化函数

//---------------------------------------------------------------------------
// InitSysCtrl:
//---------------------------------------------------------------------------
// This function initializes the System Control registers to a known state.
// - Disables the watchdog
// - Set the PLLCR for proper SYSCLKOUT frequency
// - Set the pre-scaler for the high and low frequency peripheral clocks
// - Enable the clocks to the peripherals

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();
}

○    第一个

//---------------------------------------------------------------------------
// Example: DisableDog:
//---------------------------------------------------------------------------
// This function disables the watchdog timer.

void DisableDog(void)
{
    EALLOW;
    SysCtrlRegs.WDCR= 0x0068;
    EDIS;
}

    可以看到0x0068,转换成二进制就是0000 0000 0110 1000,查看watchdog的寄存器说明(英文版System Control and Interrupts Reference Guide P54)(中文版见《手把手》P88),可以知道其意义。

    如果需要启用watchdog,则用这个函数:

//---------------------------------------------------------------------------
// Example: ServiceDog:
//---------------------------------------------------------------------------
// This function resets the watchdog timer.
// Enable this function for using ServiceDog in the application

void ServiceDog(void)
{
    EALLOW;
    SysCtrlRegs.WDKEY = 0x0055;
    SysCtrlRegs.WDKEY = 0x00AA;
    EDIS;
}

查看相应寄存器:

    可以知道需要启用watchdog的话需要先后写入这两个值。

 

○    下面是锁相环初始化

    首先看一下两个参数

/*-----------------------------------------------------------------------------
      Specify the PLL control register (PLLCR) and divide select (DIVSEL) value.
-----------------------------------------------------------------------------*/
//#define DSP28_DIVSEL   0   // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL   1 // Disable /4 for SYSCKOUT
#define DSP28_DIVSEL     2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL     3 // Enable /1 for SYSCLKOUT

#define DSP28_PLLCR   10
//#define DSP28_PLLCR    9
//#define DSP28_PLLCR    8
//#define DSP28_PLLCR    7
//#define DSP28_PLLCR    6
//#define DSP28_PLLCR    5
//#define DSP28_PLLCR    4
//#define DSP28_PLLCR    3
//#define DSP28_PLLCR    2
//#define DSP28_PLLCR    1
//#define DSP28_PLLCR    0  // PLL is bypassed in this mode
//----------------------------------------------------------------------------

     可以看出DSP28_PLLCR是倍频,DSP28_DIVSEL是分频,然后在看一下倍频与分频设置函数:

//---------------------------------------------------------------------------
// Example: InitPll:
//---------------------------------------------------------------------------
// This function initializes the PLLCR register.

void InitPll(Uint16 val, Uint16 divsel)
{

   // Make sure the PLL is not running in limp mode
   if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
   {
      // Missing external clock has been detected
      // Replace this line with a call to an appropriate
      // SystemShutdown(); function.
      asm("        ESTOP0");
   }

   // DIVSEL MUST be 0 before PLLCR can be changed from
   // 0x0000. It is set to 0 by an external reset XRSn
   // This puts us in 1/4
   if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
   {
       EALLOW;
       SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
       EDIS;
   }

   // Change the PLLCR
   if (SysCtrlRegs.PLLCR.bit.DIV != val)
   {

      EALLOW;
      // Before setting PLLCR turn off missing clock detect logic
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
      SysCtrlRegs.PLLCR.bit.DIV = val;
      EDIS;

      // Optional: Wait for PLL to lock.
      // During this time the CPU will switch to OSCCLK/2 until
      // the PLL is stable.  Once the PLL is stable the CPU will
      // switch to the new PLL value.
      //
      // This time-to-lock is monitored by a PLL lock counter.
      //
      // Code is not required to sit and wait for the PLL to lock.
      // However, if the code does anything that is timing critical,
      // and requires the correct clock be locked, then it is best to
      // wait until this switching has completed.

      // Wait for the PLL lock bit to be set.

      // The watchdog should be disabled before this loop, or fed within
      // the loop via ServiceDog().

	  // Uncomment to disable the watchdog
      DisableDog();

      while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
      {
	      // Uncomment to service the watchdog
          // ServiceDog();
      }

      EALLOW;
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
      EDIS;
    }

    // If switching to 1/2
	if((divsel == 1)||(divsel == 2))
	{
		EALLOW;
	    SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
	    EDIS;
	}

	// If switching to 1/1
	// * First go to 1/2 and let the power settle
	//   The time required will depend on the system, this is only an example
	// * Then switch to 1/1
	if(divsel == 3)
	{
		EALLOW;
	    SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
	    DELAY_US(50L);
	    SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
	    EDIS;
    }
}

    有点乱,看不懂,但是ti贴心的(真的么?)画了个流程图:

    这个流程图配合寄存器说明来看

    稍微有点混乱,不过不需要看明白,反正用默认的就行,也就是10倍频,2分频,配合30M晶振,最后得到系统频率150M。

 

○    初始化外设时钟

    函数代码:

//--------------------------------------------------------------------------
// Example: InitPeripheralClocks:
//---------------------------------------------------------------------------
// This function initializes the clocks to the peripheral modules.
// First the high and low clock prescalers are set
// Second the clocks are enabled to each peripheral.
// To reduce power, leave clocks to unused peripherals disabled
//
// Note: If a peripherals clock is not enabled then you cannot
// read or write to the registers for that peripheral

void InitPeripheralClocks(void)
{
   EALLOW;

// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
   SysCtrlRegs.HISPCP.all = 0x0001;
   SysCtrlRegs.LOSPCP.all = 0x0002;

// XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
   // XTIMCLK = SYSCLKOUT/2
   XintfRegs.XINTCNF2.bit.XTIMCLK = 1;
   // XCLKOUT = XTIMCLK/2
   XintfRegs.XINTCNF2.bit.CLKMODE = 1;
   // Enable XCLKOUT
   XintfRegs.XINTCNF2.bit.CLKOFF = 0;

// Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2833x derivates.
// Refer to the datasheet for your particular device.
//
// This function is not written to be an example of efficient code.

   SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC

   // *IMPORTANT*
   // The ADC_cal function, which  copies the ADC calibration values from TI reserved
   // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
   // Boot ROM. If the boot ROM code is bypassed during the debug process, the
   // following function MUST be called for the ADC to function according
   // to specification. The clocks to the ADC MUST be enabled before calling this
   // function.
   // See the device data manual and/or the ADC Reference
   // Manual for more information.

   ADC_cal();


   SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2C
   SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-A
   SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1;   // SCI-B
   SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 1;   // SCI-C
   SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-A
   SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1; // McBSP-A
   SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 1; // McBSP-B
   SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;    // eCAN-A
   SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1;    // eCAN-B

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the ePWM
   SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // ePWM1
   SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;  // ePWM2
   SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;  // ePWM3
   SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;  // ePWM4
   SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1;  // ePWM5
   SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1;  // ePWM6
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;   // Enable TBCLK within the ePWM

   SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1;  // eCAP3
   SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1;  // eCAP4
   SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1;  // eCAP5
   SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1;  // eCAP6
   SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;  // eCAP1
   SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1;  // eCAP2
   SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1
   SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1;  // eQEP2

   SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
   SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
   SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2

   SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA Clock
   SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;     // XTIMCLK
   SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // GPIO input clock

   EDIS;
}

♣ 首先注意的是EALLOW和EDIS语句,关于这两个语句,我找到了一篇介绍:

    原文地址:DSP的EALLOW和EDIS指令

 

    先看这段:

    我们先找到对应的寄存器说明:

    由上可知,这两句的意思是将高速时钟配置为2分频,将低速时钟配置为4分频。

 

这个是用来控制时钟输出的,可以将时钟供给其他模块,可以省一个晶振(?)

 

这个是用来控制外设时钟的开关,需要哪个模块就开哪个时钟,不用就关上,可以省电。

 

 

 

 

<think>好的,我现在需要处理用户关于DSP_F28335实验一的查询,特别是关于CCS软件的认识、数据记录及结果部分。首先,我得回忆一下DSP实验的基本内容和CCS软件的使用流程。用户可能刚接触这个实验,需要详细的步骤解释和注意事项。 首先,DSP_F28335是德州仪器的C2000系列中的一款常用芯片,用于数字信号处理和控制应用。实验一通常是入门实验,让学习者熟悉开发环境CCS(Code Composer Studio)。所以用户的问题可能集中在如何配置CCS、创建项目、编写代码、调试以及记录数据等方面。 接下来,我需要考虑用户可能遇到的问题。比如,如何安装CCS,配置目标芯片型号,建立新项目,编写代码,编译下载,调试技巧,数据记录方法,结果分析等。用户可能需要知道具体的操作步骤,例如如何设置断点、观察变量,使用Graph工具查看波形,或者导出数据到文件。 然后,关于数据记录和结果部分,用户可能需要了解如何利用CCS内置的工具,如Memory Browser或Graph功能来捕获数据,保存到PC,并用Excel或MATLAB分析。常见的实验结果可能包括ADC采样波形、PWM输出、FFT分析等,需要解释这些结果的意义。 另外,用户可能遇到编译错误、连接问题、程序无法运行等情况,需要给出一些常见问题的解决方法。比如检查头文件路径、库文件是否正确添加,仿真器连接是否正常等。 我还需要确保回答结构清晰,分步骤说明,每个部分有子点,便于用户跟随。同时,按照系统级指令,数学公式要用$...$格式,但在这个问题中可能涉及较少,不过如果有涉及变量或方程的地方需要注意格式。 最后,要确保使用中文,避免专业术语使用错误,同时保持口语化,让内容更易理解。可能还需要提醒用户注意实验中的安全事项,比如正确连接硬件,避免短路等。 总结一下,回答的结构应该是先介绍CCS软件,然后分步骤讲解实验操作,接着说明数据记录方法,最后分析实验结果和常见问题。确保每个部分都有足够的细节,帮助用户顺利完成实验。</think>### DSP_F28335实验一:CCS软件认识、数据记录及结果分析 #### 一、CCS软件基本认识 **1. CCS简介** Code Composer Studio(CCS)是德州仪器(TI)推出的集成开发环境,用于开发DSP、MCU等嵌入式系统。支持代码编写、编译、调试及性能分析。 **2. 核心功能** - **项目管理**:支持C/C++/汇编语言,需配置芯片型号(如TMS320F28335)。 - **调试工具**:断点、单步执行、寄存器/内存查看。 - **图形化分析**:实时显示波形、频谱(如使用Graph工具)。 - **数据导出**:通过Memory Browser或Probe Point导出变量数据。 --- #### 二、实验操作步骤 **1. 环境搭建** - 安装CCS(版本需兼容F28335),配置芯片支持库(C2000ware)。 - 连接仿真器(XDS100/510)与开发板,确保驱动正常。 **2. 创建工程** - **新建项目**:File → New → CCS Project,选择F28335芯片。 - **添加文件**:导入主程序(.c)、头文件(.h)及链接脚本(.cmd)。 - **配置编译选项**:设置Include Path和预定义宏(如`_DEBUG`)。 **3. 代码编写示例** ```c #include "F2833x_Device.h" void main(void) { InitSysCtrl(); // 初始化系统时钟 DINT; // 禁用全局中断 InitPieCtrl(); // 初始化PIE控制 // ... 其他初始化代码 while(1) { // 主循环代码(如ADC采样、PWM输出) } } ``` **4. 编译与下载** - 点击Build按钮(🔨图标),修复语法错误。 - 使用Debug按钮(🐞图标)下载程序到DSP。 **5. 调试与数据捕获** - **断点设置**:双击代码行左侧添加断点。 - **实时监测**: - View → Expressions:添加变量(如`AdcResult`)。 - Tools → Graph → Single Time:绘制波形。 - **导出数据**: - Memory Browser中右键保存内存数据为.dat文件。 - 使用MATLAB/Python脚本处理数据: ```matlab data = load('adc_data.dat'); plot(data); ``` --- #### 三、数据记录方法 **1. 关键数据类型** - **ADC采样值**:记录电压信号(如传感器输入)。 - **PWM占空比**:验证控制算法输出。 - **算法中间变量**:例如PID误差、FFT频谱幅值。 **2. 记录工具** - **CCS内置工具**: - Graph显示波形(设置采样率、数据长度)。 - Memory Save功能导出数组。 - **外部仪器**:示波器捕获PWM/GPIO信号,与CCS数据对比。 **3. 数据整理建议** - 按时间戳命名文件(如`20240520_ADC.csv`)。 - 表格记录关键参数(如下表): | 采样点 | ADC值(Hex) | 电压(V) | 备注 | |--------|--------------|-----------|--------------| | 1 | 0x0FFA | 3.3 | 满量程输入 | | 2 | 0x07FD | 1.65 | 半量程输入 | --- #### 四、结果分析要点 **1. 预期 vs 实际输出** - **ADC采样验证**:输入已知电压(如1.0V),检查ADC值是否符合公式: $$ \text{ADC值} = \frac{V_{\text{in}}}{3.3\text{V}} \times 4095 $$ - **PWM波形测试**:用示波器测量占空比是否与代码设定一致(如50%对应1.65V)。 **2. 常见问题排查** - **程序卡死**:检查看门狗是否禁用(`DisableDog()`)。 - **数据异常**:确认时钟配置(PLL、分频系数)是否正确。 - **仿真器连接失败**:重启CCS,重新插拔USB接口。 --- #### 五、实验报告要求 1. **实验目的**:掌握CCS开发流程及数据记录方法。 2. **实验数据**:附波形截图、数据表格及导出文件。 3. **结果分析**:对比理论值与实测值,误差分析(如ADC量化误差)。 4. **思考题**: - CCS调试中如何快速定位数组越界问题? - 如何优化数据导出的实时性? --- **提示**:实验前务必阅读《TMS320F2833x Technical Reference Manual》,重点关注时钟、外设配置章节(如第3章、第13章)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值