STM32F103复用JTAG/SWD引脚为GPIO

普中-精灵1开发板,主芯片为STM32F103C8T6,4个独立按键K1~K4依次接PA15~PA12,按下为低电平,8个LED灯D1~D8,依次接PA0~PA7。查询手册得知:PA15主功能为JTDI,PA14为JTCK/SWCLK,PA13为JTMS/SWDIO。采用串口进行程序下载(普中ISP)。用4个按键,控制4个LED,主程序如下:

/*按键程序,普中-精灵1开发板*/
#include "stm32f10x.h"
#include "delay.h"
#include "key.h"
int main(void)
{ KEY_Init();// 初始化 LED 亮灭标志为 0      0:熄灭    1:亮起unsigned int led_flag1 = 0;unsigned int led_flag2 = 0;unsigned int led_flag3 = 0;unsigned int led_flag4 = 0;// 初始化 按键按下标志为 0      0:弹起    1:按下unsigned int key_is_press1 = 0;unsigned int key_is_press2 = 0;unsigned int key_is_press3 = 0;unsigned int key_is_press4 = 0;while (1){ if( key_is_press1 == 0)  //无按键{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) ==0){   // 如果按键按下Delay(20); // 按键消抖if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15)==0 ){   // 如果按键被按下,设置按键按下标志为 1key_is_press1 = 1;// 设置 LED 亮灭标志翻转一次led_flag1 = ~led_flag1;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press1 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15)==0 ){   // 按键仍然处于按下状态,不进行任何操作}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press1 = 0;}}	if( key_is_press2 == 0){if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14) ==0){   // 如果按键按下Delay(20); // 按键消抖if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)==0 ){   // 如果按键被按下,设置按键按下标志为 1key_is_press2 = 1;// 设置 LED 亮灭标志翻转一次led_flag2 = ~led_flag2;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press2 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)==0 ){   // 按键仍然处于按下状态,不进行任何操作}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press2 = 0;}			}				if( key_is_press3 == 0){if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13) ==0){   // 如果按键按下Delay(20); // 按键消抖if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13)==0 ){   // 如果按键被按下,设置按键按下标志为 1key_is_press3 = 1;// 设置 LED 亮灭标志翻转一次led_flag3 = ~led_flag3;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press3 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13)==0 ){   // 按键仍然处于按下状态,不进行任何操作}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press3 = 0;}			}if( key_is_press4 == 0){if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) ==0){   // 如果按键按下Delay(20); // 按键消抖if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)==0 ){   // 如果按键被按下,设置按键按下标志为 1key_is_press4 = 1;// 设置 LED 亮灭标志翻转一次led_flag4 = ~led_flag4;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press4 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)==0 ){   // 按键仍然处于按下状态,不进行任何操作}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press4 = 0;}			}// 根据按键按下的标志状态操作功能// 如果按键被按下了,执行功能if( key_is_press1 == 1){   // 根据 LED 的亮灭标志控制 LED 亮起和熄灭if(led_flag1){// 点亮 LEDGPIO_ResetBits(GPIOA, GPIO_Pin_0 ); }else{// 熄灭 LEDGPIO_SetBits(GPIOA, GPIO_Pin_0 ); }               }if( key_is_press2 == 1){   // 根据 LED 的亮灭标志控制 LED 亮起和熄灭if(led_flag2){// 点亮 LEDGPIO_ResetBits(GPIOA, GPIO_Pin_1 ); }else{// 熄灭 LEDGPIO_SetBits(GPIOA, GPIO_Pin_1 ); }               }	if( key_is_press3 == 1){   // 根据 LED 的亮灭标志控制 LED 亮起和熄灭if(led_flag3){// 点亮 LEDGPIO_ResetBits(GPIOA, GPIO_Pin_2 ); }else{// 熄灭 LEDGPIO_SetBits(GPIOA, GPIO_Pin_2 ); }               }	if( key_is_press4 == 1){   // 根据 LED 的亮灭标志控制 LED 亮起和熄灭if(led_flag4){// 点亮 LEDGPIO_ResetBits(GPIOA, GPIO_Pin_3 ); }else{// 熄灭 LEDGPIO_SetBits(GPIOA, GPIO_Pin_3 ); }               }					}}

按键初始化程序key.c如下:

/*key.c按键初始化
*/
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);  // 开启时钟//GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;       //配置GPIO频率为50MHzGPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 ;	//GPIO_SetBits(GPIOA, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3); 
}

执行以上,会发现K1、K3、K4功能正常,而K2(PA14)无效,此时D2(PA1)常亮,按照手册,若此时禁掉SWD,即去掉GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);前面的注释,此时并无效果,反而有可能出现K1(PA15)、K3(PA13)也失效的情形。此时,需要执行非常关键的一个操作,即对PA12、PA13、PA14、PA15置1,且要在设置MODE之前进行,去掉GPIO_SetBits(GPIOA, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);前面的注释,会发现K2功能也正常了。实际上,如果用CMSIS-DAP(实际为WCH CMSIS-DAP,SW模式,BOOT0=1)下载程序,不需要增加GPIO_SetBits(GPIOA, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);这条指令,K2功能也是正常的。但神奇的是,利用JTAG(实际为J-Link ARM-OB STM32,SW模式,BOOT0=1),则和ISP方式效果一致。

