Перейти к содержанию
    

Вопрос по файлу компоновки F2812.cmd

В рабочем цикле происходит сравнение двух сигналов. Если один сигнал больше другого, то на выходе GPIOA0 = 0, GPIOA1 = 1; если меньше, то GPIOA0 = 1, GPIOA1 = 0. Сравнение происходит с введением коэффициентов усиления (множители с плавающей точкой) каждого сигнала. Переключение состояний порта - с учётом некоторого гистерезиса (с плавающей точкой).

 

 

#define Ki = -1.5, // Коэффициент усиления по току

#define Ku = 0.75, // Коэффициент усиления по напряжению

#define Kgist = 0.25, // Гистерезис в компараторе

 

char K = -1;

float CompA_in1, // 1-й вход компаратора

CompA_in2; // 2-й вход компаратора

unsigned int Ua_ADC,

Ia_ADC;

while(1)

{

Ua_ADC = AdcRegs.ADCRESULT0 >> 6; // АЦП работает постоянно, на максимальной частоте без прерываний. В рабочем

Ia_ADC = AdcRegs.ADCRESULT1 >> 6; // цикле текущие значения АЦП считываются в Ua_ADC и Ia_ADC.

 

CompA_in1 = Ki * Ia_ADC; // Приведение сигналов (масштабирование)

CompA_in2 = Ku * Ia_ADC; // перед подачей в компаратор.

 

switch(K) // Компаратор с гистерезисом

{ case (1):

{if (CompA_in1 > (CompA_in2 + Kgist)) K = -1;

GpioDataRegs.GPACLEAR.bit.GPIOA0 = 1;

GpioDataRegs.GPASET.bit.GPIOA1 = 1;

break;}

case (-1):

{if (CompA_in1 <= (CompA_in2 - Kgist)) K = 1;

GpioDataRegs.GPACLEAR.bit.GPIOA1 = 1;

GpioDataRegs.GPASET.bit.GPIOA0 = 1;

break;}

}

}

 

Решая задачу “в лоб”, как приведено выше, я столкнулся с проблемой очень низкой частоты рабочего цикла. Эта проблема, судя по всему, заключается в неправильном распределении кода в памяти. В связи с этим возникли следующие вопросы:

 

1. Каким образом в файле компоновки F2812.cmd распределить память (RAM и FLASH) между секциями, чтобы получить наибольшую скорость этого рабочего цикла?

2. В дальнейшем в этом проекте будут создаваться функции, содержащие математические вычисления (фильтры, регуляторы). Необходимо, чтобы эти функции работали в RAM. Каким образом их следует описывать в исходнике кода и в файле компоновки F2812.cmd?

 

Народ, подскажите, пожалуйста, как с этим бороться.

__________TMS320F2812.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По поводу быстродействия: применяйте фиксированную точку - будет быстрее по сравнению с плавающей точкой. По поводу пункта 2 смотрите pragma CODE_SECTION

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привет!

Ниже я привожу исодник командного файла TMS320F2812, внутри которого код запускается из внутренней флэши, однако критичные ко времени исполнения функции исполняются из ОЗУ (rt_OneStep).

