主頁 > 軟體設計 > STM32F103五分鐘入門系列(一)跑馬燈(庫函式+暫存器)+加編程模板+GPIO總結

STM32F103五分鐘入門系列(一)跑馬燈(庫函式+暫存器)+加編程模板+GPIO總結

2021-04-30 14:45:29 軟體設計

學習板:STM32F103ZET6

跑馬燈實驗

  • 前言
  • 一、GPIO
    • 1、GPIO種類
    • 2、GPIO輸入輸出的8種模式:
    • 3、模式用途
  • 二、點亮LED(庫函式版)
    • 1、庫函式的由來
    • 2、點亮LED庫函式版撰寫順序
      • 1、GPIO_Init()
      • 2、RCC_APB2PeriphClockCmd()
      • 3、將配置函式放在led.c和led.h檔案
  • 三、點亮LED(暫存器版本)
    • 1、新建工程、添加led檔案
    • 2、配置時鐘
    • 3、GPIO配置
    • 4、主函式代碼撰寫
  • 附1 PXout()與PXin()

前言

本來準備先總結一下GPIO、幾種輸入輸出模式以及配置方法、暫存器種類、時鐘及分頻等,但是想了想,還是算了,一步步的來,到時候用到再總結吧 ,不然前面總結了,后面用到還得回顧,

至于前面的安裝庫、安裝軟體、Keil中添加檔案等,就不在總結了,因為這些根本并不需要記的,新手可以去跟著視頻走一遍,學習程序中,不用每次都自己去新建工程,直接將官方給的模板拷過來,修改一下檔案夾名稱即可,
在這里插入圖片描述

一、GPIO

1、GPIO種類

本博板子STM32F103ZET6共有7組IO口,每組16個,共16×7=112個,分別為:
GPIOA——>PA0、PA1、PA2…PA15
GPIOB——>PB0、PB1、PB2…PB15
.
.
.
GPIOG——>PG0、PG1、PG2、…PG15

2、GPIO輸入輸出的8種模式:

程式中標識模式
GPIO_Mode_AIN模擬輸入
GPIO_Mode_IN_FLOATING浮空輸入
GPIO_Mode_IPD下拉輸入
GPIO_Mode_IPU上拉輸入
GPIO_Mode_Out_OD開漏輸出
GPIO_Mode_Out_PP推挽輸出
GPIO_Mode_AF_OD復用開漏輸出
GPIO_Mode_AF_PP復用推挽輸出

3、模式用途

1、 GPIO_Mode_AIN :模擬輸入
一般用于ADC模擬輸入

2、GPIO_Mode_IN_FLOATING :浮空輸入
可用于按鍵KEY實驗、發送接收信號RX、TX等,不過這些實驗可以不用浮空輸入,如KEY用到上拉和下拉

3、GPIO_Mode_IPD:下拉輸入
4、GPIO_Mode_IPU:上拉輸入
IO內部上拉電阻、下拉電組輸入,使情況而定,比如剛剛說的key按鍵實驗,原理圖如下:

在這里插入圖片描述

可以看到KEY_UP按下后,IO口應該是3V3電平輸入,使用上拉輸入模式,接到GPIO的上拉電阻,芯片可以更好的檢查到高電平輸入,

KEY0~2按下后,IO口是低電平輸入,使用下拉輸入模式,接到GPIO的下拉電阻后,芯片可以更好的檢查到低電平輸入,

5、GPIO_Mode_Out_OD:開漏輸出
IO 輸出 0 接 GND,IO 輸出 1,懸空,需要外接上拉電阻,才能實作輸出 高電平,當輸出為 1 時,IO 口的狀態由上拉電阻拉高電平,但由于是開漏輸出模式,這樣 IO 口也就可以 由外部電路改變為低電平或不變,該模式適合做電流型的驅動,吸收電流能力比較強,

6、GPIO_Mode_Out_PP:推挽輸出
可以輸出高、低電平,導通損耗小、效率高,既提高電路的負載能力,又提高開關速度,廣泛各種實驗,比如接下來要總結的LED,

7、GPIO_Mode_AF_OD:復用開漏輸出
當GPIO為復用IO時的開漏輸出模式,一般用于外設功能,如TX1

8、GPIO_Mode_AF_PP:復用推挽輸出
當GPIO為復用IO時的推挽輸出模式,一般用于外設功能,如I2C

二、點亮LED(庫函式版)

1、庫函式的由來

