您的位置:首页 > 科技 > 能源 > 电流采集(ADC)、位置转速测量(EQEP)、数模转换(DAC)模块实验程序

电流采集(ADC)、位置转速测量(EQEP)、数模转换(DAC)模块实验程序

2024/10/5 16:05:51 来源:https://blog.csdn.net/m0_64229842/article/details/141752259  浏览:    关键词:电流采集(ADC)、位置转速测量(EQEP)、数模转换(DAC)模块实验程序

该程序不需要连接电机以及电流传感器,只需要用杜邦线将DSP的GPIO对应的接口连接即可调试。

程序中采集的电流是通过生成正弦波的数字信号再通过TLV5620数模转换器将其转换为模拟信号,以此来模拟实际电流信号;

程序中通过EPWM模块生成正交的脉冲信号来模拟正交编码器的A、B输出,通过GPIO口生成正交编码器的I索引脉冲信号;

main.c

/利用EQEP1模块测量电机的转速以及位置
//采用EPWM1模块生成EQEPA、EQEPB正交信号
//GPIO4生成EQEPI索引信号
//分别用M法和T法测速得到电机的转速#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "eqep1.h"
#include "ADC.h"
#include "math.h"
#include "tlv5620.h"
#define PI 3.14159265358979323846
#define SINE_RESOLUTION 100
void main ()
{int index = 0;int i;Uint16 dacvalue;float sine_wave[SINE_RESOLUTION];InitSysCtrl();InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();ADC_Init();EQEP1_Init();EINT;ERTM;TLV5620_Init();for (i = 0; i < SINE_RESOLUTION; i++) {sine_wave[i] = (sin(2 * PI * i / SINE_RESOLUTION) + 1) * 127.5; // 将正弦波值映射到0-255范围}while(1){dacvalue = (Uint16)sine_wave[index];DAC_SetChannelData(0,0,dacvalue);index++;if (index >= SINE_RESOLUTION){index = 0;}DELAY_US(1*100);}
}

ADC.c 

/** ADC.c**  Created on: 2024年6月18日*      Author: ZnDream666*/
#include"ADC.h"
//初始化ADC,设置ADC为EPW1的CTR=PRD事件到来开始转换
//完成8个通道的采样后进入ADC中断,中断程序内将采集到的电流值记录
#define ADC_usDELAY  5000L
int sampleTable[8];
float I[8];
int i;
int k=0;
float I7_buf[100];
void ADC_Init()
{extern void DSP28x_usDelay(Uint32 Count);EALLOW;SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;EDIS;EALLOW;SysCtrlRegs.HISPCP.all = ADC_MODCLK;    // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK)ADC_cal();EDIS;AdcRegs.ADCTRL3.all = 0x00E0;DELAY_US(ADC_usDELAY);AdcRegs.ADCTRL1.bit.CPS= 0;AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;   //双序列发生器模式AdcRegs.ADCTRL3.bit.SMODE_SEL=0;    //顺序采样模式AdcRegs.ADCTRL1.bit.CONT_RUN = 0; //启动/停止模式AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7;AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // 采样ADCA0AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // 采样ADCA1AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // 采样ADCA2AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // 采样ADCA3AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // 采样ADCA4AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // 采样ADCA5AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // 采样ADCA6AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // 采样ADCA7AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;//EPWM_SOCA启动方式
//    AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2 = 1;EALLOW;PieVectTable.ADCINT = &adc_isr;    //配置adc中断服务函数地址EDIS;PieCtrlRegs.PIEIER1.bit.INTx6 = 1;    //开启INT1.6中断IER |= M_INT1;                     // 开启第一组中断EINT;ERTM;AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; //允许SEQ1发送中断申请AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = 0; //禁止SEQ2发送中断申请AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; //每个SEQ1序列转换完成后发送一次中断申请
}
interrupt void adc_isr()
{sampleTable[0] = (AdcRegs.ADCRESULT0) >> 4;sampleTable[1] = (AdcRegs.ADCRESULT1) >> 4;sampleTable[2] = (AdcRegs.ADCRESULT2) >> 4;sampleTable[3] = (AdcRegs.ADCRESULT3) >> 4;sampleTable[4] = (AdcRegs.ADCRESULT4) >> 4;sampleTable[5] = (AdcRegs.ADCRESULT5) >> 4;sampleTable[6] = (AdcRegs.ADCRESULT6) >> 4;sampleTable[7] = (AdcRegs.ADCRESULT7) >> 4;AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //初始化状态指针位置
//    AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;for(i = 0; i < 8; i++){I[i] = (float)sampleTable[i] * 3.0 / 4095.0;}I7_buf[k++] = I[7];if (k>=100)k = 0;
}

eqep1.c 

/** eqep1.c**  Created on: 2024年6月12日*      Author: ZnDream666*/
#include "eqep1.h"
#include "Example_posspeed.h"
#define CPU_CLK   150e6
#define PWM_CLK   10e3              // 5kHz (150rpm) EPWM1 frequency. Freq. can be changed here
#define SP        CPU_CLK/(2*PWM_CLK)
//#define SP        0xFFFF
POSSPEED qep_posspeed=POSSPEED_DEFAULTS;
Uint16 Interrupt_Count = 0;
float P_A = 0;
float P_B = 0;
float P_C = 0;
float P_D = 0;
float P_E = 0;
float P_F = 0;
float P_G = 0;
float P_H = 0;
Uint16 j=0;
int PA_buf[100];
interrupt void prdTick(void);
void  EPwm1Setup()
{EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;EDIS;InitEPwm1Gpio();EALLOW;GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;    // GPIO4 as output simulates Index signalGpioDataRegs.GPACLEAR.bit.GPIO4 = 1;  // Normally lowEDIS;EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;EPwm1Regs.TBSTS.all=0;EPwm1Regs.TBPHS.half.TBPHS =0;EPwm1Regs.TBCTR=0;EPwm1Regs.TBPRD = SP;EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;EPwm1Regs.TBCTL.bit.HSPCLKDIV=0;     //分频系数xEPwm1Regs.TBCTL.bit.CLKDIV=0;         //分频系数yEPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE;EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE;EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;//当计数器达到零点时,阴影寄存器的值会被加载到实际的CMPA寄存器中。这种加载模式确保CMPA值的更新在计数器归零时进行,从而保持PWM信号的同步和一致性。EPwm1Regs.CMPA.half.CMPA = SP/2;EPwm1Regs.CMPB = 0;EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR;EPwm1Regs.AQCTLB.bit.PRD = AQ_SET;EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;     // TBPCR=TBPRD时触发中断申请EPwm1Regs.ETSEL.bit.INTEN = 1;  // Enable INT    //使能EPWM6模块的中断功能EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //使能EPwm1SOCA信号产生EPwm1Regs.ETSEL.bit.SOCBEN = 1;EPwm1Regs.ETSEL.bit.SOCASEL = 2;  //当TBCTR=TBPRD时产生SOCA信号EPwm1Regs.ETSEL.bit.SOCBSEL = 2;EPwm1Regs.ETPS.bit.SOCAPRD = 1;   //在第一个事件来到时产生SOCA信号EPwm1Regs.ETPS.bit.SOCBPRD = 1;EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;EDIS;EALLOW;  // This is needed to write to EALLOW protected registersPieVectTable.EPWM1_INT= &prdTick;EDIS;IER |= M_INT3;PieCtrlRegs.PIEIER3.bit.INTx1 = 1;EINT;   // Enable Global interrupt INTMERTM;   // Enable Global realtime interrupt DBGM
}void EQEP1_Init()
{EALLOW;  // This is needed to write to EALLOW protected registersSysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1EDIS;InitEQep1Gpio();EPwm1Setup();qep_posspeed.init(&qep_posspeed);
}interrupt void prdTick(void)                  // EPWM1 Interrupts once every 4 QCLK counts (one period)
{Uint16 i;// Position and Speed measurementqep_posspeed.calc(&qep_posspeed);P_A=((qep_posspeed.theta_raw-390+444)%444)*20/444;P_B=((qep_posspeed.theta_raw-390-111+444)%444)*20/444;P_C=((qep_posspeed.theta_raw-390-222+444)%444)*20/444;P_D=((qep_posspeed.theta_raw-390-333+444)%444)*20/444;P_E=((qep_posspeed.theta_raw-335+444)%444)*20/444;P_F=((qep_posspeed.theta_raw-335-111+444)%444)*20/444;P_G=((qep_posspeed.theta_raw-335-222+444)%444)*20/444;P_H=((qep_posspeed.theta_raw-335-333+444)%444)*20/444;// Control loop code for position control & Speed contolInterrupt_Count++;if (Interrupt_Count==2000)                 // Every 1000 interrupts(4000 QCLK counts or 1 rev.){EALLOW;GpioDataRegs.GPASET.bit.GPIO4 = 1;     // Pulse Index signal  (1 pulse/rev.)for (i=0; i<700; i++){}GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;Interrupt_Count = 0;                   // Reset countEDIS;}// Acknowledge this interrupt to receive more interrupts from group 1PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;EPwm1Regs.ETCLR.bit.INT=1;
}

 Example_posspeed.c

//###########################################################################
//
// FILE:	Example_posspeed.c
//
//标题:使用 EQEP 外设进行位置/速度测量
//
// DESCRIPTION:
//
// 该文件包含由 Example_2833xEqep_posspeed.c 调用的 EQEP 初始化和位置及速度计算函数。
// POSSPEED_Calc() 函数在 SYSCLKOUT = 150 MHz 和
//100 MHz 时执行的位置和速度计算步骤如下详细描述:
//
// For 150 MHz Operation:
// ----------------------
//
// 1. 该程序计算: **theta_mech**
//    
//    theta_mech = QPOSCNT/mech_Scaler = QPOSCNT/4000,
//其中,4000 是一圈内的计数数。(4000/4 = 1000 线/圈的增量编码器)
//
// 2. 该程序计算: **theta_elec**
//
//    theta_elec = (# pole pairs) * theta_mech = 2*QPOSCNT/4000 for this example
//
// 3. 该程序计算: **SpeedRpm_fr** 高速测量
//
//    SpeedRpm_fr = [(x2-x1)/4000]/T                                             - Equation 1
//    其中 (x2-x1) 是 QPOSCNT 计数的差值。
//将 (x2-x1) 除以 4000 给出相对于索引的一圈内的位置。
// If base RPM  = 6000 rpm:
//                      6000 rpm = [(x2-x1)/4000]/10ms                     - Equation 2
//                                        = [(x2-x1)/4000]/(.01s*1 min/60 sec)
//                                        = [(x2-x1)/4000]/(1/6000) min
//                         max (x2-x1) = 4000 counts, or 1 revolution in 10 ms
//
//
// 将等式两边除以 6000 rpm:
//                            1 = [(x2-x1)/4000] rev./[(1/6000) min * 6000rpm] 
//							因为 (x2-x1) 对于 QPOSCNT 增量必须小于 4000(最大),
//						    (x2-x1)/4000 < 1 for CW rotation
//                          因为 (x2-x1) 对于 QPOSCNT 减量必须大于 -4000
//                          (x2-x1)/4000>-1  for CCW rotation
//						    speed_fr = [(x2-x1)/4000]/[(1/6000) min * 6000rpm]
//                                   = (x2-x1)/4000                              - Equation 3
//
// 将 speed_fr 转换为 RPM,乘以 6000 rpm:
//                           SpeedRpm_fr = 6000rpm *(x2-x1)/4000                 - Final Equation
//			SpeedRpm_fr = 2.5*	(x2-x1)
//
// 2. **min rpm ** = 根据可用的 CCPS 预分频选项选择为 10 rpm(最大为 128)
//
// 3. **SpeedRpm_pr**  低速测量
//    SpeedRpm_pr = X/(t2-t1)                                                    - Equation 4
//    其中 X = QCAPCTL [UPPS]/4000 圈(相对于索引的一圈内的位置)
// 如果最大/基础速度 = 6000 rpm:  6000 = (32/4000)/[(t2-t1)/(150MHz/128)]
//    其中 32 = QCAPCTL [UPPS](单位超时 - 每 32 个边缘一次)
//          32/4000 = position in 1 revolution (position as a fraction of 1 revolution)
//          t2-t1/(150MHz/128),  t2-t1= # of QCAPCLK cycles, and
//		                  1 QCAPCLK cycle = 1/(150MHz/128)
//										  = QCPRDLAT
//
//		        So: 6000 rpm = [32(150MHz/128)*60s/min]/[4000(t2-t1)]
//		             t2-t1 = [32(150MHz/128)*60 s/min]/(4000*6000rpm)           - Equation 5 
//		                   = 94 CAPCLK cycles = maximum (t2-t1) = SpeedScaler
//
// Divide both sides by (t2-t1), and:
//                   1 = 94/(t2-t1) = [32(150MHz/128)*60 s/min]/(4000*6000rpm)]/(t2-t1)
//				     Because (t2-t1) must be < 94 for QPOSCNT increment:
//				     94/(t2-t1) < 1 for CW rotation
//                   And because (t2-t1) must be >-94 for QPOSCNT decrement:
//				     94/(t2-t1)> -1 for CCW rotation
//
//					 speed_pr = 94/(t2-t1) 
//                      or [32(150MHz/128)*60 s/min]/(4000*6000rpm)]/(t2-t1)  - Equation 6
//
// To convert speed_pr to RPM:
// Multiply Equation 6 by 6000rpm:
//                  SpeedRpm_fr  = 6000rpm * [32(150MHz/128)*60 s/min]/[4000*6000rpm*(t2-t1)]
//							                = [32(150MHz/128)*60 s/min]/[4000*(t2-t1)]
//                                        or [(32/4000)rev * 60 s/min]/[(t2-t1)(QCPRDLAT)]- Final Equation
//SpeedRpm_fr = 562500 /(t2-t1)
//
// For 100 MHz Operation:
// ----------------------
//
// The same calculations as above are performed, but with 100 MHz
// instead of 150MHz when calculating SpeedRpm_pr.
// The value for freqScaler_pr becomes: [32*(100MHz/128)*60s/min]/(4000*6000rpm) = 63
// More detailed calculation results can be found in the Example_freqcal.xls
// spreadsheet included in the example folder.
//
//
//
// This file contains source for the posspeed module
//
//###########################################################################
// Original Author: SD
//
// $TI Release: 2833x/2823x Header Files and Peripheral Examples V133 $
// $Release Date: June 8, 2012 $
//###########################################################################
//使用固定点数运算而不是浮点数运算,以及在不同的 Q 格式之间进行转换,主要是为了提高性能、效率和确定性,节省资源,并利用硬件优化。这种方法虽然看起来复杂,
//但在嵌入式系统和实时控制应用中具有显著优势。
//即使有 FPU,定点数运算在某些情况下仍然比浮点数运算快。定点数运算使用整数运算,通常比浮点数运算消耗更少的时钟周期。
#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"     // Device Headerfile and Examples Include File
#include "Example_posspeed.h"   // Example specific Include filevoid  POSSPEED_Init(void)
{#if (CPU_FRQ_150MHZ)EQep1Regs.QUPRD=1500000;			// Unit Timer for 100Hz at 150 MHz SYSCLKOUT#endif#if (CPU_FRQ_100MHZ)EQep1Regs.QUPRD=1000000;			// Unit Timer for 100Hz at 100 MHz SYSCLKOUT#endif	EQep1Regs.QDECCTL.bit.QSRC=00;		// QEP quadrature count modeEQep1Regs.QEPCTL.bit.FREE_SOFT=2;EQep1Regs.QEPCTL.bit.PCRM=00;		// PCRM=00 mode - QPOSCNT reset on index eventEQep1Regs.QEPCTL.bit.UTE=1; 		// Unit Timeout Enable EQep1Regs.QEPCTL.bit.QCLM=1; 		// Latch on unit time outEQep1Regs.QPOSMAX=0xffffffff;EQep1Regs.QEPCTL.bit.QPEN=1; 		// QEP enableEQep1Regs.QCAPCTL.bit.UPPS=5;   	// 1/32 for unit positionEQep1Regs.QCAPCTL.bit.CCPS=7;		// 1/128 for CAP clockEQep1Regs.QCAPCTL.bit.CEN=1; 		// QEP Capture Enable}void POSSPEED_Calc(POSSPEED *p)     //传入&qep_posspeed也就是结构体的地址,用于存储数据,类似于数组
{long tmp;unsigned int pos16bval,temp1;_iq Tmp1,newp,oldp;//位置计算——机械和电角度//p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF;    // 电机方向: 0=逆时针/反向, 1=顺时针/正向
//p是指向结构体的指针,里面存放了结构体的地址,->相当于先解引用指针p,再访问结构体里面的成员pos16bval=(unsigned int)EQep1Regs.QPOSCNT;     // 捕获QA,QB的脉冲数p->theta_raw = pos16bval+ p->cal_angle;        // raw theta = current pos. + ang. offset from QA// The following lines calculate p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]// where mech_scaler = 4000 cnts/revolutiontmp = (long)((long)p->theta_raw*(long)p->mech_scaler);  	// Q0*Q26 = Q26 tmp &= 0x03FFF000;                                        p->theta_mech = (int)(tmp>>11);         		// Q26 -> Q15 p->theta_mech &= 0x7FFF;                       // The following lines calculate p->elec_mech    p->theta_elec = p->pole_pairs*p->theta_mech;  // Q0*Q15 = Q15 p->theta_elec &= 0x7FFF;          //保留有效的15位数据,限制其值在合理的范围内,避免溢出// Check an index occurrenceif (EQep1Regs.QFLG.bit.IEL == 1)     //检测到索引脉冲,CNT值锁存入QPOSILAT{  p->index_sync_flag = 0x00F0;        //同步索引标志使用这种特定的值(而不是简单的 1 或 0)可以帮助避免与其他标志或状态混淆。EQep1Regs.QCLR.bit.IEL=1;					// Clear interrupt flag}//**** High Speed Calcultation using QEP Position counter ****//
// 检查单位超时事件以进行速度计算:
//  单位计时器在初始化函数中配置为100Hzif(EQep1Regs.QFLG.bit.UTO==1)                    // 如果单位超时(一个100Hz周期){ /** 微分器 	**/// 计算位置变化量 = (x2-x1) / 4000(每转位置)pos16bval=(unsigned int)EQep1Regs.QPOSLAT;	              // 锁存的POSCNT值tmp = (long)((long)pos16bval*(long)p->mech_scaler);  	  // Q0*Q26 = Q26 tmp &= 0x03FFF000;tmp = (int)(tmp>>11);         			                  // Q26 -> Q15 tmp &= 0x7FFF;newp=_IQ15toIQ(tmp);            //将Q15格式转换为Q格式oldp=p->oldpos;if (p->DirectionQep==0)      				// POSCNT is counting down{if (newp>oldp)Tmp1 = - (_IQ(1) - newp + oldp);    // x2-x1 should be negativeelseTmp1 = newp -oldp;}else if (p->DirectionQep==1)      			// POSCNT is counting up{if (newp<oldp)Tmp1 = _IQ(1) + newp - oldp;else Tmp1 = newp - oldp;                     // x2-x1 should be positive}if (Tmp1>_IQ(1))                            p->Speed_fr = _IQ(1);else if (Tmp1<_IQ(-1))p->Speed_fr = _IQ(-1);      elsep->Speed_fr = Tmp1;// Update the electrical anglep->oldpos = newp;// Change motor speed from pu value to rpm value (Q15 -> Q0)// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Qp->SpeedRpm_fr = _IQmpy(p->BaseRpm,p->Speed_fr);  //=======================================EQep1Regs.QCLR.bit.UTO=1;					// Clear interrupt flag}	//**** Low-speed computation using QEP capture counter ****//	if(EQep1Regs.QEPSTS.bit.UPEVNT==1)                 // Unit position event{if(EQep1Regs.QEPSTS.bit.COEF==0)               // No Capture overflowtemp1=(unsigned long)EQep1Regs.QCPRDLAT;   // temp1 = t2-t1  else							               // Capture overflow, saturate the resulttemp1=0xFFFF;p->Speed_pr = _IQdiv(p->SpeedScaler,temp1);    // p->Speed_pr = p->SpeedScaler/temp1 Tmp1=p->Speed_pr;if (Tmp1>_IQ(1))p->Speed_pr = _IQ(1);   elsep->Speed_pr = Tmp1;// Convert p->Speed_pr to RPMif (p->DirectionQep==0)                                 // Reverse direction = negativep->SpeedRpm_pr = -_IQmpy(p->BaseRpm,p->Speed_pr); 	// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Qelse                                                    // Forward direction = positivep->SpeedRpm_pr = _IQmpy(p->BaseRpm,p->Speed_pr); 	// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_QEQep1Regs.QEPSTS.all=0x88;					// Clear Unit position event flag	// Clear overflow error flag}}

 tlv5620.c

/** tlv5620.c**  Created on: 2018-3-1*      Author: Administrator*/#include "tlv5620.h"void TLV5620_Init(void)
{EALLOW;SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-AEDIS;/*初始化GPIO;*/InitSpiaGpio();EALLOW;GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0; // 配置GPIO为GPIO口GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;      // 定义GPIO输出引脚GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0;      // 禁止上啦 GPIO引脚EDIS;SpiaRegs.SPICCR.all =0x0a;///进入初始状态,数据在上升沿输出,自测禁止,11位数据模式SpiaRegs.SPICTL.all =0x0006; // 使能主机模式,正常相位,使能主机发送,禁止接收//溢出中断,禁止SPI中断;SpiaRegs.SPIBRR =0x0031;	//SPI波特率=37.5M/50	=0.75MHZ;SpiaRegs.SPICCR.all =0x8a; //退出初始状态;SpiaRegs.SPIPRI.bit.FREE = 1;  // 自由运行SET_LOAD;
}///大家要知道这里所定义的各个变量的含义,channel是4个通道的地址(00,01,10,11)
///                                     rng是输出范围的倍数,可以是0或1。
///                                     dat是0~256数据
void DAC_SetChannelData(unsigned char channel,unsigned char rng,unsigned char dat)
{Uint16 dacvalue=0;//注意这里的有效数据是11位,SPI初始化中也进行了定义dacvalue = ((channel<<14) | (rng<<13) | (dat<<5));while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG ==1);//判断SPI的发送缓冲区是否是空的,等于0可写数据SpiaRegs.SPITXBUF = dacvalue;	//把发送的数据写入SPI发送缓冲区while( SpiaRegs.SPISTS.bit.BUFFULL_FLAG==1);		//当发送缓冲区出现满标志位时,开始琐存数据ClEAR_LOAD;DELAY_US(2);SET_LOAD;DELAY_US(10);}

  Example_posspeed.h

//###########################################################################
// 文件: Example_posspeed.h
//
// 标题: 使用 EQEP 外设进行位置/速度测量
//
// 描述:
//
// 包含数据类型和对象定义以及初始化器的头文件。
//
//###########################################################################
// 原作者: SD
//
// $TI 发布: 2833x/2823x 头文件和外设示例 V133 $
// $发布日期: 2012 年 6 月 8 日 $
//############################################################################ifndef __POSSPEED__
#define __POSSPEED__#include "IQmathLib.h"         // Include header for IQmath library
/*-----------------------------------------------------------------------------
定义 POSSPEED 对象的结构
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec;     	// Output: 电机电角度 (Q15)int theta_mech;     	// Output: 电机机械角度 (Q15)int DirectionQep;      	// Output: 电机旋转方向 (Q0)int QEP_cnt_idx; 	 	// Variable: 编码器计数器索引 (Q0)int theta_raw;     		// Variable: 来自 Timer 2 的原始角度 (Q0)int mech_scaler;    	// Parameter: 0.9999/总计数,总计数 = 4000 (Q26)int pole_pairs;     	// Parameter: 极对数 (Q0)int cal_angle;     		// Parameter:  编码器与相位 A 之间的原始角偏移 (Q0)int index_sync_flag; 	// Output: 索引同步状态 (Q0)Uint32 SpeedScaler;     // Parameter :  将 1/N 周期转换为 GLOBAL_Q 速度的缩放器 (Q0) - 独立于全局 Q_iq Speed_pr;           // Output :  每单位速度Uint32 BaseRpm;         // Parameter : 将 GLOBAL_Q 速度转换为 rpm 的缩放器 (Q0) - 独立于全局 Qint32 SpeedRpm_pr;      // 速度 (rpm) (Q0) - 独立于全局 Q_iq  oldpos;  			// Input: 电角度 (pu)_iq Speed_fr;           //  每单位速度int32 SpeedRpm_fr;     	// Output : 速度 (rpm) (Q0) - 独立于全局 Qvoid (*init)();     	// 指向初始化函数的指针void (*calc)();    		// 指向计算函数的指针}  POSSPEED;/*-----------------------------------------------------------------------------
Define a POSSPEED_handle
-----------------------------------------------------------------------------*/
typedef POSSPEED *POSSPEED_handle;/*-----------------------------------------------------------------------------
Default initializer for the POSSPEED Object.
-----------------------------------------------------------------------------*/#if (CPU_FRQ_150MHZ)#define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,8388,2,0,0x0,\47,0,6000,0,\0,0,0,\(void (*)(long))POSSPEED_Init,\(void (*)(long))POSSPEED_Calc }
#endif
#if (CPU_FRQ_100MHZ)#define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,8388,2,0,0x0,\63,0,6000,0,\0,0,0,\(void (*)(long))POSSPEED_Init,\(void (*)(long))POSSPEED_Calc }
#endif/*-----------------------------------------------------------------------------
Prototypes for the functions in posspeed.c                                 
-----------------------------------------------------------------------------*/
void POSSPEED_Init(void);                                              
void POSSPEED_Calc(POSSPEED_handle);#endif /*  __POSSPEED__ */

ADC.h eqep1.h tlv5620.h 头文件内容较少在此省略

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com