当前位置:网站首页>三.芯片啟動和時鐘系統
三.芯片啟動和時鐘系統
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提供了效率更高的方式 --------- 中斷。
边栏推荐
- How to implement tabbar title bar with list component
- 二叉树专题--AcWing 18. 重建二叉树(利用前、中序遍历,构建二叉树)
- (5) Gear control setting of APA scene construction
- 全网显示 IP 归属地,是怎么实现的?
- The most detailed MySQL installation tutorial
- 【付费推广】常见问题合集,推荐榜单FAQ
- 【AppLinking实战案例】通过AppLinking分享应用内图片
- flink二开,实现了个 batch lookup join(附源码)
- Binary tree topic -- Luogu p3884 [jloi2009] binary tree problem (DFS for binary tree depth BFS for binary tree width Dijkstra for shortest path)
- P1055 [NOIP2008 普及组] ISBN 号码
猜你喜欢
【深入浅出玩转FPGA学习2----设计技巧(基本语法)】
nodejs+express+mysql简单博客搭建
1287_ Implementation analysis of prvtaskistasksuspended() interface in FreeRTOS
2. Hacking lab script off [detailed writeup]
How to use ide to automatically sign and debug Hongmeng application
JVM garbage collector
【快应用】text组件里的文字很多,旁边的div样式会被拉伸如何解决
How to transfer event objects and user-defined parameters simultaneously in Huawei express applications
Creation and use of unified links in Huawei applinking
JSP webshell免殺——JSP的基礎
随机推荐
(5) Gear control setting of APA scene construction
TIPC Cluster5
The first white paper on agile practice in Chinese enterprises was released | complete download is attached
Record attributeerror: 'nonetype' object has no attribute 'nextcall‘
Easyexcel, a concise, fast and memory saving excel processing tool
MySQL environment configuration
V2x SIM dataset (Shanghai Jiaotong University & New York University)
2022 love analysis · panoramic report of digital manufacturers of state-owned enterprises
二叉树专题--AcWing 1497. 树的遍历(利用后、中序遍历,构建二叉树)
[play with FPGA learning 5 in simple terms ----- reset design]
【深入浅出玩转FPGA学习2----设计技巧(基本语法)】
MongoDB 学习整理(条件操作符,$type 操作符,limit()方法,skip() 方法 和 sort() 方法)
Appgallery connect scenario development practice - image storage and sharing
一.STM32的开发环境,keil5/MDK5.14安装教程(附下载链接)
正则及常用公式
Uncover the secrets of Huawei application market application statistics
Oracle 笔记
首份中国企业敏捷实践白皮书发布| 附完整下载
Common methods of JS array
Static variables in static function