国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

stm32(F103c8t6)自學(xué)筆記@阿布君

這篇具有很好參考價(jià)值的文章主要介紹了stm32(F103c8t6)自學(xué)筆記@阿布君。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

學(xué)習(xí)過程中的注意點(diǎn):

1.注意頭文件和C文件的包含關(guān)系,C文件自身應(yīng)包含自身的H頭文件以及用到的外部頭文件,而自身頭文件只需包含頭文件需要用到的資源文件即可。

參考文獻(xiàn):http://t.csdn.cn/o2GmL

一、認(rèn)識(shí)STM32

1.簡(jiǎn)介

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.命名規(guī)則??

3.系統(tǒng)結(jié)構(gòu)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

4.引腳&功能

注釋:

紅色表示:與電源相關(guān)

藍(lán)色是最小系統(tǒng)相關(guān)的引腳

綠色是IO口、功能口

S代表電源、I代表輸入、O代表輸出、IO代表輸入輸出、FT代表能容忍5v電壓(沒有就是3.3v)

芯片上小黑點(diǎn)旁為第一個(gè)IO口,逆時(shí)針增加;

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

5.啟動(dòng)配置 (BOOT三種模式)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

6.實(shí)物電路連接及Keil的設(shè)置?(ST-Link)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

二、軟件環(huán)境安裝(MDK)及新建工程

1.MDK的安裝

stm32不同于C51,需要安裝ARM_mdk的版本;

keil5及之后的版本需要安裝芯片對(duì)應(yīng)系列的器件庫(pack);

stm的編程模式除了像單片機(jī)那樣(1)直接操作寄存器(更可靠但是復(fù)雜、麻煩),還有通過(2)使用官方封裝好的庫函數(shù),還有一種方法是(3)使用Hal庫(如使用STM32CubeMX軟件實(shí)現(xiàn)自動(dòng)初始化配置)。

安裝過程不在過多贅述,CSDN上有實(shí)現(xiàn)C51、ARM、C251三版共存的方法。

2.新建工程

因?yàn)椴捎玫氖?span style="color:#fe2c24;">使用官方封裝好的庫函數(shù),所以并不像之前配置單片機(jī)那樣去簡(jiǎn)單的只插入頭文件然后寫程序就好,而是先導(dǎo)入官方的啟動(dòng)文件,搭建環(huán)境。

2.1 配置成寄存器開發(fā)模式(工程)(詳細(xì)步驟)

1.建立啟動(dòng)文件夾start,導(dǎo)入啟動(dòng)文件

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言
啟動(dòng)文件
stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言
必要頭文件
stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言
內(nèi)核的寄存器描述文件以及配置函數(shù)庫
stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言
成為這樣

? ? ? ? 這里注意:上圖中的md.s后綴文件是根據(jù)單片機(jī)型號(hào)選擇的,參考下圖

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.建立用戶文件夾User

? ? ? ? 創(chuàng)建main.c

3.完成

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.1.1?寄存器開發(fā)模式下實(shí)現(xiàn)點(diǎn)亮LED(GPIO13)

1.首先打開RCC寄存器的APB2使能GPIOC的時(shí)鐘

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.再配置對(duì)應(yīng)的GPIOC的模式

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

3.再寫入該GPIOC的輸出數(shù)據(jù)

????????燈是低電平點(diǎn)亮,高電平熄滅

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

4.完成

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

5.總結(jié)收獲

通過該方法配置很繁瑣,且每次配置會(huì)影響其它IO口的數(shù)據(jù),只能通過像單片機(jī)中的&=、|=來解決,更麻煩。

2.2 配置成標(biāo)準(zhǔn)庫開發(fā)模式(工程)(詳細(xì)步驟)

1.在寄存器開發(fā)模板的基礎(chǔ)上,新建Lirary文件夾,導(dǎo)入c文件、頭文件

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

? ? ? ? ?全部粘貼到剛建立的文件夾Library

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

? ? ? ? 將這三個(gè)粘貼到User文件夾(下面需要在Keil里配置路徑)

2.在Keil里添加上述文件,配置Keil

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

一定要定義 USE_STDPERIPH_DRIVER

? ? ? ? USE使用、下劃線、STD標(biāo)準(zhǔn)、PERIPH外設(shè)、下劃線、DRIVER驅(qū)動(dòng)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言
自己定義的帶有頭文件的文件夾都需要添加入路徑

?3.完成!

編譯0錯(cuò)誤0警告

2.2.1 標(biāo)準(zhǔn)庫開發(fā)模式下實(shí)現(xiàn)點(diǎn)亮LED(GPIO13)

配置思路和配置庫函數(shù)一樣,不同在于不用查手冊(cè)看具體位以及擔(dān)心改變其它位的數(shù)據(jù)了

操作流程還是一樣的

1.使能RCC寄存器控制的APB2總線上的外設(shè)IO時(shí)鐘

2.配置目標(biāo)外設(shè)的模式

? ? ? ? 這里注意:由于庫函數(shù)定義的GPIO_Init函數(shù)需要傳入一個(gè)結(jié)構(gòu)體變量的地址,這里是將需要配置的 Pin口、Speed傳輸速度、Mode輸出模式 三個(gè)封裝在了結(jié)構(gòu)體里以此簡(jiǎn)化了代碼。我們調(diào)用前必須要先自定義該結(jié)構(gòu)體類型的變量。

3.配置GPIOC_Pin口輸出的數(shù)據(jù)

? ? GPIO_SetBits (GPIOC,GPIO_Pin_13); ?//輸出高電平(熄滅)
?? ?GPIO_ResetBits (GPIOC,GPIO_Pin_13); ?//輸出低電平(點(diǎn)亮)

#include "stm32f10x.h"                  // Device header


int main(void)
{
//	RCC->APB2ENR = 0X00000010;  //配置寄存器實(shí)現(xiàn)點(diǎn)燈
//	GPIOC->CRH = 0X00300000;
//	GPIOC->ODR = 0X00000000;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOC時(shí)鐘
	GPIO_InitTypeDef GPIO_InitStruct;  //定義的結(jié)構(gòu)體
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  //輸出模式
	GPIO_InitStruct .GPIO_Pin = GPIO_Pin_13;  //輸出IO口
	GPIO_InitStruct .GPIO_Speed = GPIO_Speed_50MHz;  //輸出速度
	GPIO_Init(GPIOC,&GPIO_InitStruct);  //配置GPIOC的模式,這里將三種模式放在了一個(gè)結(jié)構(gòu)體內(nèi),因此要在上面定義一個(gè)結(jié)構(gòu)體
	//GPIO_SetBits (GPIOC,GPIO_Pin_13);  //輸出高電平(熄滅)
	GPIO_ResetBits (GPIOC,GPIO_Pin_13);  //輸出低電平(點(diǎn)亮)
	while(1)
	{
		
	}
}

3.工程架構(gòu)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

4.步驟回顧、總結(jié)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

三、GPIO(外設(shè))

1.GPIO結(jié)構(gòu)及原理

1.1 介紹

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.2 結(jié)構(gòu)?

簡(jiǎn)單來說,GPIO是受RCC寄存器?控制的APB2總線上的一系列外設(shè)IO口。

這些IO口由 GPIO A~GPIO E ,而單個(gè)GPIO如GPIOC都是又下分為16個(gè)小IO口(引腳),其中驅(qū)動(dòng)器是為了增加引腳電平驅(qū)動(dòng)能力

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

單個(gè)外設(shè)口如GPIOC的內(nèi)部電路結(jié)構(gòu)如下:

? ? ? ? 下圖中的肖特基觸發(fā)器是文獻(xiàn)翻譯錯(cuò)誤,實(shí)際應(yīng)為施密特觸發(fā)器。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?施密特觸發(fā)器原理:

? ? ? ? 內(nèi)部可設(shè)兩個(gè)閾值,輸入信號(hào)高于上限為高電平,低于下限為低電平

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.3 GPIO的八種模式

