GPIO 入門之流水燈
開發前期準備
- 開發環境:Keil μVision4
- 奮鬥STM32開發板V5 STM32F103VET
- J-Link。資料夾,命名並儲存。
建立工程模組
新建工程
- 選擇公司和晶片型號(STM32F103VE)
- 彈出視窗:Copy STM32 startup code to project folder and add file to project? 選擇否。
- 工程新建成功,接下來需新增檔案。
- 在TEST資料夾中新建五個資料夾:USER、FWlib、 CMSIS、Output、Listing,其中USER已存在,不需再建。
USER用來存放工程檔案和使用者層程式碼,包括主函式main.c
FWlib用來存放STM32庫裡面的inc和src這兩個資料夾,包含了晶片上所有驅動,這兩個檔案下檔案不需修改。
- CMSISI用來存放庫為我們自帶的啟動檔案和一些位於CMSIS層的檔案。
- Output資料夾用來儲存軟體編譯後輸出的檔案。
- Listing用來儲存編譯後生成的連結檔案。
- 回到keil中,在工程中新建四個組(除listing),(Target->Add Group)和剛才四個資料夾名字對應。
- 配置MDK選項卡
流水燈例程
#include "stm32f10x.h"
/*
#include "led.h"
*/
#define ON 1
#define OFF 0
#define DELAY_TIME 0x0FFFEF
enum
{
LED1= 0,
LED2,
LED3,
MAX_LED,
};
typedef struct led_gpio_s
{
int num; /* LED編號 */
GPIO_TypeDef *group; /* LED使用的GPIO組別 */
uint16_t pin; /* LED使用的GPIO組中哪一個pin管腳:GPIO_Pin_x */
}led_gpio_t;
led_gpio_t leds_gpio[MAX_LED] =
{
{LED1,GPIOB,GPIO_Pin_5}, /* LED1 用的GPB5 */
{LED2,GPIOD,GPIO_Pin_6}, /* LED2 用的GPD6 */
{LED3,GPIOD,GPIO_Pin_3}, /* LED3 用的GPB3 */
};
void LED_GPIO_Config(void)
{
int i;
/* 定義一個GPIO_InitTypeDef型別的結構體 */
GPIO_InitTypeDef GPIO_InitStructure;
/* 開啟GPIOB GPIOD的外設時鐘 */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);
/*
for(i=0; i<MAX_LED; i++)
{
/* 選擇要控制的GPIO引腳 */
GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin;
/* 設定引腳模式為通用推輓輸出 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/* 設定引腳速率為50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* 呼叫庫函式,初始化GPIOB GPIOD */
GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure);
}
}
void turn_led(int which,int cmd)
{
if(which<0 || which> MAX_LED)
return;
if(OFF == cmd)
GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin);
else
GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin);
}
/*void Delay(__IO u32 nCount); 精確度不高的延時函式 */
int main(void)
{
/* 初始化系統時鐘 */
SystemInit();
/* 初始化LED埠 */
LED_GPIO_Config();
while(1);
{
/* 把LED1點亮,LED2和LED3滅掉 */
turn_led(LED1, ON);
turn_led(LED2, OFF);
turn_led(LED3, OFF);
Delay(DELAY_TIME);
/* 把LED2點亮,LED1和LED3滅掉 */
turn_led(LED2, ON);
turn_led(LED1, OFF);
turn_led(LED3, OFF);
Delay(DELAY_TIME);
/* 把LED3點亮,LED1和LED2滅掉 */
turn_led(LED3, ON);
turn_led(LED2, OFF);
turn_led(LED1, OFF);
Delay(DELAY_TIME);
}
}
void Delay(__IO u32 nCount) /* 精確度不高的延時函式 */
{
for(; nCount !=0; nCount--);
}
遇到問題
Build target ‘stm32_led’
compiling main.c…
main.c(48): warning: #9-D: nested comment is not allowed
main.c(60): error: #169: expected a declaration
main.c(100): warning: #12-D: parsing restarts here after previous syntax error
main.c(101): error: #40: expected an identifier
main.c(101): warning: #77-D: this declaration has no storage class or type specifier
main.c(101): error: #92: identifier-list parameters may only be used in a function definition
main.c(102): error: #40: expected an identifier
main.c(102): warning: #77-D: this declaration has no storage class or type specifier
main.c(102): error: #92: identifier-list parameters may only be used in a function definition
main.c(103): error: #79: expected a type specifier
main.c(103): warning: #77-D: this declaration has no storage class or type specifier
main.c(104): error: #169: expected a declaration
main.c(111): warning: #1-D: last line of file ends without a newline
main.c(111): warning: At end of source: #12-D: parsing restarts here after previous syntax error
Target not created
字型大小調不了、程式碼行號無法顯示
以上問題尚未解決
已解決問題:
原因:
在硬體除錯時添加了兩次STM32F 10xHigh-density Flash。導致演算法地址重疊。
解決方法:
將其中一個remove。