stm32F1硬件資源
時間:2024-05-06 來源:華清遠見
一. stm32F1硬件資源
STMicroelectronics的STM32F1系列是一系列廣受歡迎的32位ARM Cortex-M微控制器(MCU)。這些單片機被廣泛應用于嵌入式系統,因為它們具有高性能、低功耗、豐富的外設和豐富的開發工具生態系統。
1. 系統構架
主系統由以下部分構成:
● 四個驅動單元:
─ Cortex™-M3 內核 DCode 總線(D-bus),和系統總線(S-bus)
─ 通用 DMA1 和通用 DMA2
● 四個被動單元
─ 內部 SRAM
─ 內部閃存存儲器
─ FSMC
─ AHB 到 APB 的橋(AHB2APBx),它連接所有的 APB 設備
這些都是通過一個多級的AHB總線構架相互連接的,如圖所示:

具體參數為:
64或128 kb的Flash
20 KB的SRAM
嵌套矢量中斷控制器(NVIC)
外部中斷/事件控制器(EXTI)
時鐘和啟動
DMA
RTC(實時時鐘)和備份寄存器
4個定時器和看門狗
2個I2C總線接口
通用同步/異步接收/發送(USART)
SPI接口
GPIO(通用輸入/輸出)
2個12位ADC
二. 基礎設備開發重點
1.通用輸入/輸出(GPIO):
特點:GPIO引腳可以配置為輸入或輸出,用于連接和控制外部設備。
應用:用于連接傳感器、LED、按鈕和其他外部設備,實現輸入和輸出控制。
2. 專用控制器(TIM、ADC、RTC)
1)定時器:
特點:STM32單片機通常配備了多個定時器,包括通用定時器、高級定時器和基本定時器。這些定時器可用于生成定時、測量脈沖寬度、PWM控制等。
應用:用于控制電機速度、測量時間間隔、產生PWM信號等。
通用定時器是一個通過可編程預分頻器驅動的16位自動裝載計數器構成。
主要功能:
通用TIMx (TIM2、TIM3、TIM4和TIM5)定時器功能包括:
● 16位向上、向下、向上/向下自動裝載計數器
● 16位可編程(可以實時修改)預分頻器,計數器時鐘頻率的分頻系數為1~65535之間的任意數值
● 4個獨立通道:
─ 輸入捕獲
─ 輸出比較
─ PWM 生成(邊緣或中間對齊模式)
─ 單脈沖模式輸出
● 使用外部信號控制定時器和定時器互連的同步電路
● 如下事件發生時產生中斷/DMA:
─ 更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
─ 觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
─ 輸入捕獲
─ 輸出比較
─ 支持針對定位的增量(正交)編碼器和霍爾傳感器電路
─ 觸發輸入作為外部時鐘或者按周期的電流管理
2) 串行通信接口UART
a.介紹
通用同步異步收發器(USART)提供了一種靈活的方法與使用工業標準NRZ異步串行數據格式的外部設備之間進行全雙工數據交換。USART利用分數波特率發生器提供寬范圍的波特率選擇。
它支持同步單向通信和半雙工單線通信,也支持LIN(局部互連網),智能卡協議和IrDA(紅外數據組織)SIR ENDEC規范,以及調制解調器(CTS/RTS)操作。它還允許多處理器通信。
使用多緩沖器配置的DMA方式,可以實現高速數據通信。
b. USART功能描述
任何USART雙向通信至少需要兩個腳:接收數據輸入(RX)和發送數據輸出(TX)。
RX:接收數據串行輸。通過過采樣技術來區別數據和噪音,從而恢復數據。
TX:發送數據輸出。當發送器被禁止時,輸出引腳恢復到它的I/O端口配置。當發送器被激活,并且不發送數據時,TX引腳處于高電平。
● 總線在發送或接收前應處于空閑狀態
● 一個起始位
● 一個數據字(8或9位),最低有效位在前
● 0.5,1.5,2個的停止位,由此表明數據幀的結束
● 使用分數波特率發生器 —— 12位整數和4位小數的表示方法。
● 一個狀態寄存器(USART_SR)
● 數據寄存器(USART_DR)
● 一個波特率寄存器(USART_BRR),12位的整數和4位小數
UART示例:
void Init_Uart(void)
{
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
}
void uart_send_byte(char ch)
{
USART_SendData(USART1,ch);
while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
}
char uart_recv_byte(void)
{
char ch;
while(RESET == USART_GetFlagStatus(USART1,USART_FLAG_RXNE));
ch = USART_ReceiveData(USART1);
return ch;
}
void uart_send_string(char *str)
{
while(*str)
{
uart_send_byte(*str);
str++;
}
}
int fputc(int ch, FILE *fp)
{
USART_SendData(USART1,ch);
while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
}
3)模數轉換器(ADC):
特點:ADC允許將模擬信號轉換為數字值,用于測量傳感器數據等。
● 12-位分辨率
● 轉換結束,注入轉換結束和發生模擬看門狗事件時產生中斷
● 單次和連續轉換模式
● 從通道0到通道n的自動掃描模式
● 自校準
● 帶內嵌數據一致的數據對齊
● 通道之間采樣間隔可編程
● 規則轉換和注入轉換均有外部觸發選項
應用:用于測量溫度、濕度、光線等模擬信號,廣泛應用于傳感器接口。
示例:
void Init_ADC(ADC_TypeDef* ADCx)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_DeInit(ADCx);
//ADC1 和 ADC2 工作在獨立模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
//模數轉換工作在掃描模式(多通道)還是單次(單通道)模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
//模數轉換工作在連續還是單次模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
//轉換由軟件而不是外部觸發啟動
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
// ADC 數據向左邊對齊還是向右邊對齊
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//順序進行規則轉換的 ADC 通道的數目
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADCx, &ADC_InitStructure);
ADC_Cmd(ADCx, ENABLE);//使能ADC
//設置指定 ADC 的規則組通道,設置它們的轉化順序和采樣時間 ADC_RegularChannelConfig(ADCx,ADC_Channel_1,1,ADC_SampleTime_55Cycles5);
ADC_ResetCalibration(ADC1); //使能復位校準
//等待復位校準結束
while(RESET == ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADCx);//開始校準
while(RESET == ADC_GetCalibrationStatus(ADCx));//等待校準完成
//使能或者失能 ADCx 軟件啟動注入組轉換功能
ADC_SoftwareStartConvCmd(ADCx,ENABLE);
}
4)PWM控制器:
特點:PWM(脈沖寬度調制)控制器用于生成PWM信號,可用于控制電機速度、LED亮度等。
應用:用于電機控制、LED燈控制、音頻處理等。
示例:
void Init_TIM3(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//TIM3的基本配置
TIM_BaseInitStructure.TIM_Prescaler = 720;//預分頻
TIM_BaseInitStructure.TIM_Period = 2000;//ARR 計數周期
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數
TIM_BaseInitStructure.TIM_Clockpision = TIM_CKD_p1;
TIM_TimeBaseInit(TIM3, &TIM_BaseInitStructure);//初始化TIM3
//配置TIM3的通道1輸出PWM脈沖
//TIM 脈沖寬度調制模式 1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//Specifies the TIM Output Compare state
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0;//設置裝入捕獲比較寄存器的脈沖值 CCR
//TIM 輸出比較極性:高 即周期內低于TIM_Pulse這個閾值的時間,都是高 //電平,其他時間都是低;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3,&TIM_OCInitStructure);//初始化TIM3的Channel1
TIM_OC2Init(TIM3,&TIM_OCInitStructure);//初始化TIM3的Channel2
TIM_OC3Init(TIM3,&TIM_OCInitStructure);//初始化TIM3的Channel3
TIM_OC4Init(TIM3,&TIM_OCInitStructure);//初始化TIM3的Channel4
//Enables or disables the TIMx peripheral Preload register on CCRx.
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
//Enables or disables TIMx peripheral Preload register on ARR.
TIM_ARRPreloadConfig(TIM3,ENABLE);
// Enables or disables the TIM peripheral Main Outputs.
TIM_CtrlPWMOutputs(TIM3,ENABLE);
TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
3.時鐘配置
三種不同的時鐘源可被用來驅動系統時鐘(SYSCLK):
● HSI振蕩器時鐘
● HSE振蕩器時鐘
● PLL時鐘
這些設備有以下2種二級時鐘源:
● 40kHz低速內部RC,可以用于驅動獨立看門狗和通過程序選擇驅動RTC。RTC用于從停機/待機模式下自動喚醒系統。
● 32.768kHz低速外部晶體也可用來通過程序選擇驅動RTC(RTCCLK)。
當不被使用時,任一個時鐘源都可被獨立地啟動或關閉,由此優化系統功耗。時鐘樹

4.通信時序(UART、I2C、SPI)
1)串口時序
串口通信通常需要配置參數(波特率、數據位、起始位、停止位、奇偶校驗位)

