当前位置:网站首页>三.芯片啟動和時鐘系統
三.芯片啟動和時鐘系統
2022-07-02 11:07:00 【車水碼濃】
芯片啟動和時鐘系統
1.芯片啟動
首先stm32會根據啟動方式(參考手册2.4節)從啟動比特置加載啟動代碼到內存中,之後開始執行啟動代碼,一般啟動代碼使用官方提供的即可 ---------- xxx.s

啟動代碼的工作:
初始化堆棧空間,定義异常向量錶 調用SystemInit ----------- 系統初始化 初始化時鐘,調整异常向量錶 執行main ---------- 主函數
芯片要開始工作,必須初始化時鐘和內存,stm32的內存使用片內SRAM,可以直接使用,時鐘需要初始化,ARM芯片需要定義异常向量錶,執行C語言代碼必須初始化堆棧。
stm32f407推薦的主時鐘頻率 168MHz
2.產生原始頻率的硬件
(1)晶振
(2)RC(LC)振蕩電路
原始頻率不會很高,使用前必須昇頻,昇頻使用PLL(昇頻)電路
CPU時鐘系統的大體結構

3.stm32f407的原始時鐘
HSI RC -------------- 高速內部振蕩時鐘 16M HSE OSC ------------- 高速外部晶振 4~26M(8M) //以上兩個時鐘源可以直接作為系統主時鐘,也可以通過PLL昇頻後作為主時鐘 LSI RC --------------- 低速內部振蕩時鐘 32K ----- 看門狗 LSE OSC -------------- 低速外部晶振 32.768K ----- RTC
stm32f407的時鐘樹

PLL的輸出時鐘 = PLL輸入時鐘 X PLLN / PLLM / PLLP
168M = 8M X 336 / 8 / 2
4.將keil5的工程的系統時鐘配置為168MHz
(1)修改system_stm32f4xx.c的254行
#define PLL_M 8
(2)修改stm32f4xx.h的127行
//該文件是只讀屬性文件,要去文件系統中找到該文件,去掉只讀屬性 #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
練習:
將系統主頻配置為168M
修改PLL,調節系統主頻
#define PLL_N 336//168M #define PLL_N 432//216M 超頻 #define PLL_N 168//84M 降頻
系統總線時鐘頻率:
SYSCLK時鐘 ------------ 168MHz HCLK/AHB總線 ---------- 168MHz APB1時鐘 -------------- 42MHz APB2時鐘 -------------- 84MHz
__________________________________________________________________________________________________________________________________________________________
按鍵驅動
1.看原理圖



從原理圖可知:
按鍵松開 -------- 引脚高電平
按鍵按下 -------- 引脚低電平
按鍵對應的引脚:
S1 ----- PA0
S2 ----- PE2
S3 ----- PE3
S4 ----- PE4
如何讀取輸入引脚的電平
(1)讀取輸入數據寄存器(IDR)對應比特的值 1 ----- 輸入高電平 0 ----- 輸入低電平
(2)比特段操作 PAin(0)==0 ----- 輸入低電平 PAin(0)==1 ----- 輸入高電平
(3)庫函數 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //傳入哪一組哪個脚,返回該引脚的電平
——————————————————————————————————————————————————————————————————————————————————————
練習:
完成其他三個按鍵的檢測程序,分別使用 寄存器 比特段 庫函數判斷
實現一下功能:
按下S2,D2亮 按下S3,D3亮 按下S4,D4亮
//key.c
#include <stm32f4xx.h>
#include <key.h>
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//1.開啟GPIOA的時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE,ENABLE);
//2.GPIO初始化 PA0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;//輸入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//無上下拉
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;//PA0
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//PE2 PE3 PE4
GPIO_Init(GPIOE,&GPIO_InitStruct);//main.c
#include <stm32f4xx.h>
#include <led.h>
#include <sys.h>
#include <key.h>
int main()
{
int key_flag = 0;
//初始化
led_init();
key_init();
while(1){
if(S1==0){
//延時消抖10ms
delay(100);
if(S1==0){
//真實按鍵事件
if(key_flag==0){//按下沒有松開
D1 = ~D1;//取反
key_flag = 1;
}
}
}
else{
//延時消抖10ms
delay(100);
if(S1){
key_flag = 0;
}
}
}
}//lcd.c
include <stm32f4xx.h>
#include <led.h>
void delay(unsigned int ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=0;j<5000;j++);
}
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//1.開啟GPIOE GPIOF的時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF,ENABLE);
//2.GPIO初始化 PF9 PF10 PE13 PE14
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//輸出模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽輸出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//無上下拉
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;//PF9 PF10
GPIO_Init(GPIOF,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;//PE13 PE14
GPIO_Init(GPIOE,&GPIO_InitStruct);
//3.LED默認關閉
GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14);
}//lcd.h
#ifndef _LED_H_
#define _LED_H_
#define D1 PFout(9)
#define D2 PFout(10)
#define D3 PEout(13)
#define D4 PEout(14)
void delay(unsigned int ms);
void led_init(void);
#endif//key.h
#ifndef _KEY_H_
#define _KEY_H_
#define S1 PAin(0)
#define S2 PEin(2)
#define S3 PEin(3)
#define S4 PEin(4)
void key_init(void);
#endif//sys.h 該文件由系統定義
#ifndef __SYS_H_
#define __SYS_H_
#include "stm32f4xx.h"
//IO口操作宏定義
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414 20 = 0x14
#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014
#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010 16 = 0x10
#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010
//IO口操作,只對單一的IO口!
//確保n的值小於16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //輸出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //輸入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //輸出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //輸入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //輸出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //輸入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //輸出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //輸入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //輸出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //輸入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //輸出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //輸入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //輸出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //輸入
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //輸出
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //輸入
#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //輸出
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //輸入
#endif
3.按鍵消抖————延時消抖

