闫刚 stm32-spi-DMA使用注意

本文详细介绍了STM32微控制器中SPI接口DMA模式的使用注意事项,包括DMA数据传输流程,配置步骤,以及避免SPI死机的策略。强调了在DMA传输过程中TXE和RXNE标志的重要性,以及如何正确配置DMA发送和接收中断。

资源

stm32_spi_dma.md
闫刚 stm32-spi-DMA使用注意

Stm32的spi的DMA过程

安装

  1. DMA先把数据发送到SPI1->DR, TXE位被清除
  2. 最后1个TXE,不会被DMA清除,发送完成数据,并不是接收最后1个字节发送完成
  3. DMA为什么连续,不是TC能做到的,需要TXE把数据提前准备好
  4. 发送DMA和DMA都需要配置, 仅仅DMA接收完成作为,作为完成表示,DMA发送完成标志需要手动清除. 无需管TXE, RNXE的标志

spi死机的原因

出现spi死机的问题,我们需要打开DMA2时钟

<think> 我们正在讨论Qt6中的信号(Signal)和槽(Slot)机制。根据引用内容,我们可以总结以下几点: 1. 信号和槽是Qt的核心机制,用于对象之间的通信(引用[1])。 2. 在Qt6中,通常推荐使用成员函数指针的方式连接信号和槽,而不是使用SIGNAL和SLOT宏(引用[3])。 3. 使用SIGNAL和SLOT宏时,需要注意信号和槽的参数兼容性(引用[2][3])。 4. 连接方式(ConnectionType)会影响信号发送时槽函数的执行线程(引用[4])。 下面我们将详细展开这些内容。 ### 信号和槽的基本概念 信号和槽是Qt中对象间通信的一种机制。当某个对象的状态改变时,它可以发射一个信号,而其他对象可以通过槽来接收这个信号并作出响应。这种机制是类型安全的,并且松散耦合。 ### Qt6中信号和槽的使用 #### 1. 使用成员函数指针(推荐方式) 在Qt5和Qt6中,推荐使用成员函数指针来连接信号和槽。这种方式在编译时检查类型,更安全。 示例: ```cpp connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue); ``` #### 2. 使用SIGNAL和SLOT宏(旧式,不推荐) 在Qt6中仍然支持旧式的宏连接方式,但这种方式在运行时检查,且容易出错。 示例: ```cpp connect(sender, SIGNAL(valueChanged(int)), receiver, SLOT(updateValue(int))); ``` 注意使用宏时,信号参数个数不能少于槽参数个数(引用[2]),否则运行时将报错(引用[3])。 ### 信号和槽的连接方式 Qt提供了几种连接类型(ConnectionType),它们决定了槽函数在哪个线程执行: - `Qt::AutoConnection`(默认):如果信号和槽在同一线程,则使用`Qt::DirectConnection`;否则使用`Qt::QueuedConnection`。 - `Qt::DirectConnection`:槽函数在信号发射的线程中立即执行。 - `Qt::QueuedConnection`:槽函数在接收者所在线程的事件循环中执行(跨线程时使用)。 - `Qt::BlockingQueuedConnection`:类似于队列连接,但是信号发射线程会阻塞直到槽函数执行完毕(仅用于跨线程且需要同步的情况)。 示例(指定连接方式): ```cpp connect(this, &Widget::sendStr, &subThread, &SubThread::showStr, Qt::QueuedConnection); ``` ### 信号和槽的原理 信号和槽的实现基于Qt的元对象系统(Meta-Object System),该系统通过moc(元对象编译器)预编译头文件生成额外的代码来实现反射和信号槽机制。 当使用`connect`函数连接信号和槽时,Qt会记录发送者、接收者以及信号和槽的索引。当发射信号时,Qt会根据连接类型调用相应的槽函数。 ### 注意事项 1. 使用成员函数指针连接时,信号和槽的参数类型必须匹配,或者槽的参数可以比信号少(忽略多余的参数)。 2. 使用旧式宏连接时,信号参数的数量必须不少于槽参数的数量,否则运行时出错(引用[3])。 3. 跨线程通信时,必须使用队列连接(`Qt::QueuedConnection`)或阻塞队列连接(`Qt::BlockingQueuedConnection`),以确保槽函数在接收者线程执行(引用[4])。 ### 总结 在Qt6中,推荐使用成员函数指针的方式连接信号和槽,这种方式更安全且高效。同时,理解连接类型对于多线程编程至关重要。 [^1]: Python Qt6快速入门-Signal与Slot [^2]: 【Qt】信号和槽机制 Signal & Slot [^3]: qt6 connect函数调用中使用SIGNAL、SLOT宏 和 使用成员函数指针的区别及原理 [^4]: 闫刚 QT多线程signal和slot连接方式原理 §§相关问题§§ 1. Qt6中信号和槽的连接方式有哪些?它们有什么区别? 2. 在Qt6中,如何使用成员函数指针连接信号和槽? 3. 为什么在Qt6中推荐使用成员函数指针而不是宏来连接信号和槽? 4. 在多线程编程中,信号和槽的连接方式如何选择? </think> ### Qt6中的信号(Signal)与槽(Slot)机制 #### 1. **基本概念** 信号和槽是Qt的核心通信机制,用于实现对象间的松耦合交互: - **信号(Signal)**:事件发生时由对象发出的通知(如按钮点击) - **槽(Slot)**:响应信号的函数(如处理点击事件) - **连接(Connect)**:通过`QObject::connect()`建立信号与槽的关联 在Qt6中推荐使用**成员函数指针**的现代语法: ```cpp connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName); ``` #### 2. **连接原理** ```mermaid graph LR A[信号发出对象] -- connect绑定 --> B[槽函数对象] C[事件发生] --> A A -->|发射信号| D[信号队列] D -->|事件循环| B ``` - **线程安全**:自动处理跨线程通信(通过`Qt::QueuedConnection`) - **元对象系统**:依赖moc(Meta-Object Compiler)生成的元信息 #### 3. **参数传递规则** ```cpp // 正确示例(槽函数参数≤信号参数) connect(btn, &QPushButton::clicked, // 信号无参数 label, &QLabel::clear); // 槽函数无参数 // 错误示例(运行时崩溃) connect(obj, SIGNAL(sig(int)), // 信号1个参数 obj, SLOT(slot(int, int))); // 槽需2个参数[^3] ``` #### 4. **连接类型对比** | 连接类型 | 执行线程 | 适用场景 | |----------------------|---------------|----------------------------| | `Qt::DirectConnection` | 发送者线程 | 单线程内同步调用 | | `Qt::QueuedConnection` | 接收者线程 | **跨线程通信**(最常用)[^4] | | `Qt::AutoConnection` | 自动选择 | 默认模式(根据线程判断) | #### 5. **实际应用示例 ```cpp // 创建按钮和标签 QPushButton *btn = new QPushButton("Click"); QLabel *label = new QLabel("Hello"); // 现代语法连接(推荐) connect(btn, &QPushButton::clicked, label, &QLabel::clear); // 旧式宏语法(Qt6仍兼容但不推荐) connect(btn, SIGNAL(clicked()), label, SLOT(clear())); ``` #### 6. **底层实现机制 1. **moc预处理**:扫描含`Q_OBJECT`的类头文件 2. **生成元信息**:创建`moc_*.cpp`存储信号/槽签名 3. **信号发射**:调用`QMetaObject::activate()` 4. **槽查找**:通过元对象系统匹配接收者 > ⚠️ 注意事项: > - 旧式宏语法(`SIGNAL()/SLOT()`)在参数不匹配时**编译通过但运行时报错**[^3] > - 多线程场景必须使用`Qt::QueuedConnection`避免竞争条件[^4] [^1]: Python Qt6快速入门-Signal与Slot [^2]: 【Qt】信号和槽机制 Signal & Slot [^3]: qt6 connect函数调用中使用SIGNAL、SLOT宏的区别 [^4]: QT多线程signal和slot连接方式原理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值