cyy的垃圾堆


  • 首页
  • 归档
  • 标签
  • 关于CYY
  • 友链

© 2025 CYY

Theme Typography by Makito

Proudly published with Hexo

f28335以及ccs环境

发布于 2024-03-04

对于dsp的学习仅仅停留在表面,距离结课已有了一个月多,虽然遗忘很多,还是留点东西吧

很多东西是已经是存在的,和stm32的库函数类似,课程基本是靠CCS的观察变量变化,来得出结果,除了电机,其他没有外设

内存分配位置

在不指定变量的存放位置时,const变量放入econst段,非const放入ebss段里,在函数里定义的变量不会被放入任何段,直接在ram中

对于指定变量位置时,建议代码放入page0位置,数据放入page1位置

指定变量,例如,在cmd处增加mydata : > RAML7, PAGE = 1

1
2
#pragma DATA_SECTION(zjut,"mydata")
float zjut[10];

指定函数,例如,在cmd处增加mycode : > RAML2, PAGE = 0,在main函数中调用下,否则可能会被编译器优化掉

1
2
#pragma CODE_SECTION(qqqq,"mycode")
void qqqq()

先编译代码,然后点击view->Memory Allocation观察内存分配

p1

初始

一般都是以这样开头

1
2
3
4
InitSysCtrl();//系统时钟初始化,默认已开启F28335所有外设时钟
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();

初始化外设,清楚禁用所有中断,初始化中断向量表

中断

F28335看门狗

​ f28335操作寄存器的特点是要先关闭保护,才能继续操作

​ 喂狗函数如下

1
2
3
4
5
6
7
void ServiceDog(void)
{
EALLOW;
SysCtrlRegs.WDKEY = 0x0055;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
}

​ 看门狗简单来说就是防止程序跑飞,当其计数器到达一定的值时,产生中断信号,使得产生中断或者使得处理器复位,在已有看门狗代码下进行如下循环,用以观察看门狗的现象

1
2
3
4
5
6
7
8
while(1)
{
LoopCount++;
if(a==1) //通过手动更改a的值来实现是否喂看门狗
{
ServiceDog();
}
}

不喂狗:

p2

喂狗:

p3

定时器中断

与stm32不同的是,stm32有专门的中断函数,CCS可以自定义函数名,然后与对于中断绑定

1
2
3
4
5
EALLOW; 
PieVectTable.TINT2 = &ISRTimer2;
PieVectTable.XINT13 = &ISRTimer1;
PieVectTable.TINT0 = &ISRTimer0;
EDIS;

中断函数,PieCtrlRegs.PIEACK.bit.ACK1=1语句与32类似,中断标志位恢复

1
2
3
4
5
6
7
interrupt void ISRTimer2(void)
{
EALLOW;
c++;
PieCtrlRegs.PIEACK.bit.ACK1=1;
EDIS;
}

时钟启动

1
2
3
4
5
6
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 0
SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 0
EDIS;

对应定时器开启

1
2
3
4
5
6
7
8
9
10
11
12
13
14
InitCpuTimers();
ConfigCpuTimer(&CpuTimer2, 150, 3000000);//三秒中断,150分频
ConfigCpuTimer(&CpuTimer0, 150, 2000000);
ConfigCpuTimer(&CpuTimer1, 150, 1000000);
StartCpuTimer2();
StartCpuTimer1();
StartCpuTimer0();
/*开中断*/
IER |= M_INT14;
IER |= M_INT13;
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
EINT;
ERTM;

InitCpuTimers,ConfigCpuTimer,StartCpuTimer0之类的函数都是已有的,调用填入相关参数即可

外部中断

与定时器中断相类似

1
2
3
4
5
6
7
8
EALLOW; 
PieVectTable.XINT1 = &ISRExint1;//对应中断函数
EDIS;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER1.bit.INTx4= 1;
IER |= M_INT1;
EINT;
ERTM;

外部中断需要设置XINTn外部中断通道挂接对应在某引脚外部中断1(XINT1)到外部中断2(XINT2)可以挂接GPIO0到GPIO31,外部中断3(XINT3)到外部中断7(XINT7)可以挂接GPIO32到GPIO63。