MEMORY
{
PAGE 0:
    OTP: origin=0x3d7800, length=0x800
    BEGINRAM: origin=0x3f8000, length=0x2
    BEGINFLASH: origin=0x3f7ff6, length=0x2
    CSM_PWL: origin=0x3f7ff8, length=0x8
    RAMH0: origin=0x3f8002, length=0x1ffe
    BOOTROM: origin=0x3ff000, length=0xfc0
    RESET: origin=0x3fffc0, length=0x2
    VECTORS: origin=0x3fffc2, length=0x3e
    RAMM0M1: origin=0x0, length=0x800
    FLASH: origin=0x3d8000, length=0x1fff6
    ZONE6P: origin=0x100000, length=0x8000
PAGE 1:
    RAML0L1: origin=0x8000, length=0x2000
    ZONE6D: origin=0x108000, length=0x8000
}
SECTIONS
{
    .vectors: load = 0x000000000
    .text: > FLASH, PAGE = 0
    .switch: > FLASH, PAGE = 0
    .bss: > RAML0L1, PAGE = 1
    .ebss: > RAML0L1, PAGE = 1
    .far: > RAML0L1, PAGE = 1
    .cinit: > FLASH, PAGE = 0
    .pinit: > FLASH, PAGE = 0
    .const: > FLASH, PAGE = 0
    .econst: > FLASH, PAGE = 0
    .reset: > RESET, PAGE = 0, TYPE = DSECT
    .data: > FLASH, PAGE = 0
    .cio: > RAML0L1, PAGE = 1
    .sysmem: > RAML0L1, PAGE = 1
    .esysmem: > RAML0L1, PAGE = 1
    .stack: > RAML0L1, PAGE = 1
    .rtdx_text: > FLASH, PAGE = 0
    .rtdx_data: > FLASH, PAGE = 0
    codestart: > BEGINFLASH, PAGE = 0
    IQmath: > FLASH, PAGE = 0
    ramfuncs: LOAD = FLASH,
        RUN = RAMH0,
        LOAD_START(_RamfuncsLoadStart),
        LOAD_END(_RamfuncsLoadEnd),
        RUN_START(_RamfuncsRunStart),
        PAGE = 0
    IQmathTables: > BOOTROM, PAGE = 0, TYPE = NOLOAD
}
-l "C:\Program Files\MATLAB\R2009b\toolbox\idelink\extensions\ticcs\c2000\c281xPeripherals.cmd"

А теперь часть исходного текста программы. Его я генерил из Матлаба автоматически. Нужные строки, которые необходимо вставлять ручками:

1. #pragma CODE_SECTION(rt_OneStep, "ramfuncs");

2. MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

/*
* File: FeederProbeMskHard_main.c
*
* Real-Time Workshop code generated for Simulink model FeederProbeMskHard.
*
* Model version                        : 1.1147
* Real-Time Workshop file version      : 7.4  (R2009b)  29-Jun-2009
* Real-Time Workshop file generated on : Tue Jun 29 16:14:39 2010
* TLC version                          : 7.4 (Jul 14 2009)
* C/C++ source code generated on       : Tue Jun 29 16:14:40 2010
*
* Target selection: ccslink_ert.tlc
* Embedded hardware selection: Texas Instruments->C2000
* Code generation objectives: Unspecified
* Validation result: Not run
*/

#include "FeederProbeMskHard.h"
#include "rtwtypes.h"
#include "rt_nonfinite.h"
#include "FeederProbeMskHard_private.h"
#include "c2000_main.h"
#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include <stdlib.h>
#include <stdio.h>

void init_board(void);
void enable_interrupts(void);
void config_schedulerTimer(void);
void disable_interrupts(void);
void idletask_num1(void);
volatile int IsrOverrun = 0;
static boolean_T OverrunFlag = 0;

#pragma CODE_SECTION(rt_OneStep, "ramfuncs");
void rt_OneStep(void)
{
  // Check for overrun. Protect OverrunFlag against
  // pre-emption
  if (OverrunFlag++) {
    IsrOverrun = 1;
    OverrunFlag--;
    return;
  }

  asm(" SETC INTM");
  PieCtrlRegs.PIEIER1.all |= (1 << 6);
  asm(" CLRC INTM");
  FeederProbeMskHard_step();

  /* Get model outputs here */
  asm(" SETC INTM");
  PieCtrlRegs.PIEIER1.all &= ~(1 << 6);
  asm(" RPT #5 || NOP");
  IFR &= 0xFFFE;
  PieCtrlRegs.PIEACK.all = 0x1;
  asm(" CLRC INTM");
  OverrunFlag--;
}

//
// Entry point into the code
//
void main(void)
{
  volatile boolean_T noErr;

  MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

  init_board();
  rtmSetErrorStatus(FeederProbeMskHard_M, 0);
  FeederProbeMskHard_initialize(1);
  config_schedulerTimer();
  noErr =
    rtmGetErrorStatus(FeederProbeMskHard_M) == (NULL);
  enable_interrupts();
  while (noErr ) {
    idletask_num1();
    noErr =
      rtmGetErrorStatus(FeederProbeMskHard_M) == (NULL);
  }

  /* Disable rt_OneStep() here */

  /* Terminate model */
  FeederProbeMskHard_terminate();
  disable_interrupts();
}

/*
* File trailer for Real-Time Workshop generated code.
*
* [EOF]
*/

А математику с дробными числами я делал тупо в лоб через float'ы. Микроконтроллер смолотил это на раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...