裸機開發框架構建
- 3.設備管理層
- 抽象出結構體
- 初始化結構體
- 第一種初始化方法(c89標準)
- 第二種初始化方法(C99標準)
- 2.硬體介面層
- 1.硬體層
- 硬體LED層初始化函式
- 硬體層LED控制函式
- 4.應用層
- 整體源代碼(mdk4下除錯編譯通過,主控STM32F103RB)
- 硬體層
- 硬體介面層
- 設備管理層
- 應用層
- 源工程下載鏈接
接上一篇 (一)裸機開發框架構建之—開發框架思想
實際設計代碼,
總共分四層:硬體層—硬體介面層—設備管理層—應用層面
面向物件編程步驟:
3.設備管理層
1.首先對物件進行描述,有什么屬性,任務要求可以實作什么功能,
拿LED來說:使用需要初始化函式,可能有相同的多個設備,我們要準確控制哪一個設備的開關狀態,顏色??亮度??根據專案需求可以自己設計,寫法一般是把設備所有實作的功能抽象出一個結構體,實作函式啥的全部放到結構體里面,如下:
這里描述了設備名字,選擇哪一個LED,初始化函式,控制LED的開關函式,設定LED顏色,亮度等等,這里的引數為結構體指標的形式
抽象出結構體

初始化結構體
結構體的初始化看相同設備的數量,如果數量比較多的話就用結構體陣列,如果只是單個設備就用結構體變數,這里的初始化可以用兩種形式,第一種c89標準下,這里描述相同設備比較多,使用結構體陣列的形式
第一種初始化方法(c89標準)

第二種初始化方法(C99標準)
第二種c99以上標準,此種方法代碼可讀性更高(MDK下使用需要勾選C99標準)

這一層的函式還沒實作

實作如下:可以看到,呼叫了硬體介面層的函式

接下來就實作硬體介面層的函式
2.硬體介面層
這一層僅僅是對硬體層的函式進行封裝,比較簡單
可以看到,就是一層包裝而已,實作應用層和硬體層的分離

