久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5092|回復: 0
打印 上一主題 下一主題
收起左側

學習筆記-STM32 建立工程、流水燈、宏##鏈接符

[復制鏈接]
跳轉到指定樓層
樓主
ID:91350 發表于 2015-9-30 01:01 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這段時間加班加的厲害,今天很努力的睡覺。。。
復習這些之后,感覺怪怪的,不學吧,又覺得自己沒有系統的去學,學吧,又覺得重復著學舊知識有些浪費時間,蠻矛盾的心理。
抱著“學而時習之,不亦說乎”的心態繼續觀看視頻和實驗,竟然有新的發現,哈哈,正所謂 “溫故而知新,可以為師矣”,古人誠不欺我也。
最后花了一些時間研究宏的 ## 連接符。 有收獲。。。

---------------------------------------------------------------------------------
軟件:MDK V5.12  固件庫 3.5

1、新建文件夾名為 MyProject

2、在該文件夾內分別新建 USER、CORE、OBJ、STM3210x_FWLib

3、CORE 存放核心文件和啟動文件(不同容量需要不同的啟動文件)
        將 STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport
        中 core_cm3.h 、core_cm3.c 文件拷貝到此目錄
        將 startup_stm32f10x_hd.s(大容量啟動文件) 文件拷貝到此目錄
       
4、OBJ 存放編譯過程文件以及 hex 文件

5、STM32F10x_FWLib 存放 STM32 庫函數文件
        將 STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver
        中 inc、src 文件夾拷貝到此目錄
       
6、USER 用來存放工程文件、主函數文件 main.c、以及其他包括 system_stm32f10x.c 等
        將 STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x
        中 stm32f10x.h、system_stm32f10x.h、system_stm32f10x.c 拷貝到此目錄
        將 STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template
        中 stm32f10x_it.h、stm32f10x_it.c、stm32f10x_conf.h 拷貝到此目錄
        在此目錄中新建 main.c 文件
       
7、啟動 MDK -> Project -> 選中 MyProject\USER 文件夾 -> 工程名為 MyProject

8、彈出 Select Device for Target 'Target 1' 對話框,選擇 STMicroelectronics
        -> STM32F1 Series -> STM32F103 -> STM32F103ZE -> OK

9、右擊 Target 1 -> Mange Project Items -> Project Targets -> Target 1 修改為 MyProject
        -> Groups 里新建 USER、CORE、OBJ、STM3210x_FWLib 分組。
       
10、為每個分組添加相對應目錄里面的.c文件,注意 CORE 需要將 startup_stm32f10x_hd.s 加入。

11、點擊魔術棒工具,Output -> Select Folder for Objects -> 選擇為 OBJ 目錄,勾選 Create HEX File

12、魔術棒工具 -> C/C++ -> Preprocessor Symbols -> Define 寫入 STM32F10X_HD,USE_STDPERIPH_DRIVER
        因為 3.5 版本的庫函數在配置和選擇外設的時候是通過宏定義來選擇的,我們需要配置一個全局的宏定義
        變量。

13、魔術棒工具 -> C/C++ -> Include Paths 加入頭文件的目錄
        MDK,只會從這里定義的目錄去找頭文件,注意,它只會搜索一級目錄。
       
--------------------------------------------------------------------------------------------------------

基本的IO口操作;

一、初始化函數:
        void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct);
        功能:
                設置IO口為輸入或輸出模式、翻轉速度
        參數:
                GPIOx:IO組 GPIOA ~ GPIOG
                GPIO_InitStruct:
                        .GPIO_Pin:IO引腳、
                        .GPIO_Speed:翻轉速度 GPIO_Speed_10MHz、GPIO_Speed_2MHz、GPIO_Speed_50MHz
                        .GPIO_Mode:模擬輸入、浮空輸入、上下拉輸入、推挽輸出、開漏輸出、復用推挽、復用開漏
        返回值:
               
       