以上按鍵程序不管是否有按鍵事件發生,都會占用CPU來進行判斷,這種方式叫做輪詢,效率比較低,CPU提供了效率更高的方式 --------- 中斷。
边栏推荐
- Learn open62541 -- [66] UA_ Generation method of string
- 主键策略问题
- 使用华为性能管理服务,按需配置采样率
- JSP webshell免杀——JSP的基础
- 618 what is the secret of dominating the list again? Nike's latest financial report gives the answer
- 力扣(LeetCode)182. 查找重复的电子邮箱(2022.07.01)
- Special topic of binary tree -- acwing 1589 Building binary search tree
- 【深入浅出玩转FPGA学习5-----复位设计】
- Luogu p5536 [xr-3] core city (greed + tree DP looking for the center of the tree)
- Hdu1234 door opener and door closer (water question)
猜你喜欢
![二叉树专题--洛谷 P3884 [JLOI2009]二叉树问题(dfs求二叉树深度 bfs求二叉树宽度 dijkstra求最短路)](/img/c2/bb85b681af0f78b380b1d179c7ea49.png)
二叉树专题--洛谷 P3884 [JLOI2009]二叉树问题(dfs求二叉树深度 bfs求二叉树宽度 dijkstra求最短路)

Special topic of binary tree -- acwing 18 Rebuild the binary tree (construct the binary tree by traversing the front and middle order)

Flick two open, realized a batch lookup join (with source code)

JVM之垃圾回收器

JVM garbage collector

Flink two Open, implement Batch Lookup join (attached source)

如何用list组件实现tabbar标题栏

最详细MySql安装教程

flink二開,實現了個 batch lookup join(附源碼)

flink二开,实现了个 batch lookup join(附源码)
随机推荐
MySQL keyword
2022-06-17
TIPC介绍1
static 函数中的静态变量
Special topic of binary tree -- [deep base 16. Example 7] ordinary binary tree (simplified version) (multiset seeks the precursor and subsequent sentry Art)
软件产品管理系统有哪些?12个最佳产品管理工具盘点
How to use ide to automatically sign and debug Hongmeng application
How to implement tabbar title bar with list component
[applinking practical case] share in app pictures through applinking
C#中索引器
K-d tree and octree of PCL
What are the software product management systems? Inventory of 12 best product management tools
Huawei game failed to initialize init with error code 907135000
【快应用】Win7系统使用华为IDE无法运行和调试项目
二叉树专题--AcWing 18. 重建二叉树(利用前、中序遍历,构建二叉树)
一.STM32的开发环境,keil5/MDK5.14安装教程(附下载链接)
Openmldb meetup No.4 meeting minutes
The most detailed MySQL installation tutorial
Matlab processing of distance measurement of experimental electron microscope
TIPC messaging3