引脚配置

1
2
3
4
5
6
7
8
9
10
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO18 = 0; //1为输出功能
GpioCtrlRegs.GPAQSEL2.bit.GPIO18= 2;
GpioCtrlRegs.GPAPUD.bit.GPIO18=0;


GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 18;//选择GPIO18为外部输入XINT3输入引脚
XIntruptRegs.XINT1CR.bit.POLARITY= 0;//XIntruptRegs.XINT1CR.bit.POLARITY,置0时为下降沿,置1时为上升沿
XIntruptRegs.XINT1CR.bit.ENABLE = 1; //使能XINT1中断

ePWM

一个定时器可以输出两种PWM波,互补,或者相同

1
2
3
4
5
6
EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;  
EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET;
//A通道,上升计数到达,置1。计数为0,置1
EPwm3Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
//B通道,上升计数到达,置1。计数为0,置0

SPI通讯

1
2
3
4
SpiaRegs.SPICCR.all =0x0016;	//第三位置1为自反馈模式,第四位指的是数据长度为6位
SpiaRegs.SPICTL.all =0x0006; //闲置时时钟极性为低电平,传输发生在时钟信号的下降沿。
SpiaRegs.SPIBRR =0x007F; //配置波特率
SpiaRegs.SPIPRI.bit.FREE = 1;

数据传输

1
2
3
4
5
6
7
for(;;)
{
spi_xmit(sdata);//传送数据
while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }//等待发送完成
rdata = SpiaRegs.SPIRXBUF;//接收数据
sdata+=0x0200;//发送数据自增,便于观察现象
}

传输7位,而数据有16位,出现两边不一样的现象

ADC

1
2
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x6;//采样通道,从00~15
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 15;//采样通道数

以下是进行初步的采样,多个通道进行平均,实现过采样,有一定的使得波形光滑

1
2
3
4
5
all=(AdcRegs.ADCRESULT0 >>4)+(AdcRegs.ADCRESULT1 >>4)+(AdcRegs.ADCRESULT3 >>4)+(AdcRegs.ADCRESULT4 >>4)+
(AdcRegs.ADCRESULT4 >>4)+(AdcRegs.ADCRESULT5 >>4)+(AdcRegs.ADCRESULT6 >>4)+(AdcRegs.ADCRESULT7 >>4)+
(AdcRegs.ADCRESULT8 >>4)+(AdcRegs.ADCRESULT9 >>4)+(AdcRegs.ADCRESULT10 >>4)+(AdcRegs.ADCRESULT11 >>4)+
(AdcRegs.ADCRESULT12 >>4)+(AdcRegs.ADCRESULT3 >>4)+(AdcRegs.ADCRESULT14 >>4)+(AdcRegs.ADCRESULT15 >>4)
;

一阶低通滤波实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(ConversionCount>1)
{
Voltage4[ConversionCount]=0.98*Voltage4[ConversionCount-1]+0.02*Voltage2[ConversionCount];
}
else
{
Voltage4[0]=0.98*Voltage4[1024]+0.02*Voltage2[ConversionCount];
}
if(ConversionCount == 1024)
{
ConversionCount = 0;
}
else ConversionCount++;

对G(s)=1/(s/w+1)进行离散化,使用前向差分即可。

flash运行程序

这里没有实际使用过。

1:加载另一版本CMD文件,并将RAM版CMD文件右键,选择“Exclude from Build”

2:将核心代码拷贝至RAM执行(主中断内所有核心代码),先宏定义FLASH

3:将程序和代码拷贝至RAM执行,在SECTIONS中定义RAM执行段—ramfuncs”;将程序、变量定义在“ramfuncs”段中Pragma

1
2
3
4
#ifdef FLASH
#pragma CODE_SECTION(MainISR,"ramfuncs");
#pragma CODE_SECTION(OffsetISR,"ramfuncs");
#endif

分享到 

 上一篇: YZ-AIM电机驱动记录 下一篇: ROS 

© 2025 CYY

Theme Typography by Makito

Proudly published with Hexo