1.硬體層
這一層就是直接對硬體的操作,根據庫不同和板子不同會有不同的寫法,但是最終這個函式實作的,都將被硬體介面層封裝
硬體LED層初始化函式
int LED_Init(struct LEDDevice *ptLEDDevice)
{
static char ucLed=0;
GPIO_InitTypeDef GPIO_InitStruct;
if (!ptLEDDevice) /* 防御式編程:判斷為空指標 */
return -1;
switch (ptLEDDevice->which) /*選擇使能哪個LED*/
{
case LED1:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
break;
}
case LED2:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
break;
}
case LED3:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
break;
}
default:
return -1;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);/*鎖存器時鐘*/
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStruct); //資料引腳
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStruct); //鎖存引腳
GPIO_Write(GPIOC, ~ucLed <<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
return 0;
}
硬體層LED控制函式
int LEDControl(struct LEDDevice *ptLEDDevice, int iStatus)
{
BitAction pinstate;
if (!ptLEDDevice)
return -1;
pinstate = iStatus ? Bit_RESET : Bit_SET;
switch (ptLEDDevice->which)
{
case LED1:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_8,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);/*鎖存器引腳*/
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
case LED2:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_9,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
case LED3:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_10,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
default:
return -1;
}
return 0;
}
這里有三個設備,如何使用某一個LED設備,這里在設備管理層還寫了這么一個函式
定義一個指標函式,這里傳輸的引數是witch,通過輸入witch值確定哪一個陣列
PLEDDevice GetLEDDevice(int which)
{
if (which >= LED1 && which <= LED3)
return &g_tLEDDevices[which];
else
return NULL;
}
4.應用層
最后應用測驗代碼
void Led_test(void)
{
PLEDDevice PLED1 = GetLEDDevice(LED1);
PLEDDevice PLED2 = GetLEDDevice(LED2);
PLEDDevice PLED3 = GetLEDDevice(LED3);
PLED1->Init(PLED1);
PLED2->Init(PLED2);
PLED3->Init(PLED3);
PLED1->Control(PLED1, 0); /*打開設備*/
PLED2->Control(PLED2, 0);
PLED3->Control(PLED3, 0);
}
整體源代碼(mdk4下除錯編譯通過,主控STM32F103RB)
硬體層
led.c
#include "led.h"
/*硬體層LED函式的初始化,回傳值:-1失敗,0:成功*/
int LED_Init(struct LEDDevice *ptLEDDevice)
{
static char ucLed=0;
GPIO_InitTypeDef GPIO_InitStruct;
if (!ptLEDDevice) /* 防御式編程:判斷為空指標 */
return -1;
switch (ptLEDDevice->which) /*選擇使能哪個LED*/
{
case LED1:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
break;
}
case LED2:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
break;
}
case LED3:
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
break;
}
default:
return -1;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStruct); //資料引腳
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStruct); //鎖存引腳
GPIO_Write(GPIOC, ~ucLed <<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
return 0;
}
int LEDControl(struct LEDDevice *ptLEDDevice, int iStatus)
{
BitAction pinstate;
if (!ptLEDDevice)
return -1;
pinstate = iStatus ? Bit_RESET : Bit_SET;
switch (ptLEDDevice->which)
{
case LED1:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_8,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);/*鎖存器*/
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
case LED2:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_9,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
case LED3:
{
GPIO_WriteBit(GPIOC,GPIO_Pin_10,pinstate);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
break;
}
default:
return -1;
}
return 0;
}
led.h
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#include "bsp_interface_led.h"
#include "bsp_device_led.h"
int LEDControl(struct LEDDevice *ptLEDDevice, int iStatus);/*LED控制函式*/
int LED_Init(struct LEDDevice *ptLEDDevice);
#endif
硬體介面層
bsp_interface_led.c
#include "bsp_interface_led.h"
#include "bsp_device_led.h"
#include "led.h"
/*硬體介面層的LED初始化函式*/
int Interface_LEDInit(struct LEDDevice *ptLEDDevice)
{
/* 硬體層LED初始化函式 */
return LED_Init(ptLEDDevice);
}
/*硬體介面層的LED控制函式*/
int Interface_LEDControl(struct LEDDevice *ptLEDDevice, int iStatus)
{
/* 硬體層LED控制函式 */
return LEDControl(ptLEDDevice, iStatus);
}
bsp_interface_led.h
#ifndef __BSP_LED_INTERFACE_H
#define __BSP_LED_INTERFACE_H
#include "bsp_device_led.h"
int Interface_LEDInit(struct LEDDevice *ptLEDDevice);
int Interface_LEDControl(struct LEDDevice *ptLEDDevice, int iStatus);
#endif /* __BSP_LED_INTERFACE_H */
設備管理層
bsp_device_led.c
#include "bsp_device_led.h"
#include "bsp_interface_led.h"
/*設備管理層的LED初始化函式*/
int LEDDeviceInit(struct LEDDevice *ptLEDDevice)
{
/*硬體介面層的LED初始化函式*/
return Interface_LEDInit(ptLEDDevice);
}
/*設備管理層的LED控制函式*/
int LEDDeviceControl(struct LEDDevice *ptLEDDevice, int iStatus)
{
/*硬體介面層的LED控制函式*/
return Interface_LEDControl(ptLEDDevice,iStatus);
}
LEDDevice g_tLEDDevices[] = {
{"LED1",LED1, LEDDeviceInit, LEDDeviceControl},
{"LED2",LED2, LEDDeviceInit, LEDDeviceControl},
{"LED3",LED3, LEDDeviceInit, LEDDeviceControl},
};
/* C99標準可寫成以下形式
LEDDevice g_tLEDDevices[] = {
{.name="LED1",
.which=LED1,
.LEDDeviceInit=LEDDeviceInit,
.LEDDeviceControl=LEDDeviceControl},
{.name="LED2",
.which=LED2,
.LEDDeviceInit=LEDDeviceInit,
.LEDDeviceControl=LEDDeviceControl},
{.name="LED3",
.which=LED3,
.LEDDeviceInit=LEDDeviceInit,
.LEDDeviceControl=LEDDeviceControl},
};
*/
PLEDDevice GetLEDDevice(int which)
{
if (which >= LED1 && which <= LED3)
return &g_tLEDDevices[which];
else
return NULL;
}
bsp_device_led.c
#ifndef __BSP_LED_DEVICE_H
#define __BSP_LED_DEVICE_H
#ifndef NULL
#define NULL (void *)0
#endif
#define LED1 0
#define LED2 1
#define LED3 2
typedef struct LEDDevice {
/* 設備名字 */
char *name;
/*選擇哪個LED設備*/
int which; /*這里不用io組與io口的形式,內部函式判斷實作*/
/* 初始化LED設備 引數:LED1-LED3 */
int (*Init)(struct LEDDevice *ptLEDDevice);
/* 控制LED設備, iStatus取值: 1-亮,0-滅 */
int (*Control)(struct LEDDevice *ptLEDDevice, int iStatus);
/* 設定顏色(未實作) */
void (*SetColor)(struct LEDDevice *ptLEDDevice, int iColor);
/* 設定亮度(未實作) */
void (*SetBrightness)(struct LEDDevice *ptLEDDevice, int iBrightness);
}LEDDevice, *PLEDDevice;
PLEDDevice GetLEDDevice(int which);
#endif /* __BSP_LED_DEVICE_H */
應用層
void Led_test(void)
{
PLEDDevice PLED1 = GetLEDDevice(LED1);
PLEDDevice PLED2 = GetLEDDevice(LED2);
PLEDDevice PLED3 = GetLEDDevice(LED3);
PLED1->Init(PLED1);
PLED2->Init(PLED2);
PLED3->Init(PLED3);
PLED1->Control(PLED1, 1); /*打開設備*/
PLED2->Control(PLED2, 1);
PLED3->Control(PLED3, 1);
}
源工程下載鏈接
git地址:https://gitee.com/he-dejiang/framework.git
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/323390.html
標籤:其他
上一篇:計算機網路第二章物理層