二、讀取函數
        1、讀取輸入電平函數(IO口被設置為輸入模式)
        uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);               
        功能:
                當IO口被設置為輸入模式時,讀取指定組指定IO電平狀態 讀取 IDR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:IO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
                0:為低電平
                1:為高電平
               
        uint16_t GPIO_ReadInputData(GPIO_TypeDef *GPIOx);
        功能:
                當IO口被設置為輸入模式時,讀取指定GPIO組的整組IO電平狀態 讀取 IDR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:IO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
                整組IO口的所有狀態集合為一個 16 位的整數,該整數每一位對應一個IO口的狀態

        2、讀取輸出電平函數(IO口被設置為輸出模式)
        uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
        功能:
                當IO口被設置為輸出模式時,讀取指定GPIO組指定IO電平狀態 讀取 ODR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:GPIO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
                0:為低電平
                1:為高電平
                uint16_t GPIO_ReadOutputData(GPIO_TypeDef *GPIOx);
        功能:
                當IO口被設置為輸出模式時,讀取指定GPIO組指定IO電平狀態 讀取 ODR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:GPIO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
                整組IO口的所有狀態集合為一個 16 位的整數,該整數每一位對應一個IO口的狀態
               
       
三、設置函數
        1、設指定IO口輸出高電平還是低電平
        void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
        功能:
                設置指定GPIO組指定IO口為高電平 操作 BSRR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:GPIO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
               
               
        void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
        功能:
                設置指定GPIO組指定IO口為低電平 操作 BRR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:IO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
        返回值:
               
               
        2、整體操作
        void GPIO_WriteBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
        功能:
                GPIO_SetBits()、GPIO_ResetBits() 的結合體,根據 BitVal 操作 BSRR 或 BRR 寄存器
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                GPIO_Pin:GPIO組中某個引腳 GPIO_Pin_0 ~ GPIO_Pin_15
                BitVal:Bit_RESET 設置為低電平   Bit_SET 設置為高電平
        返回值:
               
               
        void GPIO_Write(GPIO_TypeDef *GPIOx, uint16_t PortVal);
        功能:
                設置指定GPIO組整組IO電平狀態 操作 ODR 寄存器,在設置輸出模式時 ODR 寄存器決定輸入上拉還是下拉
        參數:
                GPIOx:GPIO組 GPIOA ~ GPIOG
                PortVal:16 位整數,每一位對應一個IO口的狀態
        返回值:
                               


四、GPIO 時鐘
        void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
        功能:
                設置掛載在APB2總線上的設備時鐘,GPIOA ~ GPIOG 就是掛載到 APB2 中
        參數:
                RCC_APB2Periph:選擇外設
                NewState:ENABLE 使能、DISABLE 關閉
        返回值:
               

五、遇到的問題
        1、在編寫流水燈的時候,我是先初始化GPIO,再開啟IO時鐘。發現無法點亮LED燈。
                注意,必須先開啟時鐘,再初始化IO
               
        2、想利用宏連接 ## 符號來提高代碼可移植性, 這里花的時間比較長。
                有如下宏定義:
                #define LED1_GPIO       GPIOB
                #define __ToRCC(GPIO)   RCC_APB2Periph_##GPIO
                #define ToRCC(GPIO)   __ToRCC(GPIO)
               
                使用方式:
                ToRCC(LED1_GPIO)
                原以為會擴展為:RCC_APB2Periph_GPIOB 但實際上是 RCC_APB2Periph_
                只知道是因為 GPIOB 自身也是一個宏導致這種現象,至于為什么過程中會丟失就不清楚了。
               
                目前的解決方式是再套一個宏,感覺這種方式比較麻煩,不知道還有沒有更好的方法。
                #define LED1_GPIO       B
                #define __GPIOToRCC(GPIO)   RCC_APB2Periph_GPIO##GPIO
                #define GPIOToRCC(GPIO)   __GPIOToRCC(GPIO)
               
                使用方式:
                GPIOToRCC(LED1_GPIO) 此時可以正確擴展為 RCC_APB2Periph_GPIOB
               