typedef enum
{ GPIO_Mode_AIN = 0x0,
? GPIO_Mode_IN_FLOATING = 0x04,
? GPIO_Mode_IPD = 0x28,
? GPIO_Mode_IPU = 0x48,
? GPIO_Mode_Out_OD = 0x14,
? GPIO_Mode_Out_PP = 0x10,
? GPIO_Mode_AF_OD = 0x1C,
? GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

Stm32庫里將8種模式定義為了枚舉類型

  • GPIO_Mode_AIN:模擬輸入模式(Analog Input Mode)。
  • GPIO_Mode_IN_FLOATING:浮空輸入模式(Floating Input Mode)。
  • GPIO_Mode_IPD:下拉輸入模式(Input Pull-down Mode)。
  • GPIO_Mode_IPU:上拉輸入模式(Input Pull-up Mode)。
  • GPIO_Mode_Out_OD:開漏輸出模式(Output Open-drain Mode)。
  • GPIO_Mode_Out_PP:推挽輸出模式(Output Push-pull Mode)。
  • GPIO_Mode_AF_OD:復(fù)用開漏輸出模式(Alternate Function Output Open-drain Mode)。
  • GPIO_Mode_AF_PP:復(fù)用推挽輸出模式(Alternate Function Output Push-pull Mode)。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.GPIO輸出

2.1 可輸出設(shè)備(LED、蜂鳴器...)

和51單片機(jī)一樣,每個(gè)IO口都具有輸出功能(高低電平)

因此可實(shí)現(xiàn)點(diǎn)亮LED,蜂鳴器報(bào)警等功能。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.2Stm32中LED、蜂鳴器的電路

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.3 面包板(結(jié)構(gòu))

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.4 實(shí)現(xiàn)LED閃爍(含代碼)

一定要先按照自己的思路和理解去寫一遍,主要就是調(diào)用各種庫函數(shù)。

下面代碼需要注意的是:

GPIO_InitTypeDef A,B,C; ?//定義三個(gè)IO的結(jié)構(gòu)體變量 A是PA0口、B是PA1口、C是PA3口

這段代碼如果在函數(shù)中間定義會(huì)報(bào)錯(cuò),那么是由于你的Keil版本過低導(dǎo)致,按下圖設(shè)置:

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE );//使能GPIO時(shí)鐘
	
	GPIO_InitTypeDef A,B,C;  //定義三個(gè)GPIO的結(jié)構(gòu)體變量 A是GPIOA、B是GPIOB、C是GPIOC//這里理解也不對(duì),因?yàn)锳BC只在RCC那里使能打開,這里定義的只是變量名,只是一個(gè)中間媒介去實(shí)現(xiàn)傳值

	A.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	A.GPIO_Pin=GPIO_Pin_0;  //設(shè)置為Pin0口
	A.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz
	GPIO_Init( GPIOA,&A); //以上三個(gè)都要傳入該函數(shù)初始化
	
	B.GPIO_Mode=GPIO_Mode_Out_PP;
	B.GPIO_Pin=GPIO_Pin_1;
	B.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA,&B);
	
	C.GPIO_Mode=GPIO_Mode_Out_PP;
	C.GPIO_Pin=GPIO_Pin_2;
	C.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA,&C);
	while(1)
	{
		GPIO_ResetBits (GPIOA,GPIO_Pin_0);//先亮
		GPIO_ResetBits (GPIOA,GPIO_Pin_1);
		GPIO_ResetBits (GPIOA,GPIO_Pin_2);
		Delay_ms(500);
		GPIO_SetBits (GPIOA,GPIO_Pin_0);//再滅
		GPIO_SetBits (GPIOA,GPIO_Pin_1);
		GPIO_SetBits (GPIOA,GPIO_Pin_2);
		Delay_ms(500);
	}
}

不知道你是否發(fā)現(xiàn),其實(shí)代碼里是定義了三個(gè)外設(shè),每個(gè)外設(shè)又單獨(dú)設(shè)置的IO,其實(shí)這種方法是不對(duì)的,也是初學(xué)時(shí)容易產(chǎn)生的誤區(qū),如何修改,看下面的代碼。

2.5 實(shí)現(xiàn)LED流水燈(含代碼、理解

?初始化時(shí)是初始化一個(gè)外設(shè),然后一個(gè)外設(shè)又有16個(gè)引腳。

上面的代碼中 GPIO_InitTypeDef A,B,C; ?//定義三個(gè)GPIO的結(jié)構(gòu)體變量 A是GPIOA、B是GPIOB、C是GPIOC

這里理解也不對(duì),因?yàn)锳BC只在RCC寄存器那里使能打開,這里定義的只是變量名,只是一個(gè)中間媒介去實(shí)現(xiàn)傳值

個(gè)人覺得這樣定義可以實(shí)現(xiàn)一個(gè)外設(shè)例如GPIOA的16個(gè)引腳可以設(shè)置為不同的輸出模式。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE );//使能GPIO時(shí)鐘
	
	GPIO_InitTypeDef A;  //定義一個(gè)中間結(jié)構(gòu)體變量

	A.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	A.GPIO_Pin=GPIO_Pin_All;  //設(shè)置所有的Pin口(PA0~PA15)
	A.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz
	GPIO_Init( GPIOA,&A); //以上三個(gè)都要傳入該函數(shù)初始化
	
	while(1)
	{
		unsigned char i;
		for(i=0;i<8;i++)
		{
			GPIO_Write(GPIOA ,~(0X0001<<i));//0000 0000 0000 0001依次左移8位 該函數(shù)可以整體寫入GPIOx->ODR
			Delay_ms(100);
		}
	}
}

2.6 蜂鳴器(含代碼)

?配置原理和配LED是一樣的

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE );//使能GPIO時(shí)鐘
	
	GPIO_InitTypeDef A;

	A.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	A.GPIO_Pin=GPIO_Pin_12;  //設(shè)置為Pin0口
	A.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz
	GPIO_Init( GPIOB,&A); //以上三個(gè)都要傳入該函數(shù)初始化
	while(1)
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);//低電平觸發(fā)
		Delay_ms (100);
		GPIO_SetBits(GPIOB,GPIO_Pin_12);//不響
		Delay_ms (100);
	}
}

3.GPIO輸入

3.1 可輸入設(shè)備(按鍵、溫濕度...)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

3.2 Stm32中按鍵、紅外發(fā)射等器件的電路

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

3.3 復(fù)習(xí)數(shù)據(jù)類型、宏定義、Typedef、結(jié)構(gòu)體、枚舉

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?define能改變?nèi)魏螖?shù)據(jù)的名字,但是編譯器不會(huì)檢測(cè)是否有錯(cuò)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?Typedef結(jié)構(gòu)體相關(guān)的用法和說明可以看我的另外一篇文章

http://t.csdn.cn/H8ikF

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

枚舉類似于結(jié)構(gòu)體,其中關(guān)鍵詞 enum相當(dāng)于結(jié)構(gòu)體的關(guān)鍵詞 struct;

注意enum中是用逗號(hào)分隔;

枚舉的作用就是限制變量值的輸入取值范圍,就像星期幾只能從七天里選一個(gè);

取值超出范圍會(huì)報(bào)錯(cuò);

下附釋義代碼

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

#include <stdio.h>

int main()
{
	typedef enum{ 
		mon=1,
		tur, //	等效于mon=1,tur=2,wen=3,tue=4
		wen,
		tue
	}day;//這里將整個(gè)枚舉改名為day 
	day a,b,c;
	int d;
	
	a=tur;
	b=(day)1;//直接賦值int型不行 ,需要轉(zhuǎn)化為枚舉型 
	c=day(4);
	
	d=wen;//外界數(shù)據(jù)也可以引用枚舉集合里的數(shù) 
	
	printf("a=%d\n",a);
	printf("b=%d\n",b);
	printf("c=%d\n",c);
	printf("d=%d\n",d);
 } 

3.4?代碼(按鍵控制LED)(封裝)(Delay函數(shù)封裝)

Stm32中延時(shí)函數(shù)Delay的us、ms、s的代碼

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

/***************************************************/延時(shí)函數(shù)模塊
#include "Delay.h"
#include "stm32f10x.h" 

/**
  * @brief  微秒級(jí)延時(shí)
  * @param  xus 延時(shí)時(shí)長(zhǎng),范圍:0~233015
  * @retval 無
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//設(shè)置定時(shí)器重裝值
	SysTick->VAL = 0x00;					//清空當(dāng)前計(jì)數(shù)值
	SysTick->CTRL = 0x00000005;				//設(shè)置時(shí)鐘源為HCLK,啟動(dòng)定時(shí)器
	while(!(SysTick->CTRL & 0x00010000));	//等待計(jì)數(shù)到0
	SysTick->CTRL = 0x00000004;				//關(guān)閉定時(shí)器
}

/**
  * @brief  毫秒級(jí)延時(shí)
  * @param  xms 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒級(jí)延時(shí)
  * @param  xs 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

/***************************************************/LED模塊
#include "LED.h"
#include "stm32f10x.h"                  // Device header

void LED_init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE );//使能GPIOA的時(shí)鐘
	
	GPIO_InitTypeDef A;  //定義兩個(gè)IO的結(jié)構(gòu)體變量 A是PA0口、B是PB0口

	A.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	A.GPIO_Pin=GPIO_Pin_All;  //設(shè)置為所有Pin口
	A.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz
	GPIO_Init( GPIOA,&A); //以上三個(gè)都要傳入該函數(shù)初始化
	
}

void LED_state(uint16_t GPIO_Pin,FunctionalState NewState)//指定Pin口和對(duì)應(yīng)狀態(tài)
{
	if(NewState==0)
		GPIO_ResetBits(GPIOA,GPIO_Pin);//置低電平
	else
		GPIO_SetBits(GPIOA,GPIO_Pin);//置高電平
}

/***************************************************/按鍵模塊
#include "Key.h"                  // Device header
#include "Delay.h"


void Key_init(uint16_t GPIO_Pin)//需要指定端口Pin進(jìn)行模式設(shè)置
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE );//使能GPIOA的時(shí)鐘
	
	GPIO_InitTypeDef A;  //定義兩個(gè)IO的結(jié)構(gòu)體變量 A是PA0口、B是PB0口

	A.GPIO_Mode=GPIO_Mode_IPU;//設(shè)置為 上拉輸入 模式
	A.GPIO_Pin=GPIO_Pin;  //外界參數(shù)設(shè)置Pin口
	A.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz,在輸入模式下該設(shè)置沒用
	GPIO_Init( GPIOB,&A); //以上三個(gè)都要傳入該函數(shù)初始化
}

