加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1. delay文件
    • 2. sys文件
    • 重要函數(shù)
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

STM32固件庫system文件介紹

02/06 16:49
3646
閱讀需 24 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1. delay文件

delay 文件夾內(nèi)包含了 delay.c 和 delay.h 兩個(gè)文件,這兩個(gè)文件用來實(shí)現(xiàn)系統(tǒng)的延時(shí)功能,其中包含 7 個(gè)函數(shù):

void delay_osschedlock(void); 
void delay_osschedunlock(void); 
void delay_ostimedly(u32 ticks); 
void SysTick_Handler(void); 

前面 4 個(gè)函數(shù),僅在支持操作系統(tǒng)(OS)的時(shí)候,需要用到,而后面三個(gè)函數(shù),則不論是否支持 OS 都需要用到。

void delay_init(void); 
void delay_ms(u16 nms); 
void delay_us(u32 nus); 
void      delay_init(void); 
//初始化延遲函數(shù) 
//當(dāng)使用 OS 的時(shí)候,此函數(shù)會(huì)初始化 OS 的時(shí)鐘節(jié)拍 
//SYSTICK 的時(shí)鐘固定為 HCLK 時(shí)鐘的 1/8 
//SYSCLK:系統(tǒng)時(shí)鐘 
void delay_init(u8 SYSCLK) 
{ 
#if SYSTEM_SUPPORT_OS //如果需要支持 OS. 
 u32 reload; 
#endif 
 SysTick->CTRL&=~(1<<2); //SYSTICK 使用外部時(shí)鐘源 
 fac_us=SYSCLK/8; //不論是否使用 OS,fac_us 都需要使用 
#if SYSTEM_SUPPORT_OS //如果需要支持 OS. 
 reload=SYSCLK/8; //每秒鐘的計(jì)數(shù)次數(shù) 單位為 K ,所以對(duì)于晶振是9MHZ時(shí) syclk=72000
 reload*=1000000/delay_ostickspersec; //根據(jù) delay_ostickspersec 設(shè)定溢出時(shí)間 
 //reload 為 24 位寄存器,最大值:16777216,在 72M 下,約合 1.86s 左右 
 fac_ms=1000/delay_ostickspersec; //代表 OS 可以延時(shí)的最少單位 
 SysTick->CTRL|=1<<1; //開啟 SYSTICK 中斷 
 SysTick->LOAD=reload; //每 1/delay_ostickspersec 秒中斷一次 
 SysTick->CTRL|=1<<0; //開啟 SYSTICK 
#else 
 fac_ms=(u16)fac_us*1000; //非 OS 下,代表每個(gè) ms 需要的 systick 時(shí)鐘數(shù) 
#endif 
} 

2. sys文件

    1. 共有五個(gè)文件,其中sys.c和sys.h是由ALIENTEK提供,是重點(diǎn)介紹的部分。在 sys.h 里面定義了 STM32F1 的 IO 口輸入讀取宏定義和輸出宏定義。sys.c 里面定義了很多STM32F1 底層硬件很相關(guān)的設(shè)置函數(shù),包括系統(tǒng)時(shí)鐘的配置、IO 配置、中斷的配置等。下面我們將分別向大家介紹這兩個(gè)文件。
      1. 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+12) //0x4001080C 
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C 
對(duì)應(yīng):
//IO 口操作,只對(duì)單一的 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) //輸入 
//這使得調(diào)取IO口非常方便

重要函數(shù)

    1. Stm32_Clock_Init 函數(shù)
