dsp30代码 下载本文

// ============= 电机 PWM ======================

PDC1 = 0; PDC2 = 0; PDC3 = 0; PDC4 = 0;

// 中心对齐 PWM。

// 注:PWM周期设定为 dLoopInTcy/2,但由于先采用递增计数随后为递减计数, // =>在计数到零时中断标志置 1 =>因此实际中断周期为 dLoopInTcy //

PTPER = dLoopInTcy/2; // 将 PWM周期设定为循环时间,该参数在 parms.h中定义

PWMCON1 = 0x0077; // 使能 PWM 1,2,3对工作在互补模式 DTCON1 = dDeadTime; // 死区时间 DTCON2 = 0;

FLTACON = 0; // 未使用 PWM故障引脚 FLTBCON = 0;

PTCON = 0x8002; // 使能 PWM中心对齐

// SEVTCMP: 特殊事件比较计数寄存器

// 相对于 PWM周期的 ADC捕获设定相位: 0偏移量和递增计数 SEVTCMP = 2; // 不能为 0,否则关断触发器(文档中未列明)

SEVTCMPbits.SEVTDIR = 0;

// ============= 编码器 ===============

MAXCNT = MotorParm.iCntsPerRev; POSCNT = 0; QEICON = 0;

QEICONbits.QEIM = 7; // 通过 MAXCNT脉冲复位 x4 QEICONbits.POSRES = 0; // 不要让索引脉冲复位计数器 QEICONbits.SWPAB = 0; // 方向

DFLTCON = 0; // 数字滤波器设定为关闭

// ============= ADC - 测量电流和电位器给定值 ====================== // ADC设定为对以下通道同时进行采样: // CH0=AN7, CH1=AN0, CH2=AN1, CH3=AN2

// 采样由 PWM触发,且采样结果以有符号小数形式存放。

ADCON1 = 0;

// 有符号小数格式( DOUT = sddd dddd dd00 0000) ADCON1bits.FORM = 3;

// 电机控制 PWM间隔终止采样并启动转换 ADCON1bits.SSRC = 3;

// 同时采样选择位(仅当 CHPS =01或 1x时应用)

// 同时采样 CH0、 CH1、 CH2和 CH3(当 CHPS = 1x时) // 同时采样 CH0和 CH1(当 CHPS=01时) ADCON1bits.SIMSAM = 1;

//在上一次转换结束后立即开始采样。 // SAMP位自动置位。 ADCON1bits.ASAM = 1;

ADCON2 = 0;

// 同时采样 CH0、 CH1、 CH2、 CH3(当 CHPS = 1x时) ADCON2bits.CHPS = 2;

ADCON3 = 0;

// A/D转换时钟选择位 = 8 * Tcy ADCON3bits.ADCS = 15;

/* ADCHS:ADC输入通道选择寄存器 */ ADCHS = 0; // CH0 为 AN7

ADCHSbits.CH0SA = 7;

// CH1正极性输入为 AN0, CH2正极性输入为 AN1, CH3正极性输入为 AN2 ADCHSbits.CH123SA = 0;

/* ADPCFG:ADC端口配置寄存器 */ // 将所有端口设置为数字端口 ADPCFG = 0xFFFF;

ADPCFGbits.PCFG0 = 0; // AN0 模拟 ADPCFGbits.PCFG1 = 0; // AN1 模拟 ADPCFGbits.PCFG2 = 0; // AN2 模拟

ADPCFGbits.PCFG7 = 0; // AN7 模拟

/* ADCSSL:ADC输入扫描选择寄存器 */ ADCSSL = 0;

// 开启 A/D模块

ADCON1bits.ADON = 1;

#ifdefDIAGNOSTICS

// 对用于诊断模式的输出比较通道 7和 8进行初始化。

// PWM模式中使用比较 // Timer2用作时基 PR2 = 0x1FFF;

OC7CON = 0x0006; OC8CON = 0x0006; T2CONbits.TON = 1; #endif

return False; }

#ifdefDIAGNOSTICS

void DiagnosticsOutput(void) {

int Data;

if(IFS0bits.T2IF) {

IFS0bits.T2IF = 0;

Data = (ParkParm.qIq >> 4) + 0xfff; if(Data > 0x1ff0) Data = 0x1ff0; if(Data < 0x000f) Data = 0x000f; OC7RS = Data;

Data = (EncoderParm.qVelMech) + 0x0fff;

if(Data > 0x1ff0) Data = 0x1ff0; if(Data < 0x000f) Data = 0x000f; OC8RS = Data; } }

#endif

Encoder.c

// 编码器子程序的定标

#include \ #include \ #include \

/********************************************************** InitEncoderScaling

对编码器子程序的定标常量进行初始化。

函数参数:

CntsPerRev:来自正交编码器的每转编码器计数值 ScalingSpeedInRPS:用于基本转速定标的每秒转数 IrpPerCalc:每次转速计算的 CalcVelIrp中断数 VelIrpPeriod:VelCalcIrp中断间的周期(单位为秒)

对于

CalcAng: 运行时方程:

qMechAng = qKang * (POSCNT*4) / 2^Nang

定标方程:

qKang = (2^15)*(2^Nang)/CntsPerRev.