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.pswp.cn/web/75560.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75560.shtml
英文地址,請注明出處:http://en.pswp.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…