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.

[参考译文] 编译器/MSP-EXP432P401R:我需要帮助更改代码

Guru**** 2595770 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/639723/compiler-msp-exp432p401r-i-need-to-help-for-doing-change-for-codes

部件号:MSP-EXP432P401R

工具/软件:TI C/C++编译器

实时FIR过滤,具有三重缓冲


#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h> //exact-width整数类型
#include <ti\devices\msp432p4xx\driverlib\driverlib.h>// 驱动程序库

#define clock_hf   4800万 //48MHz
#define clock_lf   3.2万 //32kHz

#define TIMER0_FREQ   1 //单位:Hz

#define sample_FREQ   8000//频率(以Hz为单位),数字音频的通用采样率:800.032万3200.0441万4410.048万00

#define MCP4921_SPI_bitrate   20e6 //needs to > sample_FREQ*16和< SMCLK/2,max 20M
#define MCP4921_SPI_DATA_MASK   0x0FFF //请参阅数据表MCP4921
#define MCP4921_SPI_CTRL_MASK   0x7000 //请参阅数据表MCP4921

#define red_LED   gPIO_PIN0
#define green_LED   gPIO_PIN1
#define blue_LED   GPIO

#define NUM_DISP_TEX_LINE   4.

//三重缓冲的定义。
#define NUM_DATA_BUFFER   3.
#define data_buffer_LEN   200

#define filter_LEN_M   28.


//函数原型
void initDevice_HFXT(void);
void initGPIO (void);
void initTimer(void);
void initUART(void);
void initADC14(void);
void initSPI(void);

void initDataBuffer(void);
void processData (void);

void uart0_searstr(const char *str);


//全局变量
uINT32_t clockMCLK,clockSMCLK;
uINT8_t当前LED =红色LED;

volatile UINT32_t dataBuffer[NUM_DATA_BUFFER][DATA_BUFFER_LEN];
volatile UINT32_t buf_inputIndex=0,buf_outputIndex=1,buf_dataIndex=2;
volatile buf_dataReady=false,buf_overrunError=false;

FLOAT FILTER_BCOef[FILTER_LEN_M+1]=

   0.0.14541062亿 ,0.0012749733 ,0.0009739225 ,0.0.00396414亿 ,0.0.24743259亿 ,
   0.0.70030369亿 ,0.0140943302 ,0.0238646359 ,0.3.59851042亿 ,0.4.9667346亿 ,
   0.6.37372145亿 ,0.0767880565 ,0.0873882711 ,0.9.43060927亿 ,0.9.67098938亿 ,
   0.9.43060927亿 ,0.0873882711 ,0.0767880565 ,0.6.37372145亿 ,0.4.9667346亿 ,
   0.3.59851042亿 ,0.0238646359 ,0.0140943302 ,0.0.70030369亿 ,0.0.24743259亿 ,
   0.0.00396414亿 ,0.0009739225 ,0.0012749733 ,0.0.14541062亿
};

const char *terminalDisplayText[NUM_DISP_TEFY_LINE]=

   "\r\n",
   "使用三重缓冲进行实时FIR过滤\r\n ",
   "R:红色,G:绿色,B:蓝色,H:帮助\r\n",
   ">"
};


Void主(void)

   uINT32_t i;
   UINT8_t数据;

   initDevice_HFXT();
   initGPIO ();
   initTimer();
   initUART();
   initADC14();
   initSPI();

   initDataBuffer();

   interrup_enableMaster();
   Timer32_startTimer(TIMER32_0_base, false);
   Timer32_startTimer(TIMER32_1_base, false);

   //终端上的初始显示。
   for (i=0;i<NUM_DISP_TEXT_LINE;i++)
   {
       uart0_terminalDisplayText[I];
   }

   同时(1)
   {
       IF (UART_getInterruptStatus (EUSCI_A0_BASE,EUSCI_A_UART_receive中断标志)
       {
           数据= UART_receiveData(EUSI_A0_base);
           UART_clearInterruptFlag (EUSCI_A0_BASE,EUSCI_A_UART_receive中断标志);

           交换机(数据)
           {
               案例'R':
               案例'r':
                   currentLED = red_LED;
                   uart0_senderStr ("红色闪烁LED。\r\n>");
                   中断;

               案例'G':
               案例'g':
                   当前LED =绿色_LED;
                   uart0_sedrStr ("闪烁绿色LED。\r\n>");
                   中断;

               案例'B':
               案例'b':
                   currentLED = blue_LED;
                   uart0_sedrStr ("蓝色闪烁LED。\r\n>");
                   中断;

               案例'H':
               案例'h':
                   for (i=0;i<NUM_DISP_TEXT_LINE;i++)
                   {
                       uart0_terminalDisplayText[I];
                   }
                   中断;
           }
       }//IF结束

       IF (buf_overrunError)
       {
           //此错误表示processData()例程需要太多时间才能完成。
           //优化此例程以更快地运行或将buffer_LEN设置为更大。
           //uart0_sedrStr ("错误:缓冲区溢出!\r\n");
           printf ("错误:缓冲区溢出!\r\n");
           buf_overrunError =假;
       }

       IF (buf_dataReady)
       {
           processData();
           buf_dataReady =假;
       }

   }//while结束
}


