2675|9

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

[已解决]STM32开漏输出与上拉输入检测按键 [复制链接]

本帖最后由 nkiy 于 2021-5-17 00:10 编辑

最近遇到个问题想请教下论坛的大佬:

我用STM32F103C8T6做按键检测,需要支持N键无冲,所以是加了二极管的按键矩阵,矩阵电路如下:

其中:

PD0为开漏输出,默认输出1;PB4-7为上拉输入,默认读取值为1。

按键扫描过程:

配置PD0为0,即PD0为低电平(GND?)当SW[N]按下时,PB[N]被拉低,从而检测到按键。

现在的问题是:

如果我按SW1,PB7为低电平没有问题,但是如果我同时按SW1和SW3,PB3-7会都被拉低。导致按键扫描程序认为按下了4个键。

 

我怎么也想不通其中的原理,上来请大佬们给解个惑,感激不尽

此帖出自stm32/stm8论坛

最新回复

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET); uint16_t keys = GPIOB->IDR; 你这样代码下面再定义变量不对或者不规范   详情 回复 发表于 2021-5-14 10:59
点赞 关注
 

回复
举报

5

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

检测代码如下,放在main循环里面或者TIM更新中断里面都不行:

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);
uint16_t keys = GPIOB->IDR;
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_SET);

 

此帖出自stm32/stm8论坛
 
 

回复

6069

帖子

4

TA的资源

版主

板凳
 

查看是否程序有问题?或者是电路有短路现象?

按下SW1和SW3, 而SW2,SW4不按  会影响PB4 PB6?如果程序没问题电路没问题。因为这两个引脚只是内部有个上拉电阻,按键没按下就再无其他。没得道理。

此帖出自stm32/stm8论坛
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

4
 

单独用洞洞板做的按键矩阵,挨个测量过没有短路。

更奇怪的是:当按下1&3时,检测到的是1-4,如果此时用万用表测量2号按键(PB5)到GND的电位,检测到3.x伏,并且同时按键检测回复正常,检测到1&3。

此帖出自stm32/stm8论坛
 
 
 

回复

6069

帖子

4

TA的资源

版主

5
 
本帖最后由 damiaa 于 2021-5-13 12:06 编辑

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);后面稍微加上点延时吧。

因为对PD0的操作刚开始就去观察PB数据,也许电路还没来及跟上变化呢。稍微加点延时。具体多少你自己试试。

另外电路和程序好好查一下。

怪问题 就是有问题。

此帖出自stm32/stm8论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

6
 

好的。

 

我晚上重新搭一套最小系统测试下。业余项目,只能拿业余时间来调试……

此帖出自stm32/stm8论坛
 
 
 

回复

1582

帖子

0

TA的资源

五彩晶圆(初级)

7
 

按键扫描一般是上拉到电源,接二极管的效果不如上拉电阻好

此帖出自stm32/stm8论坛
 
 
 

回复

4005

帖子

0

TA的资源

版主

8
 

不应该啊,PB4在SW4按键没按下时应该和外面电路没关系,肯定是高电平

此帖出自stm32/stm8论坛
 
 
 

回复

4005

帖子

0

TA的资源

版主

9
 

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);

uint16_t keys = GPIOB->IDR;

你这样代码下面再定义变量不对或者不规范

此帖出自stm32/stm8论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

10
 

问题解决了,晚上再次测试发现,设置高电平之后delay 20us左右读取IDR就正常了。

之前可能测试代码写的有问题。

 

附:最终工作代码(节选)

 

//粗延时函数,微秒级。
void delay_us(uint16_t time) {
	uint16_t i = 0;
	while (time--) {
		i = 10;  //自己定义
		while (i--)
			;
	}
}

// 扫键函数,被TIM中断调用,每毫秒一次。
void ScanKeys() {
	/*
	 * 当前使用简单按键扫描,ROW[N] + COL_PORT_ALL_PIN
	 * ROW[N] 默认输出1
	 * COL[N] 默认上拉输入
	 * 当ROW[N]为0时,COL[N]被拉地
	 */
	for (int i = 0; i < ROW_COUNT; i++) {
		ROW_PORT->ODR &= ~ROWS[i]; //设置第i位输出低电平(0)
		delay_us(20);
		CurrentKeys[i] = ~(COL_PORT->IDR); // 读取所有Pin没有HAL函数对应,直接用寄存器。由于默认为IPU,所以直接取反。
		ROW_PORT->ODR |= ROWS[i];
	}
}

 

此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表