六、源文件
---------------------------------------------------------------------------
public.h
---------------------------------------------------------------------------

#include "stm32f10x.h"


// 比較有意思的宏定義 ------------------------------------------------------------


#define __TORCC(group)      RCC_APB2Periph_GPIO##group
#define TORCC(group)        __TORCC(group)


#define __TOGPIO(group)     GPIO##group
#define TOGPIO(group)       __TOGPIO(group)


#define __TOPIN(pin)        GPIO_Pin_##pin
#define TOPIN(pin)          __TOPIN(pin)


// 比較有意思的宏定義 ------------------------------------------------------------

---------------------------------------------------------------------------
led.h
---------------------------------------------------------------------------
#ifndef __LED_H
#define __LED_H

enum en_LED_NUMBER
{
    LED_NUMBER_1,
    LED_NUMBER_2,
    LED_NUMBER_3
};

void LED_Init(void);
char LED_On(enum en_LED_NUMBER number);
char LED_Off(enum en_LED_NUMBER number);
char LED_On_Mutex(enum en_LED_NUMBER number);
char LED_Off_Mutex(enum en_LED_NUMBER number);
void LED_On_ALL(void);
void LED_Off_ALL(void);

#endif

---------------------------------------------------------------------------
led.h
---------------------------------------------------------------------------
#include "public.h"

#include "led.h"

// 移植部分 ------------------------------------------------------------

#define LED1_GPIO       B
#define LED1_GPIO_Pin   0

#define LED2_GPIO       F
#define LED2_GPIO_Pin   7

#define LED3_GPIO       F
#define LED3_GPIO_Pin   8

#define LEDON(GPIOx, GPIO_Pin)  GPIO_ResetBits(GPIOx, GPIO_Pin)
#define LEDOFF(GPIOx, GPIO_Pin)  GPIO_SetBits(GPIOx, GPIO_Pin)

// 移植部分 ------------------------------------------------------------

/* 點亮指定 LED 燈 */
char LED_On(enum en_LED_NUMBER number)
{
    switch((int)number)
    {
        case LED_NUMBER_1:
            LEDON(TOGPIO(LED1_GPIO), TOPIN(LED1_GPIO_Pin));
            break;
        case LED_NUMBER_2:
            LEDON(TOGPIO(LED2_GPIO), TOPIN(LED2_GPIO_Pin));
            break;
        case LED_NUMBER_3:
            LEDON(TOGPIO(LED3_GPIO), TOPIN(LED3_GPIO_Pin));
            break;
        default:
            return 1;
    }
   
    return 0;
}

/* 熄滅指定 LED 燈 */
char LED_Off(enum en_LED_NUMBER number)
{
    switch((int)number)
    {
        case LED_NUMBER_1:
            LEDOFF(TOGPIO(LED1_GPIO), TOPIN(LED1_GPIO_Pin));
            break;
        case LED_NUMBER_2:
            LEDOFF(TOGPIO(LED2_GPIO), TOPIN(LED2_GPIO_Pin));
            break;
        case LED_NUMBER_3:
            LEDOFF(TOGPIO(LED3_GPIO), TOPIN(LED3_GPIO_Pin));
            break;
        default:
            return 1;
    }
   
    return 0;
}

/* 只允許其中一個 LED 亮 ,其余皆滅 */
char LED_On_Mutex(enum en_LED_NUMBER number)
{
    switch((int)number)
    {
        case LED_NUMBER_1:
            LED_On(LED_NUMBER_1);
            LED_Off(LED_NUMBER_2);
            LED_Off(LED_NUMBER_3);
            break;
        
        case LED_NUMBER_2:
            LED_Off(LED_NUMBER_1);
            LED_On(LED_NUMBER_2);
            LED_Off(LED_NUMBER_3);
            break;
        
        case LED_NUMBER_3:
            LED_Off(LED_NUMBER_1);
            LED_Off(LED_NUMBER_2);
            LED_On(LED_NUMBER_3);
            break;
        
        default:
            return 1;
    }
   
    return 0;
}