在普中的这款开发板做进一步开发,例如把按键和数码管结合起来,按K1数码管显示加1,按K2减1,按K3数码管左移1位,按K4数码管右移1位。,主程序如下:

/*按键驱动数码管,普中-精灵1开发板*/
#include "stm32f10x.h"
#include "delay.h"
#include "key.h"
uint16_t table[] = {0xFF3F,0xFF06,0xFF5b,0xFF4f,0xFF66,0xFF6d,0xFF7d,0xFF07,0xFF7f,0xFF6f}; //段码
uint16_t  wei[]={0xff00,0xff20,0xff10,0xff30,0xff08,0xff28,0xff18,0xff38}; //位码
static uint8_t k=0;  //声明变量 k,j
static uint8_t j=0;
int main(void)
{   KEY_Init();unsigned int key_is_press1 = 0;unsigned int key_is_press2 = 0;unsigned int key_is_press3 = 0;unsigned int key_is_press4 = 0;while (1){ if( !key_is_press1)  //无按键{if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15)){   // 如果按键按下Delay(20); // 按键消抖if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) ){   // 如果按键被按下,设置按键按下标志为 1key_is_press1 = 1;j=j+1;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press1 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) ) //按键弹起,设置按键按下标志为 0key_is_press1 = 0;}	if( !key_is_press2){if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)){   // 如果按键按下Delay(20); // 按键消抖if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)){   // 如果按键被按下,设置按键按下标志为 1key_is_press2 = 1;j=j-1;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press2 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14) ) // 按键弹起,设置按键按下标志为 0key_is_press2 = 0;}				if( !key_is_press3 ){if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13)){   // 如果按键按下Delay(20); // 按键消抖if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13)){   // 如果按键被按下,设置按键按下标志为 1key_is_press3 = 1;k++;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press3 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13) ) // 按键弹起,设置按键按下标志为 0key_is_press3 = 0;}if(!key_is_press4 ){if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)){   // 如果按键按下Delay(20); // 按键消抖if( !GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) ){   // 如果按键被按下,设置按键按下标志为 1key_is_press4 = 1;k--;}}else{   // 如果按键弹起,设置按键按下标志为 0key_is_press4 = 0;}}else    // 如果按键已经按下了,判断按键是否弹起{if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) ) // 按键弹起,设置按键按下标志为 0key_is_press4 = 0;}GPIO_Write(GPIOA,table[j%8] );GPIO_Write(GPIOB, wei[k%8] );}
}

段码数组要32位数赋值,因为GPIO_Write(GPIOA,...)默认情况下是对整个PA进行操作,如果只给出16位数,那么高16位数将被赋值为0,显然这样就有可能导致读数据失败。参考按键初始化程序:

/*key.c
按键初始化
*/
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);  // 开启时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;       //配置GPIO频率为50MHzGPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 ;	GPIO_SetBits(GPIOA, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_SetBits(GPIOA, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure);
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

难度偏低,25西电人工智能学院821、833、834考研录取情况

1、人工智能学院各个方向 2、人工智能学院近三年复试分数线对比 学长、学姐分析 由表可看出: 1、智能院25年院线相对于24年院线 全部专业下降比较多,其中控制科学与工程下降20分,计算机科学与技术下降20分,计算机技术[专硕]下降…

达梦数据校验系统(DMDVS):数据完整性保障的不二之选

产品概述 达梦数据校验系统(DMDVS)是一款企业级数据一致性管理平台,提供跨数据库、跨平台的数据比对与修复能力。系统采用模块化架构设计,支持静态校验、动态校验、单向校验及分布式校验四大核心模式,适用于数据迁移验证、容灾备份核查、实时同步监控等关键场景,👉更多…

【3dSwap】3D-Aware Face Swapping

文章目录 3D-Aware Face Swapping背景points贡献方法从2D图像推断3D先验通过潜在代码操纵进行人脸交换联合枢轴调整目标函数实验与二维人脸交换方法比较进一步分析3D感知人脸交换消融实验局限性3D-Aware Face Swapping 会议/期刊:CVPR 2023 作者: code:https://lyx0208.gi…

客户案例 | 日事清×初心家居:多部门协作实现新品上架自动化

1、客户背景 佛山市初心家居有限公司,主营家居类目,年营收额近亿元。初心家居有自己的家居生产工厂(可为第三方提供生产),店内产品均为自主研发设计,所以新品开发也是初心家居的核心。 2、客户工作场景及需…

KWDB创作者计划—KWDB多副本集群保姆级部署

📢📢📢📣📣📣 作者:IT邦德 中国DBA联盟(ACDU)成员,10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主,全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

micro ubuntu 安装教程

