分类目录归档:STM32

STM32 SAI问题

STM32F446 SAI blockA和blockB配置为从模式,如果MCU先启动SAI,再打开音频芯片SAI时钟信号,此时MCU不能进入DMA中断,采集不到数据。用Jlink复位一下MCU,SAI接口的数据采集和发送才正常。不知道这个问题是什么原因。

解决方法有2种:1.MCU启动先不使能SAI,把音频芯片SAI时钟打开后再启动MCU SAI;2.把MCU的SAI配置为主模式。

但是对于这个问题还是感到很奇怪。

关于数组清零

不要使用赋值方法清零。对于16位数组,或者32位数组,赋值清零并没有把所有位都置零。

int32_t mix_data_new[SAI_SLOTS_SIZE][2] = {0};
#if 0
for (j = 0; j < 2; j++)
{
for (k = 0; k < SAI_SLOTS_SIZE; k++)
{
mix_data_new[j][k] = 0;
}
}
#endif

使用memset清零,可以确保每个数组中的每一位都被清零。
memset(mix_data_new, 0, sizeof(mix_data_new));

奇怪的问题

第1段:
int16_t data;
const char pcm_data2[] = {…};

data = pcm_data2[i];
data += pcm_data2[i+1]<<8;

第2段:
data = ((int16_t)pcm_data2[i+1] << 8 + pcm_data2[i]);

很奇怪,上面2段代码,在STM32F401上用MDK编译出来执行的结果不一样。第1段执行出来的结果是正确的,第2段执行出来的结果是错误的,并且不知道是怎么算出来的。

 

 

转载——关于STM32 SPI NSS的讨论

原文链接:https://www.cnblogs.com/shangdawei/p/4756415.html

NSS分为内部引脚和外部引脚。

NSS外部引脚可以作为输入信号或者输出信号,

输入信号一般用作硬件方式从机的片选,

而输出信号一般用于主SPI去片选与之相连的从SPI。

NSS从设备选择有两种模式:

1、软件模式

可以通过设置SPI_CR1寄存器的SSM位来使能这种模式,当它为1时,NSS引脚上的电平由SSI决定。
在这种模式下NSS外部引脚可以用作它用,而内部NSS信号电平可以通过写SPI_CR1的SSI位来驱动。

2、硬件模式两种方式:

(1)对于主SPI,NSS可以直接接高电平,对于从SPI,可以直接接低电平。

(2)当STM32F10xxx工作为主SPI,并且NSS输出已经通过SPI_CR2寄存器的SSOE位使能,
这时主机的NSS讲作为输出信号,引脚信号被拉低,所有NSS引脚与这个主SPI的NSS引脚相连
并配置为硬件NSS的STM32F10xxx SPI设备,将自动变成从SPI设备。

此时两个的NSS信号线可以接个上拉电阻直连。

继续阅读

STM32关闭全局中断时需要注意的问题

原文链接:https://blog.csdn.net/niepangu/article/details/49443557

STM32在使用时有时需要禁用全局中断,比如MCU在升级过程中需禁用外部中断,防止升级过程中外部中断触发导致升级失败。
ARM MDK中提供了如下两个接口来禁用和开启总中断:
__disable_irq(); // 关闭总中断
__enable_irq(); // 开启总中断
但测试发现这样一个问题,在关闭总中断后,如果有中断触发,虽然此时不会引发中断,但在调用__enable_irq()开启总中断后,MCU会立即处理之前触发的中断。这说明__disable_irq()只是禁止CPU去响应中断,没有真正的去屏蔽中断的触发,中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()开启中断后,由于相应的中断标志没有清空,因而还会触发中断。所以要想禁止所有中断,必须对逐个模块的中断进行Disable操作,由于每个模块中断源有很多,对逐个中断Disable的话比较复杂,较为简单的方法是通过XXX_ClearITPendingBit()清除中断标志或者直接通过XXX_DeInit()来清除寄存器的状态。这样在__enable_irq()开启总中断后,MCU就不会响应之前触发的中断了。

STM32 NVIC_SetPriority()中断优先级

转载自http://bbs.eeworld.com.cn/thread-331983-1-1.html

NVIC_SetPriority(SysTick_IRQn, 0x04)

NVIC_SetPriority(SysTick_IRQn, n);
n=0x00~0x03 设置Systick为抢占优先级0
n=0x04~0x07 设置Systick为抢占优先级1
n=0x08~0x0B 设置Systick为抢占优先级2
n=0x0C~0x0F 设置Systick为抢占优先级3
NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,
所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。
此帖出自stm32/stm8论坛

网上搜索了很多网页,都是这样的说明。其实我是想知道优先级0和优先级1比,谁的优先级更高。

摘自
https://blog.csdn.net/yx_l128125/article/details/9703843
前提条件1:组别优先顺序(第0组优先级最强,第4组优先级最弱):NVIC_PriorityGroup_0>NVIC_PriorityGroup_1>NVIC_PriorityGroup_2>NVIC_PriorityGroup_3>NVIC_PriorityGroup_4