void initDevice_HFXT(void)

   WDT_A_HoldTimer();// 停止监视程序计时器

   //将VCORE更改为1以支持高于24MHz的频率。
   //有关给定频率的闪存等待状态要求,请参见数据表。
   PCM_setPowerState (PCM_AM_DCDC_VCORE1);
   Flashctl_setWaitState(flash_BANK0, 1);
   Flashctl_setWaitState(flash_Bank1,1);

   FPU_enableModule();
   FPU_enableLazyStacking();//需要在ISR内使用FPU。

   //在HFXT模式下配置PJ.2和PJ.3。
   //初始化外部时钟源HFXT。
   GPIO_setAsPeripheralModuleFunctionOutputPin (GPIO端口PJ,GPIO PIN2|GPIO _PIN3,GPIO主要模块功能);
   cs_setExternalClockSourceFrequency(clock_lf,Clock_hF);
   cs_startHFXT (FALSE);

   cs_initClockSignal (CS_MCLK,CS_HFXTCLK_SELECT,CS_Clock_diver_1);
   cs_initClockSignal (CS_HSMCLK,CS_HFXTCLK_SELECT,CS_Clock_diver_16);
   cs_initClockSignal (CS_SMCLK,CS_HFXTCLK_SELECT,CS_Clock_diver_1);//48MHz支持SPI

   clockMCLK = CS_getMCLK();
   clockSMCLK = CS_getSMCLK();
}


void initGPIO (void)

   //将WFP 2.0 ,WFP 2.1 ,2.2 配置为输出。
   //WFP,2.0 2.1 ,WFP,2.2 与LaunchPad上的RGB三色LED相连。
   GPIO _setAsOutputPin (GPIO端口P2,GPIO _PIN0|GPIO _PIN1|GPIO _PIN2);
}


void initTimer(void)

   // TIMER32_0闪烁心跳LED
   Timer32_initModule (TIMER32_0_BASE,TIMER32_prescaler_1,TIMER32_32bit,TIMER32_Periodic_mode);
   Timer32_setCount (TIMER32_0_BASE,clockMCLK/TIMER0_FREQ - 1);
   Timer32_enableInterrupt (TIMER32_0_BASE);
   InterrupT_enableInterrupt (INT_T32_INT1);//在中断控制器中启用Timer32_0中断。

   // TIMER32_1执行输入/ADC和输出/DAC
   Timer32_initModule (TIMER32_1_BASE,TIMER32_prescaler_1,TIMER32_32bit,TIMER32_Periodic_mode);
   Timer32_setCount (TIMER32_1_BASE,clockMCLK/sample_FREQ -1);
   Timer32_enableInterrupt (TIMER32_1_BASE);
   InterrupT_enableInterrupt (INT_T32_INT2);//在中断控制器中启用Timer32_1中断。
}


void initUART (void)

   //配置为48MHz SMCLK,11.52万波特率。
   //使用TI提供的在线计算器计算得出:
   software-dl.ti.com/.../index.html
   CONST eUSI_UART_Config =
   {
       EUSCI_A_UART_CLOCKSOURCE_SMCLK,//SMCLK时钟源,48MHz
       26,//BRDIV
       0,//UCxBRF
       111,//UCXBRS
       EUSCI_A_UART_NO_PARity,//无奇偶校验
       EUSCI_A_UART_LSB_FIRST,//MSB FIRST
       EUSCI_A_UART_ONE_STOP_BIT,//一个停止位
       EUSCI_A_UART_MODE,//UART模式
       EUSCI_A_UART_oversampling_BAUDRATE_generation //Oversampling
   };

   //为UART配置GPIO引脚。 美国国家公园(1.2),德克萨斯州:美国国家公园(1.3)。
   GPIO _setAsPeripheralModuleFunctionInputPin (GPIO_PORT_P1, GPIO _PIN2|GPIO _PIN3,GPIO主要模块功能);

   UART_INITModule (EUSCI_A0_BASE,&config);
   UART_enableModule (EUSCI_A0_BASE);
}