//系統(tǒng)時(shí)鐘初始化函數(shù) 
//pll:選擇的倍頻數(shù),從 2 開始,最大值為 16 
void Stm32_Clock_Init(u8 PLL) 
{ 
 unsigned char temp=0; 
 MYRCC_DeInit(); //復(fù)位并配置向量表 
 RCC->CR|=0x00010000; //外部高速時(shí)鐘使能 HSEON 
 while(!(RCC->CR>>17)); //等待外部時(shí)鐘就緒 
 RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1; 
 PLL-=2; //抵消 2 個(gè)單位 
 RCC->CFGR|=PLL<<18; //設(shè)置 PLL 值 2~16 
 RCC->CFGR|=1<<16; //PLLSRC ON 
 FLASH->ACR|=0x32; //FLASH 2 個(gè)延時(shí)周期 
 RCC->CR|=0x01000000; //PLLON 
 while(!(RCC->CR>>25)); //等待 PLL 鎖定 
 RCC->CFGR|=0x00000002; //PLL 作為系統(tǒng)時(shí)鐘 
 while(temp!=0x02) //等待 PLL 作為系統(tǒng)時(shí)鐘設(shè)置成功 
 { 
  temp=RCC->CFGR>>2; 
 temp&=0x03; 
 } 
} 
//Stm32_Clock_Init 函數(shù)中,我們?cè)O(shè)置了 APB1 為 2 分頻,APB2 為 1 分頻,AHB 為 1 分頻,

同時(shí)選擇 PLLCLK 作為系統(tǒng)時(shí)鐘。該函數(shù)只有一個(gè)參數(shù) PLL,就是用來配置時(shí)鐘的倍頻數(shù)的,比如當(dāng)前所用的晶振為 8Mhz,PLL 的值設(shè)為 9,那么 STM32 將運(yùn)行在 72M 的速度下。

  1. MYRCC_DeInit 函數(shù)

MYRCC_DeInit 函數(shù)實(shí)現(xiàn)外設(shè)的復(fù)位,并關(guān)斷所有中斷,同時(shí)調(diào)用向量表配置函數(shù)MY_NVIC_SetVectorTable,配置中斷向量表。MYRCC_DeInit 函數(shù)如下:

//把所有時(shí)鐘寄存器復(fù)位 
void MYRCC_DeInit(void) 
{ 
 RCC->APB1RSTR = 0x00000000;//復(fù)位結(jié)束 
 RCC->APB2RSTR = 0x00000000; 
 RCC->AHBENR = 0x00000014; //睡眠模式閃存和 SRAM 時(shí)鐘使能.其他關(guān)閉. 
 RCC->APB2ENR = 0x00000000; //外設(shè)時(shí)鐘關(guān)閉. 
 RCC->APB1ENR = 0x00000000; 
 RCC->CR |= 0x00000001; //使能內(nèi)部高速時(shí)鐘 HSION 
 RCC->CFGR &= 0xF8FF0000; 
//復(fù)位 SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0] 
 RCC->CR &= 0xFEF6FFFF; //復(fù)位 HSEON,CSSON,PLLON 
 RCC->CR &= 0xFFFBFFFF; //復(fù)位 HSEBYP 
 RCC->CFGR &= 0xFF80FFFF;//復(fù)位 PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE 
 RCC->CIR = 0x00000000; //關(guān)閉所有中斷 
 //配置向量表 
#ifdef VECT_TAB_RAM 
 MY_NVIC_SetVectorTable(0x20000000, 0x0); 
#else 
 MY_NVIC_SetVectorTable(0x08000000,0x0); 
#endif 
} 
  1. Sys_Soft_Reset 函數(shù)

該函數(shù)用來實(shí)現(xiàn) STM32 的軟復(fù)位,代碼如下:

