你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
uwyciw100 发表于 2018-3-5 10:23 请问楼主,使用的这个调试软件是什么工具?
dh2964169 发表于 2018-3-5 14:32 程序用的就是KEIL5,波形用的示波器
dh2964169 发表于 2018-3-5 14:31 这个以前倒是没有考虑到。我看了看,SCK和MISO长度差不多,而且较短,但是CS有些长。在程序中本来加入了d ...
查看全部评分
butterflyspring 发表于 2018-3-5 17:23 你这个i--在while里面?你没有到DMA的接收完成中断?你最好检测两个频率下的miso和clk的区别. ...
使用i--情况,SCK与MISO
使用DMA中断的MISO与SCK
使用i--,没有使用中断方式
直接while(1),使用DMA传输完成中断
maxtch 发表于 2018-3-5 17:03 CS 不是高速信号,长一点无所谓,不加 delay 应该也是没有问题的。DMA 溢出是有可能,这么快的速率 DMA ...
dh2964169 发表于 2018-3-6 15:07 现在只需要对100KHz的正弦信号,采取500个点,也就是DMA缓存500个数据就行了,spi的sclk才2.8MHz,DMA存 ...
maxtch 发表于 2018-3-6 19:51 DMA 的溢出问题不是速度太慢 FIFO 溢出,而是分配的内存区域太小或者和别的东西重叠导致的指针溢出。500 ...
dh2964169 发表于 2018-3-6 20:56 啊啊,我直接是定义了一个数组变量ADC_ConvertedValue[500],然后让DMA指向这个数组,当500个数据存入了 ...
程序用的就是KEIL5,波形用的示波器
这个波形工具觉得不错,哈哈
CS 不是高速信号,长一点无所谓,不加 delay 应该也是没有问题的。DMA 溢出是有可能,这么快的速率 DMA 缓冲区要大一点才行,这只能估算一下 DMA 用量,对照着检查代码了。
评分
查看全部评分
谢谢您的关注和提醒。 确实,开始没有弄清DMA的功能,认为i=DMA缓冲区的大小,让SPI运行i次即获得data组采样数据;并且以为i--的运行不会对运行过程产生明显的影响(现在回想,这是一种麻烦的做法)。现在在您的提示下,改用了DMA传输完成进行中断。
但是,和以前的结果一样;我贴出两种情况的代码 和 SCLK与MISO图。请帮再看看为什么还是不能在16分频采样到准确的波形呢?
一 使用 i-- 未使用中断方式
SPIx_Init(); //SPI初始化
GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置1
Rheostat_DMA_Mode_Config(); //DMA初始化
MyDMA_Enable(RHEOSTAT_ADC_DMA_STREAM,numlength); //使能DMA
SPI_I2S_DMACmd (AD_SPI,SPI_I2S_DMAReq_Rx,ENABLE); //SPI_DMA功能使能
while (1)
{
GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置0
Delay(5);
SPI_Cmd(AD_SPI, ENABLE); //SPI开启
data=SPIx_ReadWriteByte(); //产生16个周期的读取数据
SPI_Cmd(AD_SPI, DISABLE); //SPI关闭
Delay(140); //延时时间稍长,为的是让CS=1前,关闭SPI,否则CS=1与sck有重合
GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置1
i--;
Delay(5);
}
二 去掉i--,并使用DMA中断传输完成中断,在中断服务函数打印缓存数据
SPIx_Init(); //SPI初始化
GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置1
Rheostat_DMA_Mode_Config(); //DMA初始化
DMAxx_NVIC(); //DMA中断配置
DMA_ITConfig(RHEOSTAT_ADC_DMA_STREAM,DMA_IT_TC,ENABLE ); //传输完成中断使能
MyDMA_Enable(RHEOSTAT_ADC_DMA_STREAM,numlength); //使能DMA
SPI_I2S_DMACmd (AD_SPI,SPI_I2S_DMAReq_Rx,ENABLE); //SPI_DMA功能使能
while (i)
{
GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置0
Delay(5);
SPI_Cmd(AD_SPI, ENABLE); //SPI开启
data=SPIx_ReadWriteByte(); //产生16个周期的读取数据
SPI_Cmd(AD_SPI, DISABLE); //SPI关闭
Delay(140); //延时时间稍长,为的是让CS=1前,关闭SPI,否则CS=1与sck有重合
GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS置1
Delay(5);
}
///////////////////////////中断服务函数//////////////////////////////////
void DMA1_Stream0_IRQHandler(void)
{
for (j=numlength;j>1;j--)
{
printf("%d\n",ADC_ConvertedValue[j]);
}
DMA_ClearITPendingBit(DMA1_Stream0,DMA_IT_TCIF0); //清除完成中断标志位
}
结果图:
使用i--情况,SCK与MISO
使用DMA中断的MISO与SCK
再贴出两种方式的采集数据,并在EXCEL中绘制的波形图(两种情况波形都差不多,但是无法得到标准的波形)
使用i--,没有使用中断方式
直接while(1),使用DMA传输完成中断
现在只需要对100KHz的正弦信号,采取500个点,也就是DMA缓存500个数据就行了,spi的sclk才2.8MHz,DMA存取的速度很快,所以又觉得不是DMA 溢出问题,有些矛盾。请帮我在观察下,那里还有问题呢,谢谢啦
DMA 的溢出问题不是速度太慢 FIFO 溢出,而是分配的内存区域太小或者和别的东西重叠导致的指针溢出。500 个数据就要分配 1k 到 2k 的内存缓冲区,你给够了吗?
啊啊,我直接是定义了一个数组变量ADC_ConvertedValue[500],然后让DMA指向这个数组,当500个数据存入了这个数组后,再在DMA完成中断服务函数中打印出、
好像我理解的太简单了,随意定义一个数组就可以装数据了。请问下@maxtch 我该如何去解决这个,请给与指点啊,谢谢你
我做嵌入式到现在还没用到过这么大数据流量用单片机处理的东西,到了这种数据吞吐我一般就直接上能跑 Linux 的高速 SoC 了。
DMA 的内存分配往往有特殊要求,你要看芯片手册里面是怎么描述的。