在學習庫函式之前,應該明白,STM32F1用的是Cortex-M3芯片,是由ARM公司設計的,所以芯片的標準是由ARM公司制定的,芯片內核架構有ARM公司提供,而我們現在用的STM32由ST公司生產,所以關系是:ARM制定內核架構,ST等芯片公司根據ARM公司的標準設計了芯片,ST等公司設計的芯片,不同的是存盤容量、外設、串口數量等等,

以本博的學習板STM32F103ZET6為例,韌體庫(庫函式的集合)是由官方提供的,這個官方是ST公司,而不是正點原子官方,也就是說不僅僅這一型號單片機,ST系列其他型號的單片機庫函式依舊可以適用,所以不必擔心更換板子后不知如何去編程,

ST公司推出官方韌體庫,將底層暫存器操作都封裝起來,形成一套介面(API)供我們使用,大多數情況下我們不必去考慮底層暫存器,比如本博的LED,只需呼叫GPIO配置函式、時鐘配置函式,然后主函式初始化后,直接給引腳賦值就可以實作LED的亮滅,而不用去考慮暫存器如何作業的,當然本博會把暫存器版的LED也總結一下,畢竟想要真正理解單片機,還得去真正理解暫存器,庫函式版只是讓我們停留在“會使用”,當然,對應大多數人來講,“會使用”已經完全足夠了,

2、點亮LED庫函式版撰寫順序

1、設定時鐘
2、設定GPIO

只要這兩步的配置,再在主函式中給對應引腳傳輸高低電平即可,