2)I2C時序
開始(S)和結束(P)標志:
開始信號:處理器讓SCL時鐘保持高電平,然后讓SDA數據信號由高變低就表示一個開始信號。同時IIC總線上的設備檢測到這個開始信號它就知道處理器要發送數據了。
停止信號:處理器讓SCL時鐘保持高電平,然后讓SDA數據信號由低變高就表示一個停止信號。同時IIC總線上的設備檢測到這個停止信號它就知道處理器已經結束了數據傳輸,我們就可以各忙各個的了,如休眠等。

通信:
開始標志(S)發出后,主設備會傳送一個7 位的Slave 地址,并且后面跟著一個第8位,稱為Read/Write 位。R/W 位表示主設備是在接受從設備的數據還是在向其寫數據。然后,主設備釋放SDA 線,等待從設備的應答信號(ACK)。每個字節的傳輸都要跟隨有一個應答位。應答產生時(既把SDA拉低),從設備將SDA 線拉低并且在SCL 為高電平時保持低。數據傳輸總是以停止標志(P)結束,然后釋放通信線路。然而,主設備也可以產生重復的開始信號去操作另一臺從設備,而不發出結束標志。綜上可知,所有的SDA 信號變化都要在SCL 時鐘為低電平時進行,除了開始和結束標志。
(3)SPI時序
SPI_CR寄存器的CPOL和CPHA位,能夠組合成四種可能的時序關系。CPOL(時鐘極性)位控制在沒有數據傳輸時時鐘的空閑狀態電平,此位對主模式和從模式下的設備都有效。如果CPOL被清’0’,SCK引腳在空閑狀態保持低電平;如果CPOL被置’1’,SCK引腳在空閑狀態保持高電平。
如果CPHA(時鐘相位)位被置’1’,SCK時鐘的第二個邊沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)進行數據位的采樣,數據在第二個時鐘邊沿被鎖存。如果CPHA位被清’0’,SCK時鐘的第一邊沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)進行數據位采樣,數據在第一個時鐘邊沿被鎖存。
CPOL時鐘極性和CPHA時鐘相位的組合選擇數據捕捉的時鐘邊沿。
圖208顯示了SPI傳輸的4種CPHA和CPOL位組合。此圖可以解釋為主設備和從設備的SCK腳、MISO腳、MOSI腳直接連接的主或從時序圖。
注意:
1. 在改變 CPOL/CPHA 位之前,必須清除 SPE 位將 SPI 禁止。
2. 主和從必須配置成相同的時序模式。
3. SCK 的空閑狀態必須和 SPI_CR1 寄存器指定的極性一致 (CPOL 為 1 時,空閑時應上拉 SCK 為高電平; CPOL 為 0 時,空閑時應下拉 SCK 為低電平 ) 。
4. 數據幀格式 (8 位或 16 位 ) 由 SPI_CR1 寄存器的 DFF 位選擇,并且決定發送 / 接收的數據長度。

