經過一番掙紮,還是決定使用官方的固件庫了。。
從網上下一個STM8S的固件庫,記得是FOR IAR的。
找到裡面的IAR模闆就可以開始用了。
這些都是直接寫好的庫函數,可以直接調用,但首先得先讀懂,先了解些必備知識。
STM8的寄存器的位址
在STM8中,與某個外圍裝置有關的寄存器在位址上都是順序排列的;比如與GPIO有關的寄存器有ODR、IDR、DDR、CR1、CR2,與PA口有關的這五個寄存器就被安排在了0x00 5000~0x00 5004這5個位址空間中,它們有一個0x005000的基位址,分别偏移0,1,2,3,4。
”stm8s.h"中與GPIO有關的定義,以及固件庫中通路外圍裝置寄存器的方法
typedef struct GPIO_struct
{
vu8 ODR; /*!< Output Data Register */
vu8 IDR; /*!< Input Data Register */
vu8 DDR; /*!< Data Direction Register */
vu8 CR1; /*!< Configuration Register 1 */
vu8 CR2; /*!< Configuration Register 2 */
}
GPIO_TypeDef;
#define GPIOA_BaseAddress 0x5000
#define GPIOB_BaseAddress 0x5005
#define GPIOC_BaseAddress 0x500A
#define GPIOD_BaseAddress 0x500F
#define GPIOE_BaseAddress 0x5014
#define GPIOF_BaseAddress 0x5019
#define GPIOA ((GPIO_TypeDef *) GPIOA_BaseAddress)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BaseAddress)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BaseAddress)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BaseAddress)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)
在結構體GPIO_TypeDef中,ODR,IDR,DDR,CR1,CR2的偏移分别是0,1,2,3,4正好與STM8S208RB對這幾個安排一緻,當我們将0x5000這個位址轉換為指向GPIO_TypeDef的指針後,
我們就可以用類似GPIOA->ODR的方法通路寄存器了。
另外固件庫在函數的參數入口都有斷言,
判斷參數設定是否符合要求,友善調試程式。如果在調試時程式跑到void assert_failed(u8* file, u32 line){}。裡面去,可以看看是否是參數設定出現問題
先從對STM8的GPIO操作開始。
以前沒有過,隻用過51的。操作管腳,給1就是1給0就是0.雖然簡單但是功能不夠給力啊。。
先了解下GPIO吧:
General Purpose Input Output (通用輸入/輸出)簡稱為GPIO
STM8的每一個GPIO引腳都可以獨立的作為輸入/輸出IO引腳使用,
作為輸入IO引腳使用時,每一個IO引腳都可以作為外部中斷的觸發輸入端使用,輸入有上拉和懸浮,
輸出有模拟開漏和推挽模式。
DDR用于設定方向,ODR用于輸出,IDR用于輸入,CR1、CR2用于控制。
具體可參考資料手冊。
固件庫為我們提供了GPIO_Init這個函數,用于GPIO工作模式的初始化設定,它的原型為
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
第一個參數是上面提到的GPIOA這樣的指針,第二、三個參數都是枚舉型變量(本質就是一些常數),用來制定要初始化的引腳和工作模式,具體設定可在GPIO.h中找到。
typedef enum
GPIO_PIN_0 = ((u8)0x01), /*!< Pin 0 selected */
GPIO_PIN_1 = ((u8)0x02), /*!< Pin 1 selected */
GPIO_PIN_2 = ((u8)0x04), /*!< Pin 2 selected */
GPIO_PIN_3 = ((u8)0x08), /*!< Pin 3 selected */
GPIO_PIN_4 = ((u8)0x10), /*!< Pin 4 selected */
GPIO_PIN_5 = ((u8)0x20), /*!< Pin 5 selected */
GPIO_PIN_6 = ((u8)0x40), /*!< Pin 6 selected */
GPIO_PIN_7 = ((u8)0x80), /*!< Pin 7 selected */
GPIO_PIN_LNIB = ((u8)0x0F), /*!< Low nibble pins selected */
GPIO_PIN_HNIB = ((u8)0xF0), /*!< High nibble pins selected */
GPIO_PIN_ALL = ((u8)0xFF) /*!< All pins selected */
}GPIO_Pin_TypeDef;
我們可以如此使用這個函數:
#define LEDS_PORT (GPIOH)
#define LED1_PIN (GPIO_PIN_3)
#define LED2_PIN (GPIO_PIN_2)
#define LED3_PIN (GPIO_PIN_1)
#define LED4_PIN (GPIO_PIN_0)
#define BUTTON_PORT (GPIOC)
#define BUTTON_PIN (GPIO_PIN_0)
/* Initialize I/Os in Output Mode */
GPIO_Init(LEDS_PORT, (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN), GPIO_MODE_OUT_PP_LOW_FAST);
/* Initialize I/O in Input Mode with Interrupt */
GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_FL_IT);
GPIO的操作函數
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal); //寫端口,8個腳一起設定
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); // 将指定腳設定為高
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); // 講指定腳設定為低
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); // 指定腳取反
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx); // 讀引腳
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); // 讀端口,上次鎖存到ODR中的資料
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin); // 讀制定腳的狀态,高電平傳回非0,低傳回0
寫一個點亮LED的程式:
#include "stm8s.h"
#define LED_PORT (GPIOD)
#define LED3_PIN (GPIO_PIN_0)
#define BUTTON_PORT (GPIOD)
#define BUTTON_PIN (GPIO_PIN_7)
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void main(void)
{
/* Infinite loop */
GPIO_Init(LED_PORT, LED1_PIN,GPIO_MODE_OUT_PP_LOW_SLOW);
GPIO_WriteHigh(LED_PORT, LED1_PIN);
}
下載下傳測試,沒有問題。
from:http://www.eefocus.com/w7838207178/blog/11-11/235052_ff6b7.html