STM32G030C8T6
实验要求
DMA-ADC多通道采集实验 拨动五向按键采集光强光敏电阻实际电压 与五向按键拨动方向 通过 DMA 搬运数据 将数据打印到串口调试工具
实验思路
在按键中断服务程序中启动 ADC 进行采集 ADC 采集结束后自动发起一个 DMA 搬运请求 DMA 请求控制总线,搬移数据,搬移完成之后触发一个搬移完成中断 在 DMA 搬移完成中断回调函数中,打印数据数组中 ADC 采集的两个数值
实物展示
底板
核心板与传感器模块
Light 原理图分析
实物看完了就要看原理图了,通过实物大家应该知道要看那些原理图了吧? 看原理图的同时要对照着实物来使用,因为核心板、传感器模块和底板的标号不一定相同
光敏模块
从电路图可以看出OUT为 A1 从接口可以看出 A1 位于 P1 从上往下第 4 号位
下面要看底板原理图的传感器模块拓展接口(传感器模块底座)
传感器模块底座
底板原理图中的传感器模块拓展接口即光敏模块针脚的底座 P1 从上往下第 4 号位碰巧也是 A1
因为传感器模块(光敏模块)、底板以及核心板都由各自厂家生产,所以原理图上有着各自的标准,一味地按照网络标号 A1 去寻找,无异于刻舟求剑。此处是碰巧了名字一样,这一点一定要谨记。
我们找到了传感器对应的底板的接口(针脚的底座)后 针脚底座通过底板的连接到核心板底座最后连接到核心板上 所以我们下一步就是找与之相对应的核心板对应的底板接口(核心板底座)
核心板底座
A1 在 CON2 右边从下往上第 2 位
这里是直接看 网络标号 ,而不是看位置,大家知道为什么吗? 因为传感器模块底座通过底板上的走线与核心板底座相连,不看 网络标号 难道看电路图吗?哈哈!
下一步看核心板原理图的针脚图
个人习惯叫针脚图,而不是引脚图,最后一步才是看引脚图 看完了底板上的核心板底座,就要看插在核心板底座上的核心板针脚图,对应起来 找到核心板针脚与核心板底板对应的位置
核心板针脚
虽然名字和上图一样都叫核心板底座,但该图是核心板的针脚图,严格意义上来说,核心板底座指的是底板上的核心板底座
找到 CON2 右侧从下往上数第 2 位,其的网络标号为 A1
挺好记的都一样,也是巧合!它只是一个网络标号,完全可以叫别的名字,你如果是核心板厂家,你就不想叫他 A1 ,那它就不是 A1 ,它可以叫 CXK 然后在核心板原理图中找到网络标号 CXK 对应的引脚就是 这里是 A1 是巧合,切记切记切记 传感器针脚和传感器底座也是同理,网络标号不一定一样,如果你不转变思维还是按着网络标号寻找,那…换了个不合群的厂家,你就…有的找了
懂得都懂,不懂得多看两遍,下面就到最后一步了! 根据找到的核心板针脚的网络标号去核心板原理图(引脚图)上找与之网络标号对应的核心板引脚 就完事了!
核心板
不难发现网路标号为 A1 的针脚,其就连在引脚 PA4 上!
Key 原理图分析
五向键ADC略有不同,一起来看看吧
五向按键
五向键是直接焊在底板上的,没有针脚和底板 其ADC数模转换网络标号 为 ADC_KEY ,直接连接到核心板的底座
核心板底座
此处应看对应的网络标号 发现 ADC_KEY 在 CON2 左侧从下往上第 2 位 下面就是核心板针脚图
核心板针脚
核心板针脚图中 CON2 左侧从下往上第 2 位的网络标号也为 ADC_KEY 下面就去核心板原理图找 ADC_KEY 对应的引脚
核心板
不难发现网路标号为 ADC_KEY 的针脚,其就连在引脚 PA1 上!
原理图到这就看完了,下面就是使用 Cube MX 配置环境了
Cube MX 环境配置
串口配置:USART1 - 波特率 - 115200
按键中断:PA8 - GPIO_EXTI8 - NVIC 勾选按键 4-15 中断
五向键ADC采集:PA1 - ADC1_IN1
光敏ADC采集:PA4 - ADC1_IN4
DMA设置: 1. ADC 里 DMA 请求要使能 2. 点击 ADD - ADC 3. CHANNEL 1 方向:外设→内存 4. 模式: 普通(不选择循环) 5. 增量模式: 在内存一侧要打钩 6. 数据传输宽度: 选择半字
代码编写
gpio.c
uint16_t buf[2];
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_8)
{
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)buf, 2);
}
}
adc.c
#include <stdio.h>
#include "usart.h"
#include <string.h>
extern uint16_t buf[2];
int fputc(int ch, FILE* f)
{
while ((USART1->ISR & 1<<7) == 0){}
USART1->TDR = ch;
return ch;
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
printf("key=%d light=%d", buf[0], buf[1]);
HAL_ADC_Stop_DMA(hadc);
memset(buf, 0, sizeof(buf));
}
实现效果
思考
首先恭喜你看完了,祝你有所收获 现在思考一下串口调试助手上显示的值有何意义?是否是正确值?该如何改进呢?
未完待续…
|