uint8_t get_keynum(uint16_t GPIO_Pin)
{
	uint8_t keynum;
	keynum =GPIO_ReadInputDataBit(GPIOB,GPIO_Pin);
	if(keynum ==0)
	{
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin) ==0);
		Delay_ms(10);
		return 0;
	}
	else 
		return keynum ;
}

/***************************************************/主函數(shù)
int main(void)
{
	uint8_t state=0;
	LED_init();
	Key_init(GPIO_Pin_12);
	while(1)
	{
		if(get_keynum(GPIO_Pin_12) ==0)
		{
			state ++;
		}
		if(state %2)
		{
			LED_state(GPIO_Pin_All ,ENABLE);
		}
		else 
		{
			LED_state(GPIO_Pin_All,DISABLE);
		}
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

3.5 代碼(光敏電阻控制蜂鳴器及LED)(封裝)

#include "stm32f10x.h"                  // Device header
#include "Buzzer.h"
#include "LightR.h"
#include "LED.h"


/***************************************************/蜂鳴器模塊
#include "Buzzer.h"                  // Device header
#include "stm32f10x.h" 

GPIO_InitTypeDef buzzer;  

void Buzzer_init(uint16_t GPIO_Pin)//需要指定端口Pin進(jìn)行模式設(shè)置
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE );//使能GPIOB的時(shí)鐘
	
	

	buzzer.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	buzzer.GPIO_Pin=GPIO_Pin;  //外界參數(shù)設(shè)置Pin口
	buzzer.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz,在輸入模式下該設(shè)置沒用
	GPIO_Init( GPIOB,&buzzer); //以上三個(gè)都要傳入該函數(shù)初始化
}

void Buzzer_run(unsigned char Flag)//設(shè)定運(yùn)行標(biāo)志位
{
	if(Flag==0)
		GPIO_ResetBits(GPIOB,buzzer.GPIO_Pin);//置低電平
	else
		GPIO_SetBits(GPIOB,buzzer.GPIO_Pin);//置高電平
}

/***************************************************/光敏電阻模塊
#include "LightR.h"
#include "stm32f10x.h" 

GPIO_InitTypeDef lightr;  

void LightR_init(uint16_t GPIO_Pin)//需要指定端口Pin進(jìn)行模式設(shè)置
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);//使能GPIOB的時(shí)鐘
	
	

	lightr.GPIO_Mode=GPIO_Mode_IPU;//設(shè)置為 上拉輸入 模式
	lightr.GPIO_Pin=GPIO_Pin;  //外界參數(shù)設(shè)置Pin口
	lightr.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz,在輸入模式下該設(shè)置沒用
	GPIO_Init( GPIOB,&lightr); //以上三個(gè)都要傳入該函數(shù)初始化
}

uint8_t get_LightR_DO(void)//用來獲取光敏電阻輸出的數(shù)字量DO值
{
	return  GPIO_ReadInputDataBit(GPIOB,lightr.GPIO_Pin);
}

/***************************************************/LED模塊
#include "LED.h"
#include "stm32f10x.h"                  // Device header

GPIO_InitTypeDef led;  //定義兩個(gè)IO的結(jié)構(gòu)體變量 A是PA0口、B是PB0口

void LED_init(uint16_t GPIO_Pin)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE );//使能GPIOA的時(shí)鐘
	
	
	led .GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置為推挽輸出模式
	led .GPIO_Pin=GPIO_Pin;  //設(shè)置為所有Pin口
	led .GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz
	GPIO_Init( GPIOA,&led ); //以上三個(gè)都要傳入該函數(shù)初始化
	
}

void LED_state(unsigned char Flag)//指定Pin口和對(duì)應(yīng)狀態(tài)
{
	if(Flag==0)
		GPIO_ResetBits(GPIOA,led.GPIO_Pin);//置低電平
	else
		GPIO_SetBits(GPIOA,led.GPIO_Pin);//置高電平
}

/***************************************************/主函數(shù)

int main(void)
{
	uint16_t lightstate;//亮、暗狀態(tài)
	
	LED_init(GPIO_Pin_0);
	Buzzer_init(GPIO_Pin_0);
	LightR_init(GPIO_Pin_1);
	while(1)
	{
		lightstate =get_LightR_DO();//循環(huán)里實(shí)時(shí)獲取
		if(lightstate)//暗	燈滅、蜂鳴器響
		{
			LED_state(1);
			Buzzer_run(0);
		}
		else //亮	燈亮、蜂鳴器不響
		{
			LED_state(0);
			Buzzer_run(1);
		}
	}
}

/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

四、OLED顯示屏

1.結(jié)構(gòu)原理

1.1 結(jié)構(gòu)圖(0.96寸4針B版本)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.2 介紹

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.3 電路

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.4 調(diào)試方法

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.OLED驅(qū)動(dòng)函數(shù)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

3.驅(qū)動(dòng)函數(shù)封裝包

見資源包

五、EXTI外部中斷系統(tǒng)

1.結(jié)構(gòu)原理

1.1 認(rèn)識(shí)中斷

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

和C51中的中斷是一樣的,只不過32的資源更加豐富;??stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.2 中斷系統(tǒng)內(nèi)部機(jī)制(中斷和異常向

?????????由于Stm32中斷資源眾多,所以這里的中斷都是由NVIC統(tǒng)一管理。

左邊需要執(zhí)行的眾多中斷會(huì)根據(jù)分組和優(yōu)先級(jí)排隊(duì),其中搶占優(yōu)先級(jí)具有最高優(yōu)先級(jí)可直接由NVIC傳入CPU,中斷CPU正在執(zhí)行的主程序或者中斷),而響應(yīng)優(yōu)先級(jí)則具有插隊(duì)排第一位的權(quán)限優(yōu)先級(jí)次于搶占優(yōu)先級(jí)),當(dāng)左邊排隊(duì)完成,NVIC會(huì)根據(jù)左邊的排隊(duì)決定當(dāng)前該執(zhí)行哪一個(gè)中斷然后傳給CPU(CPU不知道優(yōu)先級(jí)邏輯,由NVIC處理,節(jié)約算力和IO口

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?中斷和異常向表,建議翻看手冊(cè);

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.3 EXTI簡(jiǎn)介

觸發(fā)中斷,中斷響應(yīng)是正常的流程,但是Stm32還提供了一種額外的中斷處理:事件響應(yīng)。

當(dāng)選擇觸發(fā)事件響應(yīng),那么該中斷信號(hào)將不會(huì)通過NVIC傳入CPU,而是直接傳給某一個(gè)外設(shè)并觸發(fā)它。例如觸發(fā)ADC模塊‘觸發(fā)DMA等。

總結(jié):中斷響應(yīng)是正常的流程,引腳電平變化觸發(fā)中斷。事件響應(yīng)不會(huì)觸發(fā)中斷,而是觸發(fā)別的外設(shè)操作,屬于外設(shè)之間的聯(lián)合操作。

注意:相同的pin口的中斷不能同時(shí)被觸發(fā),如PA0、PB0、PC0三個(gè)中斷同時(shí)需要傳入NVIC,但是最終只會(huì)有一個(gè)被傳入。

在EXTI內(nèi)部有對(duì)數(shù)據(jù)篩選處理的模塊,最終只有指定的IO數(shù)據(jù)會(huì)傳入NVIC,其它的會(huì)作為事件觸發(fā)傳給指定的外設(shè)。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.4?EXTI機(jī)制

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5 AFIO復(fù)用IO口

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.點(diǎn)觸式旋轉(zhuǎn)編碼器

2.1 結(jié)構(gòu)原理

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?2.2 代碼實(shí)現(xiàn)(詳細(xì)步驟說明)

該模塊需要用到中斷,如何實(shí)現(xiàn)呢?其實(shí)原理就是將模塊IO口使能使其數(shù)據(jù)能夠到達(dá)NVIC再到CPU就好了。

五個(gè)步驟:

1.打開對(duì)應(yīng)IO口的RCC外設(shè)時(shí)鐘(不打開IO口不能工作);

2.配置IGPO口的模式;

3.配置AFIO,使其選擇我們要用的GPIO口,連接到EXTI;

4.配置EXTI模式,選擇觸發(fā)方式及響應(yīng)方式(中斷or事件);

5.配置NVIC,選擇一個(gè)合適的中斷優(yōu)先級(jí)。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "mokuaicount.h"
extern int num;

/***************************************************/初始化旋鈕模塊
#include "xuanniu.h"                  // Device header
#include "stm32f10x.h" 

void Xuanniu_init(uint16_t GPIO_Pin)//需要指定端口Pin進(jìn)行模式設(shè)置
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//使能GPIOA的時(shí)鐘
	
	GPIO_InitTypeDef Xuanniu_InitStruct;  

	Xuanniu_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//設(shè)置為 上拉輸入 模式
	Xuanniu_InitStruct.GPIO_Pin=GPIO_Pin;  //外界參數(shù)設(shè)置Pin口
	Xuanniu_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz,在輸入模式下該設(shè)置沒用
	GPIO_Init( GPIOA,&Xuanniu_InitStruct); //以上三個(gè)都要傳入該函數(shù)初始化
}

/***************************************************/配置中斷
//**該模塊由中斷函數(shù)實(shí)現(xiàn),可接入任意輸入模式的模塊實(shí)現(xiàn)計(jì)數(shù)
//**這里引入Key實(shí)現(xiàn)數(shù)據(jù)的減法,LightR實(shí)現(xiàn)加法
#include "stm32f10x.h"                  // Device header
#include "mokuaicount.h"
#include "Delay.h"
#include "xuanniu.h"