打開原理圖檔案(下圖我打開了6個檔案,都是需要的,而且大部分情況下,有這6個檔案足以,都在板子附帶資料的檔案夾里
在這里插入圖片描述
在這里插入圖片描述

從原理圖中得到以下資訊:

①DS0 LED0陽極接+,陰極接PB5;DS1 LED1陽極接+,陰極接PE5,

②SYS LED由名稱“PWR”顧名思義,為電源指示燈,所以單片機接通電源后,電源指示燈常亮,

③芯片的PB5引腳軟體置0后,LED0亮;PE5引腳軟體置0后,LED1亮,

所以要配置GPIOB(因為PB5)和GPIOE(因為PE5),

然后是時鐘設定,只要是對GPIO操作,就必須進行時鐘配置(而且時鐘配置在前),GPIO是掛載在APB2總線上的外設,所以在對GPIO的時鐘進行設定時,通過函式RCC_APB2PeriphClockCmd()來實作,

下面進入實戰:

打開模板檔案:(時間久遠了,不知道模板檔案原來放哪個檔案夾下,找不到的話可以把LED官方例程打開,關于LED的.c和.h檔案刪掉,主函式清空,就可以當以后的模板來用了,不用每次都創建工程)
在這里插入圖片描述在這里插入圖片描述

首先查看GPIO配置函式,既然是GPIO,那么先找一下頭檔案,在main.c下找GPIO頭檔案,并點擊進入,

在這里插入圖片描述

在這里插入圖片描述

找到對應函式:(下一博客總結所有GPIO函式的用法、以及延時函式)

在這里插入圖片描述

上圖示注,GPIO_Init()函式初始化,進行設定GPIO,GPIO_SetBits()函式給對應引腳置1,GPIO_ReSetBits()函式給對應引腳置0,

1、GPIO_Init()

右鍵選中函式,點擊【Go to Definition of …】,進入函式詳細說明
在這里插入圖片描述在這里插入圖片描述

可以看到,函式的形參有兩個,而且都是指標,進入第一個形參“型別”

在這里插入圖片描述
在這里插入圖片描述

看到GPIOx指標是指向上圖這個結構體的,也就是每組GPIO都包含的7個暫存器,

比如LED實驗,傳遞GPIOB(PB5)過來后,*GPIOB就指向這七個暫存器,初始化函式就是對七個暫存器的操作,不過被庫函式封裝起來了,emmmm…說太多了,只要知道GPIO_Init()傳過來的第一個引數表示對該組GPIO配置就行了,

察看第二組形參“型別”

在這里插入圖片描述
在這里插入圖片描述
看到第二個形參也是結構體指標,指向的結構體含有三個引數GPIO_Pin、GPIO_Speed、GPIO_Mode

到這里就可以用C++語法來說明了,比如第二個形參是a(注意是指標),那么:
a.GPIO_Pin=…
a.GPIO_Speed=…
a.GPIO_Mode=…
就完成了對引數GPIO引數的設定,

接下來我們再看看上面三個賦值陳述句的右邊究竟是什么東西:
轉回到初始化函式:

在這里插入圖片描述
在這里插入圖片描述1表示第二個形參
2表示對 GPIO_Init()的第一個形參的處理(就是那個結構體里有7個暫存器的東西)
3表示mode的配置
4表示pin的配置
5表示速speed的配置,

點開GPIO_Mode設定函式:

在這里插入圖片描述

可以看到就是我們第一大部分總結的8中輸入輸出模式

在這里插入圖片描述

點開pin設定函式

在這里插入圖片描述

可以看到pin是我們第一大部分總結的一組GPIO的15個IO口

在這里插入圖片描述

點開速度設定函式

在這里插入圖片描述

可以看到速度可設定的值:

在這里插入圖片描述
到這里,GPIO的設定函式應該會寫了:

第一步:設定形參1和形參2
第二步:上面那三個賦值陳述句的設定
第三步:運行GPIO_Init()函式

程式:(先在主函式中書寫,.c檔案中書寫接下來會總結

	GPIO_TypeDef GPIO_B;//形參1
	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(&GPIO_B,&GPIO_InitStruct);

注意GPIO_Init()傳遞的是指標,所以應該用取地址符“&”,

上面的程式還是有問題的,因為定義了GPIO_B為第一個引數,但是程式并不知道GPIO_B是對GPIOB的操作,所以在 GPIO_Init(&GPIO_B,&GPIO_InitStruct);陳述句中,“&GPIO_B”應該是真正的、物理上的地址,而不能像引數2一樣,只是程式定義引數時分配的地址,

輸入“GPIOB”,并進入

在這里插入圖片描述

發現官方真的定義了GPIOB,而且還是真正的、物理層的地址

在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述

所以之前程式中的GPIO_B可以刪掉了,不是物理層的地址,定義了、傳遞給GPIO_Init()函式也沒用,

正確完整程式:

//GPIO_TypeDef GPIO_B;//形參1
	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
		
	 //注意GPIOB是地址!GPIO_InitStruct是指標,傳遞過去后的倆個實引數都是指標,

以上配置了GPIOB是為了點亮LED0,現配置LED1(PE5)的GPIO,參考上面的程式:

	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
		
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	

因為之前設定了mode和speed,而實參2是沒有指向的,即并不能知道實參2屬于實參1,所以哪怕再重新定義一個GPIOE的實參2,重新定義mode和speed也沒有意義,所以就可以省略了,

接下來可以將LED引腳置高電平,熄滅LED,使初始狀態下LED是滅的,

int main(void)
 {	
	
	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
		
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	 
	GPIO_SetBits(GPIOB, GPIO_Pin_5);
	GPIO_SetBits(GPIOE, GPIO_Pin_5);
	
 }

2、RCC_APB2PeriphClockCmd()

之前說過,GPIO是掛載在APB2總線上的外設,所以在對GPIO的時鐘進行設定時,通過函式RCC_APB2PeriphClockCmd()來實作,打開RCC.h頭檔案,找到時鐘函式

在這里插入圖片描述

同樣的方法確定形參型別

在這里插入圖片描述

在這里插入圖片描述

形參1:

在這里插入圖片描述

形參2:

在這里插入圖片描述

所以程式:(注意時鐘配置函式應該放在最前面

	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE , ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
		
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	 
	GPIO_SetBits(GPIOB, GPIO_Pin_5);
	GPIO_SetBits(GPIOE, GPIO_Pin_5);

加入延時函式,形成流水燈:(只在Main.c檔案編程)
其中GPIO_SetBits(GPIOB, GPIO_Pin_5)是將PB5引腳置1;GPIO_ReSetBits(GPIOB, GPIO_Pin_5)是將PB5引腳置0
(是通過庫函式對BSRR和BRR暫存器操作完成置0置1,下一博客會涉及到)

#include "stm32f10x.h"
#include "delay.h"
 int main(void)
 {	
	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE , ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
		
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	 
	GPIO_SetBits(GPIOB, GPIO_Pin_5);
	GPIO_SetBits(GPIOE, GPIO_Pin_5);
	
	 delay_init();	    //延時函式初始化	  
	while(1)
	{
		GPIO_SetBits(GPIOB, GPIO_Pin_5);
		GPIO_SetBits(GPIOE, GPIO_Pin_5);
		delay_ms(1000);                       //注意包含頭檔案delay.h,這個好像是正點原子官方寫的
		GPIO_ResetBits(GPIOB, GPIO_Pin_5);
		GPIO_ResetBits(GPIOE, GPIO_Pin_5);
		delay_ms(1000); 
	}
 }

3、將配置函式放在led.c和led.h檔案

在LED使用的工程檔案夾新建一個LED檔案夾

在這里插入圖片描述

進行下一步驟:

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述

在這里插入圖片描述

創建一個text檔案,命名為led.h,保存在LED group中

在這里插入圖片描述

將頭檔案添加進來

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述

同理,新建一個led.c檔案,將.c檔案也添加進來

在這里插入圖片描述

上述步驟是創建一個LED Group,現在將頭檔案添加進來:

在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述

找到剛剛創建的檔案夾并添加

在這里插入圖片描述
上述步驟是為了之后呼叫里面生成的led.c和led.h

編輯頭檔案:
固定格式:

#ifndef  一個未定義字串
#define 一個未定義字串

#include ...
#include ...  //各種需要在本.h檔案中用到的頭檔案
...
...//一些函式宣告、甚至定義	 				    
#endif

本實驗led.h檔案可這樣寫:

#ifndef __LED_H //led.h檔案
#define __LED_H	 
void LED_Init(void);//初始化 				    
#endif

接下來編輯led.c檔案
需要有本.c檔案用到的頭檔案,如果要用到別的檔案中定義的變數,可以采用外部宣告重新宣告該變數,在.c檔案實作.h檔案宣告的函式

將我們之前main函式中關于GPIO配置和時鐘宣告的函式移植過來得到完整的LED程式:

在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述

/**led.h**/
#ifndef __LED_H //led.h檔案
#define __LED_H	 
void LED_Init(void);//初始化 		
#endif

/**led.c**/
#include "led.h"
#include "stm32f10x.h"
void LED_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;//形參2
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE , ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	GPIO_SetBits(GPIOB, GPIO_Pin_5);
	GPIO_SetBits(GPIOE, GPIO_Pin_5);
}

/**main.c**/
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
 int main(void)
 {	
	LED_Init();
	delay_init();	    //延時函式初始化	  
	while(1)
	{
		GPIO_SetBits(GPIOB, GPIO_Pin_5);
		GPIO_SetBits(GPIOE, GPIO_Pin_5);
		delay_ms(1000);                       //注意包含頭檔案delay.h,這個好像是正點原子官方寫的
		GPIO_ResetBits(GPIOB, GPIO_Pin_5);
		GPIO_ResetBits(GPIOE, GPIO_Pin_5);
		delay_ms(1000); 
	}
 }

三、點亮LED(暫存器版本)

1、新建工程、添加led檔案

畢竟是32系列第一個博客,還是希望詳細一點,之后的實驗就會慢慢省略一部分東西,暫存器版本完整來一遍

打開模板檔案,如果沒有,就把LED庫函式例程打開,刪掉led.c和led.h,當做以后所有實驗的模板就行了,

一般情況下,應該【HARDWARE】中創建.c檔案,也可以在檔案【HARDWARE】之外建,看個人習慣,

如果懶得去搞模板,就用我這個吧

先將模板檔案拷過來,在HARDWARE檔案夾下創建LED檔案夾

在這里插入圖片描述

打開模板檔案

在這里插入圖片描述

新建兩個text檔案,保存在剛剛創建的LED檔案夾下,并改名為led.c、led.h

在這里插入圖片描述

將led.c檔案添加進工程

在這里插入圖片描述在這里插入圖片描述

將LED檔案目錄添加進來

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述
現在進入實戰

led.h編輯,之前庫函式版本講過了,直接附代碼:

#ifndef LED_H  //led.h檔案
#define LED_H
int LED_Init(void);
#endif

led.c檔案編輯
開始還是老規矩:

#include "led.h"
#include "stm32F10x.h"

int LED_Init(void)
{

}

2、配置時鐘

打開《STM32中文參考手冊》7.3.7 APB2外設時鐘使能暫存器(RCC_APB2ENR)

在這里插入圖片描述在這里插入圖片描述

暫存器下一博客總結,現在只需知道,APB2外設時鐘使能暫存器的第3位和第6位分別對應GPIOB(LED0、DS0)和GPIOE(LED1、DS1)

時鐘使能代碼如下:

RCC->APB2ENR|=1<<3;
RCC->APB2ENR|=1<<6;

解釋一下:

首先RCC->APB2ENR是對外設時鐘使能暫存器的訪問
在這里插入圖片描述

RCC->APB2ENR|=1的意思是:RCC->APB2ENR=RCC->APB2ENR|0x00000001(32位暫存器),也就是說將該暫存器的第0位軟體置1,其它位保持不變,"<<3"是將剛剛設定的那個第0位的1左移3位,也就是此時第3位為1.同理“<<6”是將第6位設定為1;此時就使能了GPIOB和GPIOE的時鐘

在這里插入圖片描述

3、GPIO配置

用到埠配置暫存器,由于是對PB5、PE5的配置,是低位IO口(Px0~Px7是低位、Px8 ~Px15是高位),所以用到埠配置低暫存器GPIOx_CRL

打開《STM332中文參考手冊》
在這里插入圖片描述

看到第21、20位控制模式和速度,為50M輸出,所以這兩位是11;23 、22控制哪種輸出,為推挽輸出,所以這兩位為00,所以GPIOx_CRL的狀態值為:0x00300000;程式如下:

    GPIOB->CRL&=0xff0fffff; //PB5
	GPIOB->CRL|=0x00300000;
	
	GPIOE->CRL&=0xff0fffff; //PE5
	GPIOE->CRL|=0x00300000;

解釋一下:

GPIOB->CRL&=0xff0fffff 是將GPIOB的20、21、22、23這四位置0,其它位保持不變;

GPIOB->CRL|=0x00300000是將GPIOB的20、21、22、23這四位置1,其它位保持不變;

此時配置好了,然后可以給IO口賦初值,如開始時讓LED處于熄滅狀態,則PB5、PE5均置1,用到的暫存器:埠輸出資料暫存器GPIOx_ODR

在這里插入圖片描述

代碼:

	GPIOB->ODR|=1<<5;
	GPIOE->ODR|=1<<5;

led.c檔案完整代碼:

#include "led.h" //led.c檔案
#include "stm32F10x.h"
int LED_Init(void)
{
	RCC->APB2ENR|=1<<3;
	RCC->APB2ENR|=1<<6;
	
	GPIOB->CRL&=0xff0fffff; //PB5
	GPIOB->CRL|=0x00300000;
	
	GPIOE->CRL&=0xff0fffff; //PE5
	GPIOE->CRL|=0x00300000;
	
	GPIOB->ODR|=1<<5;
	GPIOE->ODR|=1<<5;
}

4、主函式代碼撰寫

進入主函式后,首先應呼叫剛剛寫的LED初始化函式,完成GPIO配置;程式會用到延時函式,將延時函式也初始化,代碼:(頭檔案包含led.h)

	#include "sys.h"
	#include "delay.h"
	#include "led.h"
	
	 int main(void)
	 {	
		LED_Init();
		delay_init();
	 }

然后在死回圈中,對PB5和PE5 IO口賦值就行了,還是用到埠輸出資料暫存器GPIOx_ODR

不過給IO口置0時,需要注意,應該和0xffffffdf進行與運算
在這里插入圖片描述

	GPIOB->ODR&=0xffffffdf;//置0
	GPIOE->ODR&=0xffffffdf;//置0

或者移位運算,將第0位置0再向左移5位

	GPIOB->ODR&=0xfffffffe<<5;
	GPIOE->ODR&=0xfffffffe<<5;

給IO口置1就和0x00000020進行或運算

在這里插入圖片描述

 	GPIOB->ODR|=0x00000020;
	GPIOE->ODR|=0x00000020;

或者直接位移運算,先和0x00000001進行或運算,使第0位置1,再將第0位向左移動5,代碼:

	GPIOB->ODR|=1<<5;
	GPIOE->ODR|=1<<5;

main.c檔案完整程式:

#include "sys.h" //main.c檔案
#include "delay.h"
#include "led.h"

 int main(void)
 {	
	LED_Init();
	delay_init();
	 while(1)
	 {
		GPIOB->ODR&=0xffffffdf;//置0
		GPIOE->ODR&=0xffffffdf;//置0
		//GPIOB->ODR&=0xfffffffe<<5;
		//GPIOE->ODR&=0xfffffffe<<5;
		 
		 delay_ms(1000);
		
		 GPIOB->ODR|=0x00000020;
		 GPIOE->ODR|=0x00000020;
		//GPIOB->ODR|=1<<5;
		//GPIOE->ODR|=1<<5;
		delay_ms(1000);
	 }
 }


附1 PXout()與PXin()

打開sys.h頭檔案

在這里插入圖片描述
定義了PXout()與PXin()函式,用法為:

點亮熄滅DS0、DS1,只需:

PBout(5)=0;//點亮
PEout(5)=0;//點亮
delay_ms(1000);
PBout(5)=1;//熄滅
PEout(5)=1;//熄滅
delay_ms(1000);

或者定義:

#define LED0 PBout(5)
#define LED1 PEout(5)

LED0=0;//點亮
LED1=0;//點亮
delay_ms(1000);
LED0=1;//熄滅
LED1=1;//熄滅
delay_ms(1000);

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/281630.html

標籤:其他

上一篇:keycloak~OIDC&OAuth2&自定義皮膚

下一篇:現在網上流傳的 35 歲很多人會失業,究竟是危言聳聽,還是真實存在的?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more