本文中,筆者將介紹使用嵌入式開發工具Keil uVision5,使用C語言,對微處理器STM32F103C8進行嵌入式開發。
開發使用C語言,首先需要新建一個C語言文件,將其設為主函數的入口,因此,將此文件命名為main.c
配置好軟硬件依賴環境后,在此文件中鍵入如下內容,嘗試編譯,如果能夠編譯成功說明環境配置成功。
stm32f10x.h庫的功能是提供對於stm32f10x系列開發板的所有功能的定義與實現,因此在頭文件中要加一句。
#include <stdio.h> #include <stm32f10x.h> int main(){ return 0; }
實驗1:讓小燈常亮
查閱STM32技術手冊,可知管腳A1-4是用於控制小燈的,然而,要操控管腳A1-4,我們要先使能GPIOA的時鍾信號
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
然后,我們定義一個GPIO結構體,用於操控小燈
GPIO_InitTypeDef GPIO_LED_INIT;
根據技術手冊,GPIO_InitStruct類型結構體有以下三個成員:
typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef;
分別代表控制哪個或哪些管腳,信號速率和工作狀態。
其中,工作狀態分為輸入和輸出,輸出狀態又分為(復用)開漏輸出,(復用)推挽輸出。
我們在此實驗中僅操控第1個led燈,因此只操控時鍾GPIOA控制下的管腳1,信號速率設置為2MHz,工作模式設置為推挽輸出。
GPIO_InitTypeDef GPIO_LED_INIT; GPIO_LED_INIT.GPIO_Pin=GPIO_Pin_1; GPIO_LED_INIT.GPIO_Speed=GPIO_Speed_2MHz; GPIO_LED_INIT.GPIO_Mode=GPIO_Mode_Out_PP;
然后我們根據以上設置初始化此結構體,並用GPIO的置位函數,令管腳輸出信息,從而讓小燈亮起。
GPIO_Init(GPIOA,&GPIO_LED_INIT);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
實驗2:讓四個小燈同時閃亮
想同時操控多個小燈,只需要將GPIO_Pin的參數按位或起來。
GPIO_Pin是一個無符號16位整數,實際上,它的每一位表示一個時鍾控制下16個管腳的開閉,0代表無信號,1代表有信號。
GPIO_Pin_x的宏定義,實際上也是一個16位整數,某一位為1,其他位為0
GPIO_LED_INIT.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
要讓小燈閃亮,其亮滅的時間就必須有一定延遲,人眼才能看出。在嵌入式開發中無法使用Sleep()函數,因為Sleep()函數依賴於操作系統的時鍾。
因此,要手寫一個函數阻塞開發板處理器的運行。
void Delay(int time){ for(int i=0;i<time;i++) for(int j=0;j<100000;j++); }
要讓小燈亮滅延遲時,調用此阻塞函數即可。
while(1){ GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); Delay(500); }
實驗3:流水燈
流水燈就是讓小燈依次亮起,稍微修改一下閃燈的程序即可。
while(1){ GPIO_SetBits(GPIOA,GPIO_Pin_1); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_1); GPIO_SetBits(GPIOA,GPIO_Pin_2); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_2); GPIO_SetBits(GPIOA,GPIO_Pin_3); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_3); GPIO_SetBits(GPIOA,GPIO_Pin_4); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_4); }
本實驗完整代碼:
#include <stdio.h> #include <stm32f10x.h> void Delay(int time){ for(int i=0;i<time;i++) for(int j=0;j<1000;j++); } void blingbling(){ while(1){ GPIO_SetBits(GPIOA,GPIO_Pin_1); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_1); GPIO_SetBits(GPIOA,GPIO_Pin_2); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_2); GPIO_SetBits(GPIOA,GPIO_Pin_3); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_3); GPIO_SetBits(GPIOA,GPIO_Pin_4); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_4); } } void hualahuala(){ while(1){ GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); Delay(500); GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); Delay(500); } } int main(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_LED_INIT; GPIO_LED_INIT.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; GPIO_LED_INIT.GPIO_Speed=GPIO_Speed_2MHz; GPIO_LED_INIT.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(GPIOA,&GPIO_LED_INIT); blingbling(); return 0; }