int num;

void Count_interrupt_init(void)
{
	//1、2、**步驟一二在模塊內(nèi)已經(jīng)實(shí)現(xiàn)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//AFIO時(shí)鐘需要使能
	
	Xuanniu_init(GPIO_Pin_0|GPIO_Pin_1);
	//3**配置AFIO,選擇輸入引腳
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//Xuanniu旋鈕
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
	//4**配置EXTI寄存器,選擇觸發(fā)方式,這里配置EXTI和GPIO一樣需要定義一個(gè)結(jié)構(gòu)體
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line=EXTI_Line0|EXTI_Line1;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
	//5**配置NVIC,選擇合適的中斷優(yōu)先級(jí) --------每一個(gè)外設(shè)要單獨(dú)配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//要先分組,整個(gè)系統(tǒng)NVIC只分配一種模式
	//**配置Xuanniu A端
	NVIC_InitTypeDef NVIC_InitStruct_Xuanniu;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct_Xuanniu);
	//**配置Xuanniu C端
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI1_IRQn;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct_Xuanniu);
	
	
	//****所有配置完成
}

//中斷位置隨便放,也不需要聲明
void EXTI0_IRQHandler()//正轉(zhuǎn)觸發(fā)
{
	if(EXTI_GetITStatus(EXTI_Line0)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)
		{
			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==1)
			{
				num++;
			}
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler()
{
	if(EXTI_GetITStatus(EXTI_Line1)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==0)
		{
			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)
			{
				num--;
			}
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line1);
}


/***************************************************/主函數(shù)
int main(void)
{
	OLED_Init();
	Count_interrupt_init();
	OLED_ShowString(1,1,"Hello,my honey");
	OLED_ShowString(2,1,"Hello WangFang");
	OLED_ShowString(3,1,"Hello Tomorrow");
	while(1)
	{
		OLED_ShowSignedNum(4,1,num,5);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

六、TIM定時(shí)中斷

1.結(jié)構(gòu)原理

1.1 介紹

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.2 定時(shí)器種類

不同型號(hào)的開發(fā)板擁有的定時(shí)器資源不一樣

基本定時(shí)器只支持向上計(jì)數(shù)(由0加到重裝載值觸發(fā)中斷后清零)

通用定時(shí)器和高級(jí)定時(shí)器都支持向上計(jì)數(shù)、向下計(jì)數(shù)、中央對(duì)齊三種模式計(jì)數(shù)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.3 基本定時(shí)器框圖

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.4 通用定時(shí)器框圖

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5 高級(jí)定時(shí)器框圖

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.6 定時(shí)中斷基本結(jié)構(gòu)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.7 時(shí)序圖(詳細(xì)解釋)

計(jì)數(shù)流程:選擇時(shí)鐘源-->確定濾波的幾分頻-->確定預(yù)分頻PSC-->確定重裝載值A(chǔ)RR-->溢出觸發(fā)中斷

分頻過程:外部輸入規(guī)律的高低電平脈沖信號(hào),經(jīng)過選擇分頻模式后,信號(hào)轉(zhuǎn)化輸入預(yù)分頻器開始計(jì)數(shù),每到達(dá)預(yù)分頻器設(shè)置的閾值溢出時(shí)就產(chǎn)生一個(gè)脈沖給計(jì)數(shù)器,計(jì)數(shù)器+1,最后當(dāng)計(jì)數(shù)器計(jì)數(shù)值等于自動(dòng)裝載器設(shè)置的閾值時(shí)產(chǎn)生溢出,觸發(fā)中斷,因此在一分頻模式下:

定時(shí)頻率(時(shí)間)=(預(yù)分頻值/初始時(shí)鐘頻率)*預(yù)裝載值

如定時(shí)1s,則1 s=(7200)/72Mhz * 10000? ? ? ? ? ? ? ? ? ? ?(取值范圍 0~65535)

這就像是兩個(gè)定時(shí)器級(jí)聯(lián)一樣,增大了計(jì)數(shù)范圍

最新理解:

已知公式 t=1/f

那么內(nèi)部時(shí)鐘經(jīng)過預(yù)分頻后每記一次的時(shí)間就為:t1=1/(72Mhz/PSC+1)

那么分頻器每隔t1時(shí)間就產(chǎn)生信號(hào)給計(jì)數(shù)器,直到計(jì)數(shù)器經(jīng)過t2=t1*(ARR+1)的時(shí)間或者說累加到等于ARR時(shí),產(chǎn)生中斷同時(shí)計(jì)數(shù)器清零。

所以整個(gè)過程花費(fèi)時(shí)間(每次中斷的間隔時(shí)間)為:t2=1/(72Mhz/PSC+1)*(ARR+1)

比如要計(jì)時(shí) 1s :1 s = 1 / ( 72Mhz / 7200)* 10000

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.定時(shí)器中斷計(jì)數(shù)(代碼)

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "timer2.h"

/***************************************************/定時(shí)器2
#include "stm32f10x.h"
#include "timer2.h"

extern int num;
void timer2_init(void)
{
	//**1.打開總的RCC
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	//**2.選定定時(shí)器接入的時(shí)鐘
	TIM_InternalClockConfig(TIM2);//設(shè)置定時(shí)器2使用內(nèi)部時(shí)鐘,可不寫,上電默認(rèn)
	//**3.配置時(shí)基單元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;//設(shè)置預(yù)裝載值
	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除
	//**4.使能時(shí)基單元的中斷
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	//**5.配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分組
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	//**6.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);

}

//**配置中斷函數(shù)
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		num++;
	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//一定要清除標(biāo)志位
}

/***************************************************/主函數(shù)

int num;
int main(void)
{
	OLED_Init();
	timer2_init();
	OLED_ShowString(1,1,"Hello,my honey");
//	OLED_ShowString(2,1,"Hello WangFang");
//	OLED_ShowString(3,1,"Hello Tomorrow");
//	OLED_ShowString(4,1,"I miss you");
	while(1)
	{
		OLED_ShowString(2,1,"NUM:");
		OLED_ShowNum(2,5,num,5);
		
		OLED_ShowString(3,1,"Prescaler:");
		OLED_ShowNum(3,11,TIM_GetPrescaler(TIM2),5);
		
		OLED_ShowString(4,1,"Counter:");
		OLED_ShowNum(4,9,TIM_GetCounter(TIM2),5);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

3.外部時(shí)鐘的定時(shí)器中斷(代碼)

相對(duì)于2的使用內(nèi)部時(shí)鐘,此方法不同之處僅在于使用函數(shù):

TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//第二個(gè)設(shè)置分頻,第三個(gè)設(shè)置觸發(fā)方式,第四個(gè)設(shè)置采樣頻率(濾波器)

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "timer2.h"

/***************************************************/定時(shí)器2
#include "stm32f10x.h"
#include "timer2.h"

extern int num;
void timer2_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//**2.配置定時(shí)器接入外部時(shí)鐘 同時(shí)配置外部時(shí)鐘輸入的引腳
	//TIM_InternalClockConfig(TIM2);//設(shè)置定時(shí)器2使用內(nèi)部時(shí)鐘,可不寫,上電默認(rèn)
	
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//第二個(gè)設(shè)置分頻,第三個(gè)設(shè)置觸發(fā)方式,第四個(gè)設(shè)置采樣頻率(濾波器)
	//**3.配置時(shí)基單元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
//	TIM_TimeBaseInitStruct.TIM_Period=10000-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
//	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_Period=10-1;//設(shè)置預(yù)裝載值
	TIM_TimeBaseInitStruct.TIM_Prescaler=2-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除
	//**4.使能時(shí)基單元的中斷
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	//**5.配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分組
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	//**6.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);

}

//**配置中斷函數(shù)
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		num++;
	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}


/***************************************************/主函數(shù)

int num;
int main(void)
{
	OLED_Init();
	timer2_init();
	OLED_ShowString(1,1,"Hello,my honey");
//	OLED_ShowString(2,1,"Hello WangFang");
//	OLED_ShowString(3,1,"Hello Tomorrow");
//	OLED_ShowString(4,1,"I miss you");
	while(1)
	{
		OLED_ShowString(2,1,"NUM:");
		OLED_ShowNum(2,5,num,5);
		
		OLED_ShowString(3,1,"Prescaler:");
		OLED_ShowNum(3,11,TIM_GetPrescaler(TIM2),5);
		
		OLED_ShowString(4,1,"Counter:");
		OLED_ShowNum(4,9,TIM_GetCounter(TIM2),5);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

4.TIM(OC)比較輸出(PWM)?。?!

4.1 結(jié)構(gòu)原理介紹(模式)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

?8種模式

?TIM_OCMode? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)庫描述? ? ? ? ? ? ? ? ? ? ? ? ? ? ?解釋


TIM_OCMode_Timing? ? ? ?TIM輸出比較? ? ? ? ? ? ? ? ? ?? ?凍結(jié),輸出比較不起作用
TIM_OOCMode_Active? ? ?TIM輸出比較主動(dòng)模式? ? ? ? 當(dāng)比較發(fā)生時(shí),強(qiáng)制輸出高電平
TIM_OCMode_Inactiive?? ?TIM輸出比較非主動(dòng)模式? ? ?當(dāng)比較發(fā)生時(shí),強(qiáng)制輸出低電平
TIM_OCMode_Toggle? ? ? ?TIM輸出比較觸發(fā)模式? ? ? ? 當(dāng)比較發(fā)生時(shí),輸出翻轉(zhuǎn)
TIM_OCMode_PWM1? ? ? ? TIM脈沖寬度調(diào)制模式1? ? ??PWM1
TIM_OCMode_PWM2? ? ? ? TIM脈沖寬度調(diào)制模式2? ? ??PWM2

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

4.2 輸出設(shè)備(舵機(jī),直流電機(jī))

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

4.3 代碼配置

4.3.1(呼吸燈、重映射)

先和配置定時(shí)器步驟差不多,只不過最后不需要配置中斷和NVIC,就直接配置CCR

CCR需要先使用TIM_OCStructInit()整體初始化,然后再單獨(dú)配置需要的模式:

????TIM_OCInitTypeDef TIM_OCInitStruct;
?? ?TIM_OCStructInit(&TIM_OCInitStruct);//先整體初始化,防止有些變量未初始化而出錯(cuò)
?? ?TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//配置為PWM1輸出模式
?? ?TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//配置REF為高極性
?? ?TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//配置輸出使能
?? ?TIM_OCInitStruct.TIM_Pulse=100;//配置CCR計(jì)數(shù)器值
?? ?TIM_OC1Init(TIM2,&TIM_OCInitStruct);

重映射使用看視頻學(xué)習(xí)

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "PWM.h"
/***************************************************/PWM模塊
#include "stm32f10x.h"                  // Device header
#include "Delay.h"


void pwm_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**3.配置時(shí)基單元
	//配置為1000KHz,分辨率為1%
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=100-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除

	//**4.配置CCR
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);//先整體初始化,防止有些變量未初始化而出錯(cuò)
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//配置為PWM1輸出模式
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//配置REF為高極性
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//配置輸出使能
	TIM_OCInitStruct.TIM_Pulse=100;//配置CCR計(jì)數(shù)器值
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
	
	//5.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);
}