//使用WFP 6.1 / A14进行采样
void initADC14(void)

   ADC14_enableModule();
   ADC14_INITModule (ADC_CLOCKSOURCE_SMCLK,ADC_PREDIVIDER_1,ADC_DIVIDER_1,ADC_NOROUTE);

   //将WFP 6.1 配置为A14
   GPIO _setAsPeripheralModuleFunctionInputPin (GPIO_PORT_P6,GPIO _PIN1,GPIO第三模块功能);

   ADC14_setResolution (ADC_12位);
   ADC14_configureSingleSampleMode (ADC_MEM0,TRUE);//repeatMode = TRUE
   ADC14_configureConversionMemory (ADC_MEM0,ADC_VREFPOS_AVCC_VREFNEG_VSS,ADC_INPUT_A14,FALSE);

   //请参阅技术参考第20.2 章节6了解样例正时注意事项。
   ADC14_enableSampleTimer(ADC_MANUAL_ITED);
   ADC14_setSampleHoldTime (ADC_PULSE_WIDES_4,ADC_PULSE_WIDES_4);

   ADC14_enableConversion();
}


void initSPI(void)

   Const eUSI_SPI_MasterConfig spiMasterConfig =
   {
       EUSCI_B_SPI_CLOCKSOURCE_SMCLK,            //SMCLK时钟源
       clockSMCLK,                               //时钟源频率
       MCP4921_SPI_bitrate,                      //desedSpiClock
       EUSCI_B_SPI_MSB_FIRST,                    //MSB FIRST
       EUSCI_B_SPI_PHASE DATA_Changed_ONFIRST_Captured_on_NEXT   ,//相位
       EUSCI_B_SPI_CLOCKPOLARITY_INACILY_LOW, //极性低
       EUSCI_B_SPI_3pin                          //3Wire SPI模式
   };

   //WFP 1.5 :SCK, WFP 1.6 :SDI,WFP 5.2 :CS
   GPIO _setAsPeripheralModuleFunctionInputPin (GPIO_PORT_P1, GPIO _PIN5|GPIO _PIN6,GPIO主要模块功能);
   GPIO _setAsOutputPin (GPIO端口P5,GPIO _PIN2);
   GPIO _setOutputHighOnPin (GPIO端口P5,GPIO _PIN2);

   //在3Wire主模式下配置SPI
   SPI_initMaster(EUSI_B0_BASE,&spiMasterConfig);

   //启用SPI模块
   SPI_enableModule(EUSI_B0_BASE;
}


void initDataBuffer(void)

   uINT32_t i,j;

   for (i=0;i<NUM_DATA_BUFFER;i++)
   {
       对于(j=0;j<数据缓冲器_LEN;j++)
       {
           dataBuffer[I][j]= 0;
       }
   }
}


void processData (void)

   静态浮点数据[DATA_BUFFER_LEN + FILTER_LEN_M]={0};//增强数据帧,初始化为0
   浮子y;
   uINT32_t *pBuf =(UINT32_t *) dataBuffer[buf_dataIndex];
   uINT32_t i,j,k;

   //将数据从数据帧复制到增强数据帧。
   //开始填充ATer FILTER_LEN_M元素。
   对于(i=0,j=filter_LEN_M;i<data_buffer_LEN;i++,j++)
   {
       data[j]=(浮点) pBuf[i];
   }

   // FIR过滤:y[n]= sum_{i=0}^{M}(B[i]x[n-I])。
   对于(i=0;i<data_buffer_LEN;i++)
   {
       Y = 0;
       用于(j=0,k=i;j<=filter_LEN_M;j++,k++)
       {
           y += FILTER_BCOef[j]*DATA[k];
       }
       pBuf[i]=(UINT32_t) y;
   }

   //将最后一个FILTER_LEN_M样本数保存到增强数据帧的开头。
   对于(i=0;i<filter_LEN_M;i++)
   {
       data[i]= data[data_buffer_LEN+i];
   }
}


