当前位置:网站首页>三.芯片啟動和時鐘系統
三.芯片啟動和時鐘系統
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提供了效率更高的方式 --------- 中斷。
边栏推荐
- 华为游戏初始化init失败,返回错误码907135000
- 2022-06-17
- TIPC Service and Topology Tracking4
- JSP webshell免殺——JSP的基礎
- 2022爱分析· 国央企数字化厂商全景报告
- 洛谷 P3398 仓鼠找 sugar(树上倍增 lca 判断树中两条路径是否相交 结论)
- The difference between self and static in PHP in methods
- V2X-Sim数据集(上海交大&纽约大学)
- 618 what is the secret of dominating the list again? Nike's latest financial report gives the answer
- Common methods of JS array
猜你喜欢

Open the encrypted SQLite method with sqlcipher

【深入浅出玩转FPGA学习2----设计技巧(基本语法)】
![[SUCTF2018]followme](/img/63/9104f9c8bd24937b0fc65053efec96.png)
[SUCTF2018]followme

洛谷 P5536 【XR-3】核心城市(贪心 + 树形 dp 寻找树的中心)

From Read and save in bag file Jpg pictures and PCD point cloud

Hdu1234 door opener and door closer (water question)

【深入浅出玩转FPGA学习3-----基本语法】

Shell programming 01_ Shell foundation

V2X-Sim数据集(上海交大&纽约大学)

Jsp webshell Free from killing - The Foundation of JSP
随机推荐
二叉树专题--P1030 [NOIP2001 普及组] 求先序排列
Nodejs+express+mysql simple blog building
Convert yv12 to rgb565 image conversion, with YUV to RGB test
PCL eigen introduction and simple use
首份中国企业敏捷实践白皮书发布| 附完整下载
Logu p3398 hamster looks for sugar (double LCA on the tree to judge whether the two paths in the tree intersect)
Matlab processing of distance measurement of experimental electron microscope
TIPC Cluster5
二叉树专题--AcWing 3540. 二叉搜索树建树(实用板子 构建二叉搜索树 并输出前、中、后序遍历)
全网显示 IP 归属地,是怎么实现的?
MySQL lethal serial question 4 -- are you familiar with MySQL logs?
Record attributeerror: 'nonetype' object has no attribute 'nextcall‘
Primary key policy problem
V2X-Sim数据集(上海交大&纽约大学)
Read H264 parameters from mediarecord recording
Disassembling Meitu SaaS: driving the plane to change the engine
TIPC 寻址2
TIPC Getting Started6
Overview of integrated learning
From Read and save in bag file Jpg pictures and PCD point cloud