void LED_run(void)
{
	uint16_t num;
	for(num=100;num>0;num--)
	{
		TIM_SetCompare1(TIM2,num);
		Delay_ms(10);

	}
	for(num=0;num<100;num++)
	{
		TIM_SetCompare1(TIM2,num);
		Delay_ms(10);
	}
}

/***************************************************/主函數(shù)

int main(void)
{
	OLED_Init();
	pwm_init();
	OLED_ShowString(1,1,"Hello,my honey");
//	OLED_ShowString(2,1,"Hello WangFang");
//	OLED_ShowString(3,1,"Hello Tomorrow");
//	OLED_ShowString(4,1,"I miss you");
	while(1)
	{
		LED_run();
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/
4.3.2(旋鈕控制舵機(jī)角度PWM)

旋轉(zhuǎn)旋鈕觸發(fā)中斷從而改變CCR的值(改變占空比)

要注意舵機(jī)的信號(hào)周期為20ms,既50Hz

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "PWM.h"
#include "mokuaicount.h"

/***************************************************/PWM模塊
#include "stm32f10x.h"                  // Device header
#include "PWM.h"
#include "Delay.h"


void pwm_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳PA0
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**3.配置時(shí)基單元
	//配置為1000KHz,分辨率為1%
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=20000-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除

	//**4.配置CCR
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
	
	//5.
	//**6.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);
}

void set_angle(uint16_t angle)
{
	TIM_SetCompare1(TIM2,angle);
}

/***************************************************/GPIO初始化
#include "xuanniu.h"                
#include "stm32f10x.h" 

void Xuanniu_init(uint16_t GPIO_Pin)//需要指定端口Pin進(jìn)行模式設(shè)置
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);//使能GPIOA的時(shí)鐘
	
	GPIO_InitTypeDef Xuanniu_InitStruct;  

	Xuanniu_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//設(shè)置為 上拉輸入 模式
	Xuanniu_InitStruct.GPIO_Pin=GPIO_Pin;  //外界參數(shù)設(shè)置Pin口
	Xuanniu_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;  //輸出速度為50MHz,在輸入模式下該設(shè)置沒用
	GPIO_Init( GPIOB,&Xuanniu_InitStruct); //以上三個(gè)都要傳入該函數(shù)初始化
}

/***************************************************/計(jì)數(shù)模塊
//**該模塊由中斷函數(shù)實(shí)現(xiàn),可接入任意輸入模式的模塊實(shí)現(xiàn)計(jì)數(shù)
//**這里引入Key實(shí)現(xiàn)數(shù)據(jù)的減法,LightR實(shí)現(xiàn)加法
#include "stm32f10x.h"                  // Device header
#include "mokuaicount.h"
#include "Delay.h"
#include "xuanniu.h"


extern int num;

void Count_interrupt_init(void)
{
	//1、2、**步驟一二在模塊內(nèi)已經(jīng)實(shí)現(xiàn)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//AFIO時(shí)鐘需要使能
	
	Xuanniu_init(GPIO_Pin_0|GPIO_Pin_1);
	//3**配置AFIO,選擇輸入引腳PB1(C),PB0(A)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//Xuanniu旋鈕
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
	//4**配置EXTI寄存器,選擇觸發(fā)方式,這里配置EXTI和GPIO一樣需要定義一個(gè)結(jié)構(gòu)體
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line=EXTI_Line0|EXTI_Line1;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
	//5**配置NVIC,選擇合適的中斷優(yōu)先級(jí) --------每一個(gè)外設(shè)要單獨(dú)配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//要先分組,整個(gè)系統(tǒng)NVIC只分配一種模式
	//**配置Xuanniu A端
	NVIC_InitTypeDef NVIC_InitStruct_Xuanniu;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct_Xuanniu);
	//**配置Xuanniu C端
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannel=EXTI1_IRQn;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct_Xuanniu.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct_Xuanniu);
	
	
	//****所有配置完成
}