//通过UART0传输字符串。
void uart0_searstr(const char *str)

   uINT32_t长度,i=0;

   len = strlen (str);
   同时(我< len)
   {
       UART_HESRData (EUSCI_A0_BASE,STR[I++]);
       while (!UART_getInterruptStatus (EUSCI_A0_BASE,EUSCI_A_UART_Transmit_Complete_InterrupT_flag));
       UART_clearInterruptFlag (EUSCI_A0_BASE,EUSCI_A_UART_Transmit_Complete_InterrupT_flag);
   }
}


//Timer32_0 ISR
void T32_INT1_IRQHandler (void)

   Timer32_clearInterruptFlag (TIMER32_0_BASE);

   IF (GPIO _getInputPinValue (GPIO端口P2,GPIO _PIN0|GPIO _PIN1|GPIO _PIN2))
   {
       GPIO _setOutputLowOnPin (GPIO端口P2,GPIO _PIN0|GPIO _PIN1|GPIO _PIN2);
   }
   否则
   {
       GPIO_setOutputHighOnPin (GPIO端口P2,当前LED);
   }
}


//Timer32_1 ISR
void T32_INT2_IRQHandler (void)

   静态UINT32_t样本索引=0;
   uINT32_t tmpIndex;
   UINT16_t数据;
   uINT8_t字节1,字节0;

   Timer32_clearInterruptFlag (TIMER32_1_BASE);

   //从ADC读取。
   ADC14_toggleConversionTrigger();

   while (!(ADC_INT0 & ADC14_getInterruptStatus());
   ADC14_clearInterruptFlag(ADC_INT0);

   dataBuffer[buf_inputIndex][sampleIndex]= ADC14_getResult(ADC_MEM0);

   //为SPI准备数据。
   数据= MCP4921_SPI_CTRL_MASK |(MCP4921_SPI_DATA_MASK & dataBuffer[buf_outputIndex][sampleIndex]);
   字节1 =(uint8_t)(data>>8);
   byte0 =(uint8_t)数据;

   //SPI使用寄存器级操作编写,以支持16位操作。
   p5->out &=~BIT2;//在SPI从属设备上将CS设置为LOW。

   EUSCI_B0->TXBUF =字节1;//传输字节1
   EUSCI_B0->TXBUF =字节0;//传输字节0

   while (!(EUSSCI_B0->IFG & EUSCI_B_IFG_TXIFG));//检查TX缓冲区是否就绪。
   p5->out || BIT2;//在SPI从属设备上将CS设置为HIGH。

   //更新缓冲区索引和样本索引。
   IF (++sampleIndex >= DATA_BUFFER_LEN)
   {
       样本索引=0;
       IF (buf_dataReady)
       {
           buf_overrunError =真;
       }

       tmpIndex = buf_inputIndex;
       buf_inputIndex = buf_outputIndex;
       buf_outputIndex = buf_dataIndex;
       buf_dataIndex = tmpIndex;
       buf_dataReady =真;
   }
}

问题2. 如何使用Matlab执行FIR滤波器设计。
 1•在Matlab中,使用“filterDesigner”设计低通FIR等波滤波器,顺序为50=M,采样频率为kHz 8=SF,带式切断频率为Hz 1500=passF,带式切断频率为Hz 2000=stopF,带式和带式的重量均为1。  将设计的过滤器作为系数变量导出到Matlab工作区,并使用Matlab函数“plot”绘制其时间域单位样本响应,并使用Matlab函数“freqz”绘制其频率响应。  
 
2•创建新的CCS项目“Lab9_2”。  将示例代码“Lab9_1_main.c”添加到项目中。 •本实验的输入和输出设置与问题1完全相同。
 
3•将“Lab9_1_main.c”中使用的过滤器替换为刚刚设计的新FIR过滤器。  “Lab9_1_main.c”中的某些参数/变量值需要根据新过滤器的规范进行更改。 •使用问题1中的测试信号重复滤波实验步骤,以测试新FIR滤波器设计的实施情况。 •在报告中解释您的代码和实验结果。
 
 
问题3. 使用Ping Pong缓冲进行实时FIR过滤。
 
•创建新的CCS项目“Lab9_3”。 •本实验的输入和输出设置与问题1完全相同。 •使用Ping-Pong缓冲技术实现与Lab9_2中相同的实时FIR过滤功能。   •在您的报告中解释基于Ping Pong缓冲的FIR过滤是如何工作的。 •在报告中解释您自己的代码。