/* 只允許其中一個 LED 滅 ,其余皆亮 */
char LED_Off_Mutex(enum en_LED_NUMBER number)
{
    switch((int)number)
    {
        case LED_NUMBER_1:
            LED_Off(LED_NUMBER_1);
            LED_On(LED_NUMBER_2);
            LED_On(LED_NUMBER_3);
            break;
        
        case LED_NUMBER_2:
            LED_On(LED_NUMBER_1);
            LED_Off(LED_NUMBER_2);
            LED_On(LED_NUMBER_3);
            break;
        
        case LED_NUMBER_3:
            LED_On(LED_NUMBER_1);
            LED_On(LED_NUMBER_2);
            LED_Off(LED_NUMBER_3);
            break;
        
        default:
            return 1;
    }
   
    return 0;
}

void LED_On_ALL(void)
{
    LED_On(LED_NUMBER_1);
    LED_On(LED_NUMBER_2);
    LED_On(LED_NUMBER_3);
    return ;
}

void LED_Off_ALL(void)
{
    LED_Off(LED_NUMBER_1);
    LED_Off(LED_NUMBER_2);
    LED_Off(LED_NUMBER_3);
    return ;
}

/* 初始化 LED */
void LED_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
   
    // 初始化IO時鐘
    RCC_APB2PeriphClockCmd(TORCC(LED1_GPIO), ENABLE);
    RCC_APB2PeriphClockCmd(TORCC(LED2_GPIO), ENABLE);
    RCC_APB2PeriphClockCmd(TORCC(LED3_GPIO), ENABLE);
   
    // 初始化 GPIO
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   
    GPIO_InitStructure.GPIO_Pin = TOPIN(LED1_GPIO_Pin);   
    GPIO_Init(TOGPIO(LED1_GPIO), &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = TOPIN(LED2_GPIO_Pin);
    GPIO_Init(TOGPIO(LED2_GPIO), &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = TOPIN(LED3_GPIO_Pin);
    GPIO_Init(TOGPIO(LED3_GPIO), &GPIO_InitStructure);
       
    LED_Off_ALL();
}



---------------------------------------------------------------------------
main.c
---------------------------------------------------------------------------
#include "public.h"

#include "delay.h"
#include "led.h"


int main(void)
{
    delay_init();

    LED_Init();

    while(1)
    {
        delay_ms(500);
        LED_On_Mutex(LED_NUMBER_1);
        delay_ms(500);
        LED_On_Mutex(LED_NUMBER_2);
        delay_ms(500);
        LED_On_Mutex(LED_NUMBER_3);
    }

}
---------------------------------------------------------------------------


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品久久久久久久久久 | 精品成人一区二区 | 久色视频在线观看 | 亚洲一区二区视频在线播放 | 久久久久亚洲精品 | 在线观看日韩 | 国产激情视频在线观看 | 日韩av在线一区 | 我想看一级黄色毛片 | 久久久久久久久精 | 日韩久久中文字幕 | 午夜成人免费视频 | 欧美精品一区二区三区在线 | 欧美久久精品一级c片 | 九九九久久国产免费 | 在线成人av | 范冰冰一级做a爰片久久毛片 | 日一区二区 | 日韩精品在线一区 | 国产精品视频在线播放 | 国产九九九九 | wwwww在线观看 | 99精彩视频| 高清欧美性猛交xxxx黑人猛交 | 二区欧美| 黄色在线免费观看视频网站 | 国产成人精品一区二 | 亚洲精品一区二区三区在线 | 欧美日日日日bbbbb视频 | 国产高清免费视频 | 91麻豆精品国产91久久久更新资源速度超快 | 国产精品永久免费 | 青青久在线视频 | 在线观看黄色电影 | 亚洲综合在线播放 | 免费在线观看av片 | 激情婷婷成人 | 国产精品美女久久久久aⅴ国产馆 | 午夜视频在线观看网址 | 免费一区二区 | 欧美一区免费 |