//中斷位置隨便放,也不需要聲明
void EXTI0_IRQHandler()//正轉(zhuǎn)觸發(fā)
{
	if(EXTI_GetITStatus(EXTI_Line0)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
		{
			if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==1)
			{
				num+=100;
			}
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler()
{
	if(EXTI_GetITStatus(EXTI_Line1)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
		{
			if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==1)
			{
				num-=100;
			}
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line1);
}


/***************************************************/主函數(shù)
int num=1500;

int main(void)
{
	OLED_Init();
	pwm_init();
	Count_interrupt_init();
	OLED_ShowString(1,1,"Hello,my baby");
	set_angle(num);//默認(rèn)居中
	while(1)
	{	
		if(num<=0)
		{
			num=0;
			OLED_ShowString(2,8,"Left Max ");
		}
		else if(num<1500)
		{
			OLED_ShowString(2,8,"Left     ");
		}
		else if(num==1500)
		{
			OLED_ShowString(2,8,"Midel    ");
		}
		else if(num<2500)
		{
			OLED_ShowString(2,8,"Right    ");
		}
		else if(num>=2500)
		{
			num=2500;
			OLED_ShowString(2,8,"Right Max");
		}
		OLED_ShowNum(2,1,num,5);
		
		set_angle(num);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/
4.3.3?直流電機(jī)(調(diào)速)

stay待機(jī)控制直接接入高電平3.3v就可以了

in1、in2初始化GPIO(推完輸出模式)然后設(shè)置高低電平即可

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Motor.h"

/***************************************************/PWM模塊
#include "stm32f10x.h"                  // Device header
#include "PWM.h"
#include "Delay.h"


void pwm_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳PA0
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**3.配置時(shí)基單元
	//配置為1000KHz,分辨率為1%
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=100-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除

	//**4.配置CCR
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
	
	//5.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);
}

void set_num(uint16_t num)
{
	TIM_SetCompare1(TIM2,num);
}

/***************************************************/電機(jī)模塊
#include "stm32f10x.h"                  // Device header
#include "Motor.h"
#include "PWM.h"

void Motor_init(void)
{
	pwm_init();
	
	GPIO_InitTypeDef GPIO_InitStruct;//初始化兩個(gè)方向控制引腳:PA4,PA5
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	GPIO_Init(GPIOA,&GPIO_InitStruct);
}

void set_speed(int speed)
{
	if(speed>=0)
	{
		set_num(speed);
		GPIO_SetBits(GPIOA,GPIO_Pin_4);
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
	}
	else
	{
		set_num(-speed);
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
	}
}

/***************************************************/主函數(shù)


int main(void)
{
	OLED_Init();
	Motor_init();
	while(1)
	{	
		set_speed(-100);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

5.TIM輸入捕獲

5.1 結(jié)構(gòu)原理

利用定時(shí)器模塊計(jì)數(shù),當(dāng)輸入捕獲模塊的邊沿檢測(cè)模塊檢測(cè)到下降沿或上升沿,觸發(fā)獲取CNT的值,每記完一次后CNT清零,獲取到的該周期的CNT值再通過與CNT計(jì)數(shù)頻率即可得到該電平變化周期的時(shí)間T。

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

由此可見,測(cè)頻法適合測(cè)量高頻,測(cè)周法適合測(cè)量低頻?

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言?

5.2 代碼配置

5.2.1 單通道測(cè)頻率

這里采用TIM2產(chǎn)生PWM信號(hào)用于測(cè)量

配置TIM3時(shí),也需要配置定時(shí)器時(shí)基模塊使CNT計(jì)數(shù),然后配置IC模塊(通過一個(gè)結(jié)構(gòu)體),再配置從模式的觸發(fā)源和觸發(fā)事件,使能定時(shí)器即可。

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

/***************************************************/PWM模塊
#include "stm32f10x.h"                  // Device header


void pwm_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**3.配置時(shí)基單元
	//配置為1000KHz,分辨率為1%
	TIM_InternalClockConfig(TIM2);//選擇內(nèi)部時(shí)鐘源
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=100-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除

	//**4.配置CCR
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	TIM_OCStructInit(&TIM_OCInitStruct);//先整體初始化,防止有些變量未初始化而出錯(cuò)
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//配置為PWM1輸出模式
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//配置REF為高極性
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//配置輸出使能
	TIM_OCInitStruct.TIM_Pulse=0;//配置初始CCR計(jì)數(shù)器值
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
	
	//**5.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);
}

void set_Zhankongbi(uint16_t  num)
{
	TIM_SetCompare1(TIM2,num);//通過改變CCR的值,從而改變CCR/CNT占空比
}

void set_PSC(uint16_t  num)
{
	TIM_PrescalerConfig(TIM2,num,TIM_PSCReloadMode_Immediate);//改變PSC的值
}	

/***************************************************/IC輸入捕獲模塊
#include "stm32f10x.h"                  // Device header
#include "IC.h"

void IC_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//打開TMI3,因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳PA6
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**選擇內(nèi)部時(shí)鐘源
	TIM_InternalClockConfig(TIM3);
	//**3.配置時(shí)基單元
	//配置為1MHz
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=65536-1;//設(shè)置預(yù)裝載值   ARR    //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;//設(shè)置預(yù)分頻值   PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM3,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除
	
	//**4.配置IC模塊
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;//選擇通道一
	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;//選擇上升沿觸發(fā)
	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//選擇正極性
	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;//選擇一分頻
	TIM_ICInitStruct.TIM_ICFilter=0xF;//選擇濾波器的值
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	//**5.配置從模式
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	//**6.使能定時(shí)器模塊,開始計(jì)數(shù)
	TIM_Cmd(TIM3,ENABLE);
}

uint32_t get_Freq(void)
{
	return 1000000/(TIM_GetCapture1(TIM3)+1) ;
}


/***************************************************/主函數(shù)
int main(void)
{
	OLED_Init();
	pwm_init();
	IC_init();
	OLED_ShowString(1,1,"Hello,my honey");
	set_Zhankongbi(50);			//Freq = 72M / (PSC + 1) / 100
	set_PSC(720 - 1);			//Duty = CCR / 100
	while(1)
	{
		OLED_ShowNum(2,1,get_Freq(),5);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/
5.2.2 PWMI模式同時(shí)測(cè)頻率、占空比

相當(dāng)于開了TI1FP2的通道去實(shí)現(xiàn)讀取占空比

占空比是 CCR2記錄的高電平持續(xù)時(shí)間 除以 CCR1記錄的整個(gè)周期的時(shí)間

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

/***************************************************/PWM模塊
#include "stm32f10x.h"                  // Device header


void pwm_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**3.配置時(shí)基單元
	//配置為1000KHz,分辨率為1%
	TIM_InternalClockConfig(TIM2);//選擇內(nèi)部時(shí)鐘源
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=100-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除

	//**4.配置CCR
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	TIM_OCStructInit(&TIM_OCInitStruct);//先整體初始化,防止有些變量未初始化而出錯(cuò)
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//配置為PWM1輸出模式
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//配置REF為高極性
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//配置輸出使能
	TIM_OCInitStruct.TIM_Pulse=0;//配置初始CCR計(jì)數(shù)器值
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
	
	//**5.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);
}

void set_Zhankongbi(uint16_t  num)
{
	TIM_SetCompare1(TIM2,num);//通過改變CCR的值,從而改變CCR/CNT占空比
}

void set_PSC(uint16_t  num)
{
	TIM_PrescalerConfig(TIM2,num,TIM_PSCReloadMode_Immediate);//改變PSC的值
}	

/***************************************************/IC輸入捕獲模塊
#include "stm32f10x.h"                  // Device header
#include "IC.h"

void IC_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//打開TMI3,因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//**2.配置PWM輸出引腳PA6
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//**選擇內(nèi)部時(shí)鐘源
	TIM_InternalClockConfig(TIM3);
	//**3.配置時(shí)基單元
	//配置為1MHz
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=65536-1;//設(shè)置預(yù)裝載值   ARR    //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;//設(shè)置預(yù)分頻值   PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM3,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除
	
	//**4.配置IC模塊
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;//選擇通道一
	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;//選擇上升沿觸發(fā)
	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//選擇正極性
	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;//選擇一分頻
	TIM_ICInitStruct.TIM_ICFilter=0xF;//選擇濾波器的值
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);

	//**5.配置從模式
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	//**6.使能定時(shí)器模塊,開始計(jì)數(shù)
	TIM_Cmd(TIM3,ENABLE);
}

uint32_t get_Freq(void)
{
	return 1000000/(TIM_GetCapture1(TIM3)+1) ;
}

uint32_t get_Zhankongbi(void)
{
	return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);
}
/***************************************************/主函數(shù)
int main(void)
{
	OLED_Init();
	pwm_init();
	IC_init();
	OLED_ShowString(1,1,"Hello,my honey");
	set_Zhankongbi(50);			//Freq = 72M / (PSC + 1) / 100
	set_PSC(720 - 1);			//Duty = CCR / 100
	while(1)
	{
		OLED_ShowNum(2,1,get_Freq(),5);
        OLED_ShowNum(3,1,get_Zhankongbi(),3);
	}
}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/
5.2.3 編碼器接口測(cè)速(簡(jiǎn)介)

通過配置定時(shí)器,占用了IC捕獲模式的兩個(gè)通道,自動(dòng)判斷兩個(gè)腳的波形相位差和邊沿觸發(fā)(一般都是使用T1T2模式,可消除毛刺信號(hào)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Bianmaqi.h"
#include "Delay.h"
#include "timer2.h"

/***************************************************/延時(shí)函數(shù)
#include "Delay.h"
#include "stm32f10x.h" 

/**
  * @brief  微秒級(jí)延時(shí)
  * @param  xus 延時(shí)時(shí)長(zhǎng),范圍:0~233015
  * @retval 無
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//設(shè)置定時(shí)器重裝值
	SysTick->VAL = 0x00;					//清空當(dāng)前計(jì)數(shù)值
	SysTick->CTRL = 0x00000005;				//設(shè)置時(shí)鐘源為HCLK,啟動(dòng)定時(shí)器
	while(!(SysTick->CTRL & 0x00010000));	//等待計(jì)數(shù)到0
	SysTick->CTRL = 0x00000004;				//關(guān)閉定時(shí)器
}

/**
  * @brief  毫秒級(jí)延時(shí)
  * @param  xms 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒級(jí)延時(shí)
  * @param  xs 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

/***************************************************/編碼器
#include "stm32f10x.h"                  // Device header
#include "Bianmaqi.h"

void Bianmaqi_init(void)
{
	//1**使能時(shí)鐘
	RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);
	
	//2**定義GPIO
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//3**初始化時(shí)基單元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_Channel_1|TIM_Channel_2;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_Period=65536-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler=1-1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	
	//4**初始化IC模塊(部分)兩個(gè)Pin口
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICStructInit(&TIM_ICInitStruct);
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICFilter=0xF;
//	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
//	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
//	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
	TIM_ICInitStruct.TIM_ICFilter=0xF;
//	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;
//	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;
//	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	//5**配置編碼器
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Rising);//控制極性
	
	//6.使能定時(shí)器TIM3
	TIM_Cmd(TIM3,ENABLE);
}

int16_t get_cnt(void)
{
	int16_t temp=0;
	temp=TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3,0);
	return temp;
}

/***************************************************/定時(shí)器TIM2
#include "stm32f10x.h"
#include "timer2.h"

extern int num;
void timer2_init(void)
{
	//**1.打開總的RCC,要配置GPIO從而傳入外部時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因?yàn)槎〞r(shí)器2是通用定時(shí)器,在APB1總線上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//**2.配置定時(shí)器接入外部時(shí)鐘 同時(shí)配置外部時(shí)鐘輸入的引腳
	TIM_InternalClockConfig(TIM2);//設(shè)置定時(shí)器2使用內(nèi)部時(shí)鐘,可不寫,上電默認(rèn)
	
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	//TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//第二個(gè)設(shè)置分頻,第三個(gè)設(shè)置觸發(fā)方式,第四個(gè)設(shè)置采樣頻率(濾波器)
	//**3.配置時(shí)基單元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置分頻
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//設(shè)置向上l計(jì)數(shù)
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;//設(shè)置預(yù)裝載值       //外部時(shí)鐘的話用不了這么高的頻率
	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//設(shè)置預(yù)分頻值
//	TIM_TimeBaseInitStruct.TIM_Period=10-1;//設(shè)置預(yù)裝載值
//	TIM_TimeBaseInitStruct.TIM_Prescaler=2-1;//設(shè)置預(yù)分頻值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高級(jí)計(jì)數(shù)器功能,重復(fù)計(jì)數(shù)器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化時(shí)基單元
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化時(shí)會(huì)產(chǎn)生標(biāo)志位,需要清除
	//**4.使能時(shí)基單元的中斷
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	//**5.配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分組
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	//**6.開始計(jì)數(shù)
	TIM_Cmd(TIM2,ENABLE);

}
/*
//配置中斷函數(shù)
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		num++;
	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}
*/