micro ubuntu 安装教程 官网地址 : https://micro-editor.github.io 以下是在 Ubuntu 系统中安装 micro 编辑器 的详细教程: 方法 1:通过 ​apt​​ 直接安装(推荐) 适用于 Ubuntu 20.04 及以上版本(官方仓库已收录…

Docker 镜像 的常用命令介绍

拉取镜像 $ docker pull imageName[:tag][:tag] tag 不写时,拉取的 是 latest 的镜像查看镜像 查看所有本地镜像 docker images or docker images -a查看完整的镜像的数字签名 docker images --digests查看完整的镜像ID docker images --no-trunc只查看所有的…

从零搭建微服务项目Pro(第0章——微服务项目脚手架搭建)

前言: 在本专栏Base第0章曾介绍一种入门级的微服务项目搭建,尽管后续基于此框架上实现了Nacos、Eureka服务注册发现、配置管理、Feign调用、网关模块、OSS文件存储、JSR参数校验、LogBack日志配置,鉴权模块、定时任务模块等,但由于…

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇:IntelliJ IDEA下开发FPGA-CSDN博客 Type:Quartus 一、安装插件 在应用商店先安装Digtal IDE插件 安装后,把其他相关的Verilog插件禁用,避免可能的冲突。重启后,可能会弹出下面提示 这是插件默认要求的工具链&a…

使用Python从零开始构建端到端文本到图像 Transformer大模型

简介:通过特征向量从文本生成图像 回顾:多模态 Transformer 在使用Python从零实现一个端到端多模态 Transformer大模型中,我们调整了字符级 Transformer 以处理图像(通过 ResNet 特征)和文本提示,用于视觉…

Webpack中的文件指纹:给资源戴上个“名牌”

你是否想过,当你修改代码后,浏览器为什么仍然拿着旧版资源不放?秘密就在于——文件指纹!简单来说,文件指纹就像给每个构建出来的文件贴上独一无二的“姓名牌”,告诉浏览器:“嘿,我更…

python可变对象与不可变对象

文章目录 Python 中的可变对象与不可变对象不可变对象(Immutable Objects)可变对象(Mutable Objects)重要区别 Python 中的可变对象与不可变对象 在 Python 中,对象可以分为可变对象(mutable)和不可变对象(immutable),这是 Python 中非常重要的概念&…

DeepSeek私有化部署性能怎么样?企业级AI落地实战解析!

1. 私有化部署是什么?为什么企业需要它? 很多公司在考虑用AI时都会问:“DeepSeek私有化部署性能怎么样?能不能在我们自己的服务器上跑?” 私有化部署的意思就是把AI模型装在你自己的机房或者云服务器上,而…

SQL学习--基础语法学习

SQL和excle对比 学习目标 单表查询 项目背景 SQL 练习环境 SQL Online Compiler - Next gen SQL Editor 商品信息表:https://study-zhibo.oss-cn-shanghai.aliyuncs.com/test/%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF%E8%A1%A8.csv 订单明细表:https://…

【Docker基础-网络】--查阅笔记4

目录 Docker 网络网络类型none 网络host 网络bridge 网络自定义网络 容器间通信IP 通信Docker DNS Serverjoined 容器 容器与外部通信容器访问外部外部访问容器 Docker 网络 学习Docker提供的几种原生网络如何创建自定义网络容器间通信,容器于外界交互 Docker 安装…

GPT模型架构与文本生成技术深度解析

核心发现概述 本文通过系统分析OpenAI的GPT系列模型架构,揭示其基于Transformer解码器的核心设计原理与文本生成机制。研究显示,GPT模型通过自回归机制实现上下文感知的序列生成,其堆叠式解码器结构配合创新的位置编码方案,可有效…

AWTK-MVVM 如何让多个View复用一个Model记录+关于app_conf的踩坑

前言 有这么一个业务,主界面点击应用窗口进入声纳显示界面,声纳显示界面再通过按钮进入菜单界面,菜单界面有很多关于该声纳显示界面的设置项,比如量程,增益,时间显示,亮度,对比度等…

CrystalDiskInfo电脑硬盘监控工具 v9.6.0中文绿色便携版

前言 CrystalDiskInfo是一个不用花钱的硬盘小帮手软件,它可以帮你看看你的电脑硬盘工作得怎么样,健不健康。这个软件能显示硬盘的温度高不高、还有多少地方没用、传输东西快不快等等好多信息。用了它,你就能很容易地知道硬盘现在是什么情况&…

数据分析-数据预处理

数据分析-数据预处理 处理重复值 duplicated( )查找重复值 import pandas as pd apd.DataFrame(data[[A,19],[B,19],[C,20],[A,19],[C,20]],columns[name,age]) print(a) print(--------------------------) aa.duplicated() print(a)只判断全局不判断每个 any() import p…

如何用海伦公式快速判断点在直线的哪一侧

一、海伦公式的定义与推导 1. 海伦公式的定义 海伦公式(Heron’s Formula)是用于计算三角形面积的一种方法,适用于已知三角形三边长度的情况。公式如下: S s ( s − a ) ( s − b ) ( s − c ) S \sqrt{s(s - a)(s - b)(s - c…