1. Tuyển Mod quản lý diễn đàn. Các thành viên xem chi tiết tại đây

Cho Minh Hoi Ve Dsp Tms320f2812 !

Chủ đề trong 'Điện - Điện tử - Viễn thông' bởi TNT2611, 15/07/2007.

  1. 0 người đang xem box này (Thành viên: 0, Khách: 0)
  1. TNT2611

    TNT2611 Thành viên mới

    Tham gia ngày:
    15/07/2007
    Bài viết:
    1
    Đã được thích:
    0
    Chao tat ca moi nguoi tren dien dan !
    Hien nay toi dan su dung DSP TMS320F2812 va ACPM750 cua hang TI de dieu khien dong co BLDC. Nhung hien nay toi dang bi bi trong van de doc du lieu ADC tu DSP len may tinh va doc toc do cua dong co. Toi gui cho cac ban code cua toi, rat mong cac ban co the gop y giup toi.
    Thank !
    Thanh vien moi.
    ______________________________

    #include "IQmathLib.h"
    #include "LF2812_Regs.h"
    #include "RegDef.h"
    #include "logger.h"
    #include "refer.h"
    #include "parameter.h"

    #include "f2812ileg.h"
    #include "f2812qep.h"
    #include "f2812pwm.h"
    #include "clarke.h"
    #include "park.h"
    #include "ipark.h"
    #include "limit_voltage.h"
    #include "svgen_dq.h"
    #include "speed.h"
    #include "pid_reg3.h"
    #include "CURRENT_CONTROLLER.h"
    #include "STATE_FDB_CONTROLLER.h"
    #include "SPEED_CONTROLLER.h"
    /*-----------------------------------------------------------------------------
    Monitor declaration
    -----------------------------------------------------------------------------*/
    #define callmon2812 (int(*)(void)) 0x003f4000 // monitor''s command interpreter
    Uint16 stop; // stop index (1 = stop)
    Uint16 ret_val_mon; // value returned by the monitor

    /*-----------------------------------------------------------------------------
    Global Functions and Interrupts
    -----------------------------------------------------------------------------*/
    void initBlock(); // init all blocks
    void initPeripheral(); // init peripherals
    interrupt void MainISR(void); // Timer 1 period interrupt service routine
    interrupt void ReadADC(void); // Timer 1 period interrupt service routine

    // Define the ISR frequency (kHz) FOR PID ONLY***

    #define ISR_FREQUENCY 20

    //float32 T = 0.001/ISR_FREQUENCY;

    Uint16 SpeedLoopPrescaler = 10; // Speed loop prescaler
    Uint16 SpeedLoopCount = 1; // Speed loop counter

    // end PID parameter
    // bien dung trong chg trinh tao d/ap

    Uint16 f; // tan so dien ap
    _iq15 Tck; // chu ky dien ap

    Uint16 err;// bien chay dung de reset den error

    _iq15 Speed_ref; // toc do dat

    Uint16 intcount,watchUs,watchVs;
    Uint16 watchIu,watchIv,watch ; // IuRaw,IvRaw,IwRaw;
    _iq15 tgu,tgv;
    Uint16 countu =0, counts = 0;
    _iq15 w,t,wt;
    int16 watchSpeed,watchSpeedRpm,watchElec;
    Uint16 LoopSpeed=1000;
    _iq15 count=_IQ15(0), watch15;
    _iq15 countCMPR=_IQ15(0);

    #pragma DATA_SECTION(intcount,"DemoFile");
    #pragma DATA_SECTION(count,"DemoFile");
    #pragma DATA_SECTION(w,"DemoFile");
    #pragma DATA_SECTION(t,"DemoFile");
    #pragma DATA_SECTION(wt,"DemoFile");
    #pragma DATA_SECTION(clarke1,"DemoFile");
    #pragma DATA_SECTION(svgen_dq1,"DemoFile");
    #pragma DATA_SECTION(pwm1,"DemoFile");
    #pragma DATA_SECTION(ileg2_1,"DemoFile");

    /************************************************** **************
    MAIN PROGRAM
    ************************************************** **************/

    void main(void)
    {
    stop = 0;
    ret_val_mon = 1;
    init_logger();
    init_reference();

    // Init all the blocks
    initBlock();

    // Init peripheral of DSP2812
    initPeripheral();

    // Stay in loop forever

    while (!stop)
    {
    // call monitor

    ret_val_mon = (*callmon2812)();
    }

    // Generate system reset

    DINT;
    EALLOW;
    SysCtrlRegs.SCSR.bit.WDOVERRIDE =1; // Set WDOVERRIDE bit to allow the Watchdog enable
    SysCtrlRegs.WDCR = 0x000F; // Enable Watchdog and write incorrect WD Check Bits
    // (001 in lieu of 101) to force a system reset
    }

    /************************************************** **************
    END MAIN
    ************************************************** **************/


    //================================================== =====
    // Main IRS: Timer 1 under flow interrupt service routine
    //================================================== =====

    interrupt void MainISR(void)
    {
    // ------------------------------------------------------------------------------
    // Doc gia tri toc do sau moi 1000 lan ngat (tuc 0,1s=100ms=1000*100us)
    // ------------------------------------------------------------------------------

    if (LoopSpeed==0)
    {
    LoopSpeed=1000;
    F281X_EV1_QEP_Calc(&qep1);

    // Khoi SPEED

    speed1.ElecTheta=qep1.ElecTheta;
    speed1.DirectionQep=qep1.DirectionQep;
    speed_frq_calc(&speed1);
    }
    else LoopSpeed=LoopSpeed-1;



    // ------------------------------------------------------------------------------
    // Call the ILEG2 read function.
    // ------------------------------------------------------------------------------

    tgu=_IQ15div(ileg2_1.IuRaw,_IQ15(1365));
    tgv=_IQ15div(ileg2_1.IvRaw,_IQ15(1365));

    tgu=_IQ15div((_IQ15(1.5)-tgu),_IQ15(0.235));
    tgv=_IQ15div((_IQ15(1.5)-tgv),_IQ15(0.235));


    // Take the meased values of current from ADC

    ileg2_1.IuMeas=_IQ15toIQ(tgu);
    ileg2_1.IvMeas=_IQ15toIQ(tgv);

    watchIu=tgu;//ileg2_1.IuMeas;//ileg2_1.IuRaw;
    watchIv=tgv;//ileg2_1.IvMeas;//ileg2_1.IvRaw;
    watch=_IQ15int(_IQ15mpy(_IQtoIQ15(pid1_iq.Ref),_IQ 15(100)));

    logger();

    // Note: To be safe, use a mask value to write to the entire
    // EVAIFRA register. Writing to one bit will cause a read-modify-write
    // operation that may have the result of writing 1''s to clear
    // bits other then those intended.
    EvaRegs.EVAIFRA.all = BIT9; //0x0200

    // Acknowledge interrupt to recieve more interrupts from PIE group 2
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; //0x0002

    }

    //================================================== =============================
    // Read ADC: Timer 1 period interrupt service routine ( in the middle of cycle )
    //================================================== =============================

    void ReadADC()
    {

    // Take the meased values of current from ADC
    ileg2_1.IuMeas=AdcRegs.RESULT0>>4;
    ileg2_1.IvMeas=AdcRegs.RESULT1>>4;

    //logger();
    // Note: To be safe, use a mask value to write to the entire
    // EVAIFRA register. Writing to one bit will cause a read-modify-write
    // operation that may have the result of writing 1''s to clear
    // bits other then those intended.
    EvaRegs.EVAIFRA.all = BIT7; //0x0040

    // Acknowledge interrupt to recieve more interrupts from PIE group 3
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; //0x0002
    }


    //===========================================
    // Timer 1 period interrupt service routine
    //===========================================
    interrupt void adc_isr(void)
    {
    // Read the results of ADC
    ileg2_1.IuRaw=AdcRegs.RESULT0>>4;// doc ADCIN06
    ileg2_1.IvRaw=AdcRegs.RESULT1>>4;// doc ADCIN05

    // Reinitialize for next ADC sequence
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
    AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    }

    void initPeripheral()
    {

    // Enable PWM pins
    EALLOW;
    GpioMuxRegs.GPAMUX.all = EVA_PWM_OUTPUT; // EVA PWM 1-6 pins
    EDIS;

    // Enable EVA clock

    SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;

    // Enable ADC clock
    EALLOW;
    SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;
    EDIS;

    // Set HSPCLK to SYSCLKOUT = 150MHz
    EALLOW;
    SysCtrlRegs.HISPCP.all = 0; // HSPCLK = SYSCLKOUT / 1 = 150MHz
    EDIS;

    //--------------ADC -----------------------------------------------------
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 3; // ADCCLK = HSPCLK/6
    AdcRegs.ADCTRL1.bit.CPS = 0; // ADCCLK = HSPCLK/6

    // Power up the reference and bandgap circuits
    AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // Power up bandgap/reference circuitry
    DELAY_US(DELAY5000); // Delay before powering up rest of ADC
    AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Power up rest of ADC
    DELAY_US(DELAY20); // Delay after powering up ADC

    // Assign ADC Interrupt Service Routine

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.ADCINT = &adc_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    // Enable ADCINT in PIE
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;

    // Enable CPU Interrupt 1
    IER |= M_INT1; // Enable Global INT1

    // set Maximum Conversion Channels Register
    AdcRegs.MAXCONV.all = 1; // Setup the number of conv''s on SEQ1: maxchanel=1 -->Enable 2 sequents

    // Select Cascaded mode
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // Cascaded mode

    // Initialize ADC Input Channel Select Sequencing Control Register
    AdcRegs.CHSELSEQ1.all = 0x0056; // Setup the 1st to 4th SEQ1 conv: ADCIN06=pha u; ADCIN05=pha v;
    AdcRegs.CHSELSEQ2.all = 0; // Setup the 5th to 8th SEQ1 conv.
    AdcRegs.CHSELSEQ3.all = 0; // Setup the 9th to 12th SEQ1 conv.
    AdcRegs.CHSELSEQ4.all = 0; // Setup the 13th to 16th SEQ1 conv.

    AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

    //--------------END ADC-----------------------------------------------

    // Setup Timer 1 Registers (EV A)

    EvaRegs.GPTCONA.bit.T1TOADC = 1; // ADC NEN CHO PHEP START
    EvaRegs.T1PR = _IQ15int(pwm1.pwm_period); // set GPT1 timer period
    EvaRegs.T1CNT = 0x0000; // reset GPT1 counter register

    // set dead-band parameters
    EvaRegs.DBTCONA.all = DBT_CFG; // enable dead-band and set dead-time to 1us

    // set Action Control Register.
    EvaRegs.ACTRA.all = ACTIVE_HI_LO; // Action that takes place on compare event:
    // output pin 1 CMPR1 - active high
    // output pin 2 CMPR1 - active low
    // output pin 3 CMPR2 - active high
    // output pin 4 CMPR2 - active low
    // output pin 5 CMPR3 - active high
    // output pin 6 CMPR3 - active low

    // set value for compare units 1,2,3 register
    EvaRegs.CMPR1 = _IQ15int(pwm1.u_cmp_val);
    EvaRegs.CMPR2 = _IQ15int(pwm1.v_cmp_val);
    EvaRegs.CMPR3 = _IQ15int(pwm1.w_cmp_val);

    // set GPT1 configuration register
    EvaRegs.T1CON.all = TIM_CONT_UP_DN; // timer in continuous up/down mode for symmetric PWM
    EvaRegs.T1CON.bit.TPS = 2; // Set clock prescaler to x/4 (T1 clock = 37.5MHz)

    // start PWM generation
    EvaRegs.COMCONA.bit.CENABLE = 1; // enable compare operation
    EvaRegs.COMCONA.bit.FCOMPOE = 1; // enable compare output pins

    //------------------------------------------------------------------------
    // KHOI TAO CAPTURE (QEP)
    //-------------------------------------------------------------------------
    // chon Cap3 va theo che do suon len: cap3en=1, capres=1; cap3edge=01
    EvaRegs.CAPCON.all = 0xB004; // Set up capture units (0x9004)

    // chon timer2 che do freeruntime(free=1), Tenable=1, Tmode=11( che do directional up/down count mode), Tclks=11 ( mach QEP)
    EvaRegs.T2CON.all = 0x1870; // Set up capture timer (TI: 0x9870) con TECHNO la: 0x1870
    EvaRegs.T2PR = 4*qep1.LineEncoder; // Init Timer 2 period Register (4*500=2000)

    // them vao theo TECHNO
    EvaRegs.GPTCONA.bit.T2TOADC = 0; // configure GPTCONA not to start ADC on GPT2 Event

    // configure Capture Control Register CAPCONA
    EvaRegs.CAPCON.bit.CAPQEPN = 3; // enable cap1&2 in CAPCONA register
    EALLOW; // Enable EALLOW
    GpioMuxRegs.GPAMUX.all |= 0x0700; // Set up the capture pins to primary functions
    EDIS;

    //--------------------------------------------
    // RESET DEN ERROR
    //--------------------------------------------
    // configure GPIOD1 as digital I/O (GPIODx)
    EALLOW;
    GpioMuxRegs.GPDMUX.all &= 0xFFFD;
    // Configure GPIOD1 pins as output
    GpioMuxRegs.GPDDIR.all |=0x0002;
    EDIS;

    // ReSet the output GPIOD1=0
    err=0;
    while (err<500)
    {
    GpioDataRegs.GPDDAT.all &= 0xFFFD;
    err=err+1;
    }


    //----------------------------
    // THEM VAO PHAN KHOI TAO NGAT
    //----------------------------

    // Reassign ISRs.
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.T1UFINT = &MainISR;
    PieVectTable.T1PINT = &ReadADC;
    EDIS; // This is needed to disable write to EALLOW protected registers

    // Enable PIE group 2 interrupt 6 for T1UFINT
    PieCtrlRegs.PIEIER2.bit.INTx6 = 1; // Enable PIE group 2 (INT2) interrupt 6 for T1UFINT
    PieCtrlRegs.PIEIER2.bit.INTx4 = 1; // Enable PIE group 2 (INT2) interrupt 4 for T1PINT

    // Enable Underflow and Period interrupt bits for GP timer 1
    EvaRegs.EVAIMRA.bit.T1UFINT = 1;
    EvaRegs.EVAIMRA.bit.T1PINT = 1;
    EvaRegs.EVAIFRA.bit.T1UFINT = 1;
    EvaRegs.EVAIFRA.bit.T1PINT = 1;

    // Enable CPU INT2 for T1UFINT and T1PINT
    IER |= M_INT2; //0x0002

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM;
    //----------------------------
    // END IRS INIT
    //----------------------------

    // Start Timer 1:
    EvaRegs.T1CON.bit.TENABLE = 1; // Start GPT1 counter

    }

Chia sẻ trang này