/***************************************************/主函數(shù)
int16_t speed=0;
int main(void)
{
	timer2_init();
	OLED_Init();
	Bianmaqi_init();
	OLED_ShowString(1,1,"Hello,my honey");
	while(1)
	{
		OLED_ShowSignedNum(2,1,speed,6);
	}
} 

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		speed=get_cnt();
		Delay_ms (10);
	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}
/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

七、ADC模數(shù)轉(zhuǎn)換

1.結(jié)構(gòu)原理

1.1 介紹

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.2 原理

采樣、抽取、量化、編碼

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.3 ADC結(jié)構(gòu)框圖

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.4 stm32片上資源

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5 ADC工作的4種模式

1.5.1 單次轉(zhuǎn)換,非掃描模式

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5.2 連續(xù)轉(zhuǎn)換,非掃描模式

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5.3 單次轉(zhuǎn)換,掃描模式

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.5.4 連續(xù)轉(zhuǎn)換,掃描模式?

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.6 ADC的觸發(fā)方式(軟件,硬件)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

1.7 ADC的數(shù)據(jù)處理、轉(zhuǎn)換時(shí)間、校準(zhǔn)

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

2.代碼配置

2.1 ADC單通道模式

單次轉(zhuǎn)換、非連續(xù)模式

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "ADC.h"
#include "Delay.h"

/***************************************************/ADC模塊
#include "stm32f10x.h"                  // Device header
#include "ADC.h"


void ADC_init(void)
{
	//1.先使能時(shí)鐘
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2.設(shè)置ADC的分頻
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3.配置GPIO口PA0
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	//4.確定規(guī)則組或注入組的通道
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_28Cycles5);
	
	//5.初始化ADC
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//配置是否連續(xù)觸發(fā)模式
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//選擇數(shù)據(jù)對(duì)齊模式為右對(duì)齊
	ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//選擇外界觸發(fā)源
	ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//配置是ADC是幾個(gè)同時(shí)工作還是獨(dú)立工作
	ADC_InitStruct.ADC_NbrOfChannel=1;//確定要輸入的組的個(gè)數(shù)
	ADC_InitStruct.ADC_ScanConvMode=DISABLE;//是否連續(xù)掃描模式
	ADC_Init(ADC1, &ADC_InitStruct);
	
	//6.打開ADC
	ADC_Cmd(ADC1,ENABLE);
	
	//7.校準(zhǔn)ADC
	ADC_ResetCalibration(ADC1);//1.復(fù)位校準(zhǔn)
	while(ADC_GetResetCalibrationStatus(ADC1));//2.等待復(fù)位校準(zhǔn)完成
	ADC_StartCalibration(ADC1);//3.開始校準(zhǔn)
	while(ADC_GetCalibrationStatus(ADC1));//4.等待校準(zhǔn)完成
}

uint16_t get_adcvalue(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//觸發(fā)開始ADC讀值
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//讀取EOC標(biāo)志位,當(dāng)轉(zhuǎn)化讀取完成后退出循環(huán)
	return ADC_GetConversionValue(ADC1);//讀取ADC寄存器,自動(dòng)清除EOC標(biāo)志位
}

/***************************************************/延時(shí)函數(shù)
#include "Delay.h"
#include "stm32f10x.h" 

/**
  * @brief  微秒級(jí)延時(shí)
  * @param  xus 延時(shí)時(shí)長(zhǎng),范圍:0~233015
  * @retval 無
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//設(shè)置定時(shí)器重裝值
	SysTick->VAL = 0x00;					//清空當(dāng)前計(jì)數(shù)值
	SysTick->CTRL = 0x00000005;				//設(shè)置時(shí)鐘源為HCLK,啟動(dòng)定時(shí)器
	while(!(SysTick->CTRL & 0x00010000));	//等待計(jì)數(shù)到0
	SysTick->CTRL = 0x00000004;				//關(guān)閉定時(shí)器
}

/**
  * @brief  毫秒級(jí)延時(shí)
  * @param  xms 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒級(jí)延時(shí)
  * @param  xs 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

/***************************************************/主函數(shù)

uint16_t ADCvalue;//旋鈕值
float  Voltage;//轉(zhuǎn)換成電壓值
int main(void)
{
	OLED_Init();
	ADC_init();
	OLED_ShowString(1,1,"Hello,my honey");

	OLED_ShowString(2, 1, "ADValue:");
	OLED_ShowString(3, 1, "Volatge:0.00V");
	while(1)
	{
		ADCvalue=get_adcvalue();
		Voltage = (float)ADCvalue / 4095 * 3.3;
		
		OLED_ShowNum(2, 9, ADCvalue, 4);
		OLED_ShowNum(3, 9, Voltage, 1);//這里將電壓值按整數(shù)部分和小數(shù)部分兩部分取出來
		OLED_ShowNum(3, 11, (uint16_t)(Voltage * 100) % 100, 2);
		
		Delay_ms(100);;
	}
}


/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

**2.簡(jiǎn)單實(shí)現(xiàn)ADC多通道

每次改變序號(hào)里的通道即可;

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "ADC.h"
#include "Delay.h"

/***************************************************/ADC
#include "stm32f10x.h"                  // Device header
#include "ADC.h"


void ADC_init(void)
{
	//1.先使能時(shí)鐘
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2.設(shè)置ADC的分頻
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3.配置GPIO口PA0
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	//4.確定規(guī)則組或注入組的通道
//	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_28Cycles5);
	
	//5.初始化ADC
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//配置是否連續(xù)觸發(fā)模式
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//選擇數(shù)據(jù)對(duì)齊模式為右對(duì)齊
	ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//選擇外界觸發(fā)源
	ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//配置是ADC是幾個(gè)同時(shí)工作還是獨(dú)立工作
	ADC_InitStruct.ADC_NbrOfChannel=1;//確定要輸入的組的個(gè)數(shù)
	ADC_InitStruct.ADC_ScanConvMode=DISABLE;//是否連續(xù)掃描模式
	ADC_Init(ADC1, &ADC_InitStruct);
	
	//6.打開ADC
	ADC_Cmd(ADC1,ENABLE);
	
	//7.校準(zhǔn)ADC
	ADC_ResetCalibration(ADC1);//1.復(fù)位校準(zhǔn)
	while(ADC_GetResetCalibrationStatus(ADC1));//2.等待復(fù)位校準(zhǔn)完成
	ADC_StartCalibration(ADC1);//3.開始校準(zhǔn)
	while(ADC_GetCalibrationStatus(ADC1));//4.等待校準(zhǔn)完成
}

uint16_t get_adcvalue(uint8_t ADC_Channel)
{
		ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_28Cycles5);

	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//觸發(fā)開始ADC讀值
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//讀取EOC標(biāo)志位,當(dāng)轉(zhuǎn)化讀取完成后退出循環(huán)
	return ADC_GetConversionValue(ADC1);//讀取ADC寄存器,自動(dòng)清除EOC標(biāo)志位
}
     
/***************************************************/延時(shí)
#include "Delay.h"
#include "stm32f10x.h" 

/**
  * @brief  微秒級(jí)延時(shí)
  * @param  xus 延時(shí)時(shí)長(zhǎng),范圍:0~233015
  * @retval 無
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//設(shè)置定時(shí)器重裝值
	SysTick->VAL = 0x00;					//清空當(dāng)前計(jì)數(shù)值
	SysTick->CTRL = 0x00000005;				//設(shè)置時(shí)鐘源為HCLK,啟動(dòng)定時(shí)器
	while(!(SysTick->CTRL & 0x00010000));	//等待計(jì)數(shù)到0
	SysTick->CTRL = 0x00000004;				//關(guān)閉定時(shí)器
}

/**
  * @brief  毫秒級(jí)延時(shí)
  * @param  xms 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒級(jí)延時(shí)
  * @param  xs 延時(shí)時(shí)長(zhǎng),范圍:0~4294967295
  * @retval 無
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

/***************************************************/主函數(shù)
uint16_t key,light;

int main(void)
{
	OLED_Init();
	ADC_init();
	OLED_ShowString(1,1,"Hello,my honey");
//	OLED_ShowString(2,1,"Hello WangFang");
//	OLED_ShowString(3,1,"Hello Tomorrow");
//	OLED_ShowString(4,1,"I miss you");

	while(1)
	{
		key=get_adcvalue(ADC_Channel_0);
		light=get_adcvalue(ADC_Channel_1);
		
		OLED_ShowNum(2,1,key,5);
		OLED_ShowNum(3,1,light,5);
	}
}

/*********************阿布君***********************/
/****************編碼不易,謝謝關(guān)注*****************/
/****************QQ:2062808868********************/

3.DMA實(shí)現(xiàn)數(shù)據(jù)遷移

**1.結(jié)構(gòu)原理

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

stm32f103c8t6的啟動(dòng)文件,stm32,筆記,單片機(jī),嵌入式硬件,c語言