//系統(tǒng)軟復(fù)位 
void Sys_Soft_Reset(void) 
{ 
 SCB->AIRCR =0X05FA0000|(u32)0x04; 
} 
SCB  MDK 定義的一個(gè)寄存器組,里面包含了很多與內(nèi)核相關(guān)的控制器,該結(jié)構(gòu)體
core_m3.h 里面,可以找到,具體的定義如下所示: 
typedef struct 
{ 
 __I uint32_t CPUID; //CM3 內(nèi)核版本號(hào)寄存器 
 __IO uint32_t ICSR; //中斷控制及狀態(tài)控制寄存器 
 __IO uint32_t VTOR; //向量表偏移量寄存器 
 __IO uint32_t AIRCR; //應(yīng)用程序中斷及復(fù)位控制寄存器 
 __IO uint32_t SCR; //系統(tǒng)控制寄存器 
 __IO uint32_t CCR; //配置與控制寄存器 
 __IO uint8_t SHP[12]; //系統(tǒng)異常優(yōu)先級(jí)寄存器組 
 __IO uint32_t SHCSR; //系統(tǒng) Handler 控制及狀態(tài)寄存器 
 __IO uint32_t CFSR; //MFSR+BFSR+UFSR 
 __IO uint32_t HFSR; //硬件 fault 狀態(tài)寄存器 
 __IO uint32_t DFSR; //調(diào)試 fault 狀態(tài)寄存器 
 __IO uint32_t MMFAR; //存儲(chǔ)管理地址寄存器 
 __IO uint32_t BFAR; //硬件 fault 地址寄存器 
 __IO uint32_t AFSR; //輔助 fault 地址寄存器 
 __I uint32_t PFR[2]; //處理器功能寄存器 
 __I uint32_t DFR; //調(diào)試功能寄存器 
__I uint32_t ADR; //輔助功能寄存器 
 __I uint32_t MMFR[4]; //存儲(chǔ)器模型功能寄存器 
 __I uint32_t ISAR[5]; //ISA 功能寄存器 
} SCB_TypeDef; 

在 Sys_Soft_Reset 函數(shù)里面,我們只是對(duì) SCB-> AIRCR 進(jìn)行了一次操作,即實(shí)現(xiàn)了 STM32的軟復(fù)位。AIRCR 寄存器的各位定義如圖 5.2.3.1 所示:

  1. usart 文件夾介
    1. usart.c 里面包含了 2 個(gè)函數(shù)
      1. 一個(gè)是 void USART1_IRQHandler(void);
      2. 另外一個(gè)是 void uart_init(u32 bound);
      3. 還有一段對(duì)串口 printf 的支持代碼,如果去掉,則會(huì)導(dǎo)致 printf 無法使用,雖然軟件編譯不會(huì)報(bào)錯(cuò),但是硬件上 STM32 是無法啟動(dòng)的,這段代碼不要去修改。
    2. printf 函數(shù)向串口發(fā)送我們需要的內(nèi)容,方便開發(fā)過程中查看代碼執(zhí)行情況以及一些變量值這段代碼不需要修改,引入到 usart.h 即可。
    3. uart_init 函數(shù) ,這個(gè)很常見,也很重要,筆記中的串口通信和通信專欄都有詳細(xì)的講解。以下是 uart_init(u32 bound)的配置范例:
void uart_init(u32 bound){ 
 //GPIO 端口設(shè)置 
 GPIO_InitTypeDef GPIO_InitStructure; 
 USART_InitTypeDef USART_InitStructure; 
 NVIC_InitTypeDef NVIC_InitStructure; 
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA , ENABLE);  //使能 USART1,GPIOA 時(shí)鐘 
 //USART1_TX PA.9 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 復(fù)用推挽輸出 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出 
 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.0 發(fā)送端 
 
 //USART1_RX PA.10 浮空輸入 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入 
 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.10 接收端 
 
 //Usart1 NVIC 中斷配置 配置 
 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //對(duì)應(yīng)中斷通道 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí) 3 
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí) 3 
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 
  NVIC_Init(&NVIC_InitStructure); //中斷優(yōu)先級(jí)配置 
 
 //USART 初始化設(shè)置 
  USART_InitStructure.USART_BaudRate = bound;//波特率設(shè)置; 
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長(zhǎng)為 8 位 
  USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位 
  USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗(yàn)位 
   USART_InitStructure.USART_HardwareFlowControl= 
 USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制 
   USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;//收發(fā)模式 
  USART_Init(USART1, &USART_InitStructure); //初始化串口 
 
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟中斷 
  USART_Cmd(USART1, ENABLE); //使能串口 
} 
USART1_IRQHandler 函數(shù) 一共三個(gè):
 DCD USART1_IRQHandler ; USART1
 DCD USART2_IRQHandler ; USART2
 DCD USART3_IRQHandler ; USART3