5.中斷開發
STM32F103xx性能線嵌入了一個嵌套的矢量中斷控制器,能夠處理多達43個可屏蔽中斷通道(不包括Cortex-M3的16個中斷線)和16個優先級級別。
1)常見中斷類型:
EXTI中斷:主要由外設觸發的中斷
ADC中斷:主要由ADC觸發的中斷
TIM中斷:主要由定時器觸發的中斷
USART中斷:主要由串口觸發的中斷
DMA全局中斷:主要由DMA觸發的中斷
2)TIM2中斷為例
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Init_TIM2(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_Period = 1000-1;
TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;
TIM_TimeBaseInitStructure.TIM_Clockpision = TIM_CKD_p1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(void)
{
//中斷處理
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清中斷標志
}
三. 開發方式介紹
1.標準庫開發
1)開發環境搭建
a.下載安裝keil MDK-ARM集成開發環境
b.導入芯片支持包
c.創建新項目
選擇合適的設備型號
選擇外設驅動
d.編程
2)點燈示例
void Init_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void led_on(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_5); //點亮LED
}
void led_off(void)
{
GPIO_ResetBits (GPIOA,GPIO_Pin_5); //熄滅LED
}
2.stm32CubeMx工具開發
1)開發環境搭建
a.官網下載JRE和stm32CubeMx并安裝
b.stm32CubeMx庫安裝
c.創建工程
d.生成keil工程并添加自己的功能代碼
2)點燈示例