待續(xù)

8.USART串口

1.文章來源地址http://www.zghlxwxcb.cn/news/detail-779502.html

到了這里,關(guān)于stm32(F103c8t6)自學(xué)筆記@阿布君的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 F103C8T6學(xué)習(xí)筆記4:時(shí)鐘樹、滴答計(jì)時(shí)器、定時(shí)器定時(shí)中斷

    STM32 F103C8T6學(xué)習(xí)筆記4:時(shí)鐘樹、滴答計(jì)時(shí)器、定時(shí)器定時(shí)中斷

    今日理解一下STM32F103 C8T6的時(shí)鐘與時(shí)鐘系統(tǒng)、滴答計(jì)時(shí)器、定時(shí)器計(jì)時(shí)中斷的配置,文章提供原理,代碼,測(cè)試工程下載。 目錄 時(shí)鐘樹與時(shí)鐘系統(tǒng): 滴答計(jì)時(shí)器: 定時(shí)器計(jì)時(shí)中斷: 測(cè)試結(jié)果: 測(cè)試工程下載: 該系統(tǒng)介紹在 STM32F10x-中文參考手冊(cè) P56頁開始 微控制器的時(shí)鐘系

    2024年02月13日
    瀏覽(32)
  • STM32 F103C8T6學(xué)習(xí)筆記8:0.96寸單色OLED顯示屏顯示字符

    STM32 F103C8T6學(xué)習(xí)筆記8:0.96寸單色OLED顯示屏顯示字符

    使用STM32F103 C8T6 驅(qū)動(dòng)0.96寸單色OLED顯示屏: OLED顯示屏的驅(qū)動(dòng),在設(shè)計(jì)開發(fā)中OLED顯示屏十分常見,因此今日學(xué)習(xí)一下。一篇文章從程序到顯示都講通。 文章提供源碼、原理解釋、測(cè)試工程下載,測(cè)試效果圖展示。 ? 目錄 OLED驅(qū)動(dòng)原理—IIC通信: SSD1306 單色 0.96 OLED 顯示屏特性

    2024年02月12日
    瀏覽(24)
  • STM32 F103C8T6學(xué)習(xí)筆記13:IIC通信—AHT10溫濕度傳感器模塊

    STM32 F103C8T6學(xué)習(xí)筆記13:IIC通信—AHT10溫濕度傳感器模塊

    今日學(xué)習(xí)一下這款A(yù)HT10 溫濕度傳感器模塊,給我的OLED手環(huán)添加上測(cè)溫濕度的功能。 文章提供源碼、測(cè)試工程下載、測(cè)試效果圖。 目錄 AHT10溫濕度傳感器: 特性: 連接方式: 適用場(chǎng)所范圍: 程序設(shè)計(jì): 設(shè)計(jì)目標(biāo): ?程序設(shè)計(jì)注意點(diǎn): AHT10代碼: ?主函數(shù)代碼: 測(cè)試效果:

    2024年02月11日
    瀏覽(26)
  • STM32 F103C8T6學(xué)習(xí)筆記5:定時(shí)器輸出不同占空比PWM驅(qū)動(dòng)舵機(jī)旋轉(zhuǎn)角度

    現(xiàn)在學(xué)習(xí)使用STM32 F103C8T6的定時(shí)器PWM模式,使用PWM驅(qū)動(dòng)舵機(jī)轉(zhuǎn)動(dòng)不同角度,文章提供源碼,測(cè)試工程,測(cè)試動(dòng)態(tài)效果圖。 目錄 基礎(chǔ)原理: ?實(shí)驗(yàn)?zāi)繕?biāo): 測(cè)試視頻結(jié)果: 測(cè)試工程下載: 這次依舊拿出之前學(xué)習(xí)過的舵機(jī)DS3115,它的基礎(chǔ)原理不多加介紹,在往期講MSP432的文章有所

    2024年02月13日
    瀏覽(25)
  • STM32 F103C8T6學(xué)習(xí)筆記2:GPIO的認(rèn)識(shí)—GPIO的基本輸入輸出—點(diǎn)亮一個(gè)LED

    STM32 F103C8T6學(xué)習(xí)筆記2:GPIO的認(rèn)識(shí)—GPIO的基本輸入輸出—點(diǎn)亮一個(gè)LED

    今日繼續(xù)學(xué)習(xí)使用? STM32 F103C8T6開發(fā)板 點(diǎn)亮一個(gè)LED燈,文章提供源碼,測(cè)試工程,實(shí)驗(yàn)效果圖,希望我的歸納總結(jié)會(huì)對(duì)大家有幫助~ 目錄 GPIO的認(rèn)識(shí)與分類 : 引腳安排整理: 定時(shí)器的引腳例舉: 串口的引腳例舉: ?CAN串口通信: SPI通信: IIC通信: ?其余引腳: 燒錄引腳:

    2024年02月11日
    瀏覽(19)
  • STM32 HAL庫 CubeMX配置 定時(shí)器學(xué)習(xí) F103C8T6

    STM32 HAL庫 CubeMX配置 定時(shí)器學(xué)習(xí) F103C8T6

    開發(fā)板: STM32F103C8T6最小系統(tǒng)板 編譯環(huán)境: Keil5 MDK 輔助軟件: STM32 CubeMX 課程教學(xué): 基于正點(diǎn)原子HAL庫學(xué)習(xí)教程 其余配件: 江科大STM32配件包?和 示波器一臺(tái) 備注: ?因?yàn)檫@塊開發(fā)板沒有基本定時(shí)器,所以本文也 沒有基本定時(shí)器的內(nèi)容 ????????????本文1.3和2.1部分的

    2024年04月26日
    瀏覽(21)
  • STM32 F103C8T6學(xué)習(xí)筆記10:OLED顯示屏GIF動(dòng)圖取?!?jiǎn)易時(shí)鐘—?jiǎng)訄D手表的制作~

    STM32 F103C8T6學(xué)習(xí)筆記10:OLED顯示屏GIF動(dòng)圖取模—簡(jiǎn)易時(shí)鐘—?jiǎng)訄D手表的制作~

    今日嘗試做一款有動(dòng)圖的OLED實(shí)時(shí)時(shí)鐘,本文需要現(xiàn)學(xué)一個(gè)OLED的GIF動(dòng)圖取模 其余需要的知識(shí)點(diǎn)有不會(huì)的可以去我? STM32 F103C8T6學(xué)習(xí)筆記? 系列專欄自己查閱把,閑話不多,直接開肝~~~ 文章提供源碼,測(cè)試工程下載,測(cè)試效果圖。 做個(gè)簡(jiǎn)易的時(shí)鐘,就不把RTC實(shí)時(shí)時(shí)鐘放進(jìn)來學(xué)了

    2024年02月12日
    瀏覽(42)
  • STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信_(tái)_驅(qū)動(dòng)MPU6050 6軸運(yùn)動(dòng)處理組件—一階互補(bǔ)濾波

    STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信_(tái)_驅(qū)動(dòng)MPU6050 6軸運(yùn)動(dòng)處理組件—一階互補(bǔ)濾波

    今日主要學(xué)習(xí)一款傾角傳感器——MPU6050,往后對(duì)單片機(jī)原理基礎(chǔ)講的會(huì)比較少,更傾向于簡(jiǎn)單粗暴地貼代碼,因?yàn)榻?jīng)過前些日子對(duì)MSP432的學(xué)習(xí),對(duì)原理方面也有些熟絡(luò)了,除了在新接觸它時(shí)會(huì)對(duì)其引腳、時(shí)鐘、總線等進(jìn)行仔細(xì)一些的研究之外,其余驅(qū)動(dòng)方面便是照搬經(jīng)驗(yàn)了~

    2024年02月13日
    瀏覽(24)
  • STM32 F103C8T6學(xué)習(xí)筆記9:0.96寸單色OLED顯示屏—自由取模顯示—顯示漢字與圖片

    STM32 F103C8T6學(xué)習(xí)筆記9:0.96寸單色OLED顯示屏—自由取模顯示—顯示漢字與圖片

    今日學(xué)習(xí)0.96寸單色OLED顯示屏的自由取模顯示: 宋體漢字比較復(fù)雜,常用字符可以直接復(fù)制存下來,畢竟只有那么幾十個(gè)字母字符,但漢字實(shí)在太多了,基本不會(huì)全部放在單片機(jī)里存著,一般用到多少個(gè)字就取幾個(gè)字的模,因此漢字放在這里與自由取模一起講。 文章提供源碼

    2024年02月11日
    瀏覽(25)
  • STM32系列(HAL庫)——F103C8T6獲取DHT11溫濕度串口打印

    STM32系列(HAL庫)——F103C8T6獲取DHT11溫濕度串口打印

    在此特別鳴謝原文博主! (1)編程平臺(tái):Keil5 (2)CubeMX (3)XCOM(串口調(diào)試助手) (1)F1的板子,本例使用經(jīng)典F103C8T6 ?(2)DHT11——溫濕度傳感器 (3)ST-link?下載器 (4)USB-TTL模塊 (5)杜邦線若干 (1)芯片選擇 STM32F103C8T6 ?(2)配置RCC、SYS、時(shí)鐘樹 配置RCC 配置SYS 配置時(shí)鐘樹 (3) 配置GPIO ?(4)配置

    2023年04月08日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包