void USART1_IRQHandler(void)函數(shù)是串口 1 的中斷響應(yīng)函數(shù),當(dāng)串口 1 發(fā)生了相應(yīng)的中斷后,就會(huì)跳到該函數(shù)執(zhí)行。中斷相應(yīng)函數(shù)的名字是不能隨便定義的,一般我們都遵循 MDK定義的函名。這些函數(shù)名字在啟動(dòng)文件 startup_stm32f10x_hd.s 文件中可以找到。

函數(shù)體里面通過函數(shù):

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 

判斷是否接受中斷,如果是串口接受中斷,則讀取串口接受到的數(shù)據(jù):

Res =USART_ReceiveData(USART1);//(USART1->DR); //讀取接收到的數(shù)據(jù) 

讀到數(shù)據(jù)后接下來就對(duì)數(shù)據(jù)進(jìn)行分析。

1、 PLLMUL

PLLMUL 用于設(shè)置 STM32 的 PLLCLK,STM32 支持 2~16 倍頻設(shè)置。我們常用的是 8M 外部晶振+9 倍頻設(shè)置,剛好得到 72Mhz 的 PLLCLK。從上圖可以看出,PLLMUL 的時(shí)鐘源,可以來自內(nèi)部 8M RC 振蕩/2 或者外部高速晶振(4~16Mhz)。這里切記 PLLMUL 設(shè)置后的頻率不要超過72Mhz(想超也是可以,最大 128M 也可以跑,不過一旦出問題 ST 是不負(fù)責(zé)的!)。

2、 SW

SW 是 STM32 的 SYSCLK(系統(tǒng)時(shí)鐘)切換開關(guān),從上圖可以看出,SYSCLK 的來源可以是3個(gè):HSI、PLLCLK 和HSE。我們一般選擇PLLCLK作為SYSCLK。SYSCLK最大為 72M。這里提示一下大家:STM32 剛上電的時(shí)候,用的是系統(tǒng)內(nèi)部 8M RC 時(shí)鐘,之后運(yùn)行程序才會(huì)把時(shí)鐘源設(shè)置為其他。

3、 系統(tǒng)滴答時(shí)鐘(SYSTICK)

SYSTICK 就是 CortexM3 的系統(tǒng)滴答時(shí)鐘,上圖清楚的表明 SYSTICK 的來源是AHB 分頻后再 8 分頻,因?yàn)槲覀円话阍O(shè)置 AHB 不分頻,所以 SYSTICK 的頻率就等于SYSCLK/8,如果 SYSCLK 為 72M,那么 SYSTICK 的頻率就是 9Mhz。前面介紹的延時(shí)函數(shù),就是基于 SYSTICK 來實(shí)現(xiàn)的。

4、 PCLK1

PCLK1 是 APB1 總線上外設(shè)的時(shí)鐘,最大為 36Mhz,所有掛載在 APB1 上的外設(shè),最大時(shí)鐘都是 36Mhz(定時(shí)器除外,原因見上圖),比如串口 2~5、SPI2 和 SPI3 等,在使用的時(shí)候,要特別留意。PCLK1 的時(shí)鐘可以通過 APB1 預(yù)分頻器設(shè)置,我們默認(rèn)一般設(shè)置為 2 分頻。

5、 PCLK2

PCLK2 是 APB2 總線上外設(shè)的時(shí)鐘,最大為 72Mhz,所有掛載在 APB2 上的外設(shè),最大時(shí)鐘都是 72Mhz,比如 GPIOA~G、串口 1、SPI1、ADC1~3 等。 PCLK2 的時(shí)鐘可以通過 APB2 預(yù)分頻器設(shè)置,我們默認(rèn)一般設(shè)置為 1,也就是不分頻。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
SN74LVC1G125DBVR 1 Texas Instruments Single 1.65-V to 5.5-V buffer with 3-state outputs 5-SOT-23 -40 to 125

ECAD模型

下載ECAD模型
$0.12 查看
NX3215SA-32.768KHZ-EXS00A-MU00525 1 Nihon Dempa Kogyo Co Ltd Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom,
暫無數(shù)據(jù) 查看
BGM113A256V21R 1 Silicon Laboratories Inc Telecom IC,

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