ST对STM8S系列都有提供固件库,而不同的版本自然存在一些不同,版本也一直从V1.0.0升级到目前的V1.1.1。
环境: FWLIB V1.0.1版本,采用STM8SF103
在使用GPIO库时,一个偶然发现stm8s_gpio.h中的宏定义是存在问题的。
代码定义如下:
******************************************************************************
* @file stm8s_gpio.h
* @brief This file contains all functions prototype and macros for the GPIO peripheral.
* @author STMicroelectronics - MCD Application Team
* @version V1.0.1
* @date 09/22/2008
******************************************************************************
/**
* @brief GPIO modes
*
* Bits definitions:
* - Bit 7: 0 = INPUT mode
* 1 = OUTPUT mode
* 1 = PULL-UP (input) or PUSH-PULL (output)
* - Bit 5: 0 = No external interrupt (input) or No slope control (output)
* 1 = External interrupt (input) or Slow control enabled (output)
* - Bit 4: 0 = Low level (output)
* 1 = High level (output push-pull) or HI-Z (output open-drain)
*/
typedef enum
{
GPIO_MODE_IN_FL_NO_IT = (u8)0b00000000, /*!< Input floating, no external interrupt */
GPIO_MODE_IN_PU_NO_IT = (u8)0b01000000, /*!< Input pull-up, no external interrupt */
GPIO_MODE_IN_FL_IT = (u8)0b00100000, /*!< Input floating, external interrupt */
GPIO_MODE_IN_PU_IT = (u8)0b01100000, /*!< Input pull-up, external interrupt */
GPIO_MODE_OUT_OD_LOW_FAST = (u8)0b10000000, /*!< Output open-drain, low level, no slope control */
GPIO_MODE_OUT_PP_LOW_FAST = (u8)0b11000000, /*!< Output push-pull, low level, no slope control */
GPIO_MODE_OUT_OD_LOW_SLOW = (u8)0b10100000, /*!< Output open-drain, low level, slow slope */
GPIO_MODE_OUT_PP_LOW_SLOW = (u8)0b11100000, /*!< Output push-pull, low level, slow slope */
GPIO_MODE_OUT_OD_HIZ_FAST = (u8)0b10010000, /*!< Output open-drain, high-impedance level, no slope control */
GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11010000, /*!< Output push-pull, high level, no slope control */
GPIO_MODE_OUT_OD_HIZ_SLOW = (u8)0b10110000, /*!< Output open-drain, high-impedance level, slow slope */
GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11110000 /*!< Output push-pull, high level, slow slope */
}GPIO_Mode_TypeDef;
我在main.c中是直接这样用的 GPIO_Init(GPIOC,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST); //将GPIOC所有IO口设置成推挽输出,10M速度。空闲IO口设置为输出低电平能降低不必要的功耗。
但是调试查看寄存器时发现 CR2寄存器全为0,不应该才对。手册上清晰的表明了为1为设置10M速度。
翻看stm8s_gpio.c中的GPIO_Init函数,有设置CR2寄存器,前提是根据GPIO_MODE掩码来进行判断,判断的根据就是 Bit 5。如下:
if ((((u8)(GPIO_Mode)) & (u8)0x20) != (u8)0x00) /* Interrupt or Slow slope */
{
GPIOx->CR2 |= GPIO_Pin;
} else /* No external interrupt or No slope control */
{
GPIOx->CR2 &= (u8)(~(GPIO_Pin));
}
继续查看固件库,对于V1.1.1来说不存在这个问题,如:
******************************************************************************
* @file stm8s_gpio.h
* @brief This file contains all functions prototype and macros for the GPIO peripheral.
* @author STMicroelectronics - MCD Application Team
* @version V1.1.1
* @date 06/05/2009
******************************************************************************
/**
* @brief GPIO modes
*
* Bits definitions:
* - Bit 7: 0 = INPUT mode
* 1 = OUTPUT mode
* 1 = PULL-UP (input) or PUSH-PULL (output)
* - Bit 5: 0 = No external interrupt (input) or No slope control (output)
* 1 = External interrupt (input) or Slow control enabled (output)
* - Bit 4: 0 = Low level (output)
* 1 = High level (output push-pull) or HI-Z (output open-drain)
*/
typedef enum
{
GPIO_MODE_IN_FL_NO_IT = (u8)0b00000000, /*!< Input floating, no external interrupt */
GPIO_MODE_IN_PU_NO_IT = (u8)0b01000000, /*!< Input pull-up, no external interrupt */
GPIO_MODE_IN_FL_IT = (u8)0b00100000, /*!< Input floating, external interrupt */
GPIO_MODE_IN_PU_IT = (u8)0b01100000, /*!< Input pull-up, external interrupt */
GPIO_MODE_OUT_OD_LOW_FAST = (u8)0b10100000, /*!< Output open-drain, low level, 10MHz */
GPIO_MODE_OUT_PP_LOW_FAST = (u8)0b11100000, /*!< Output push-pull, low level, 10MHz */
GPIO_MODE_OUT_OD_LOW_SLOW = (u8)0b10000000, /*!< Output open-drain, low level, 2MHz */
GPIO_MODE_OUT_PP_LOW_SLOW = (u8)0b11000000, /*!< Output push-pull, low level, 2MHz */
GPIO_MODE_OUT_OD_HIZ_FAST = (u8)0b10110000, /*!< Output open-drain, high-impedance level,10MHz */
GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11110000, /*!< Output push-pull, high level, 10MHz */
GPIO_MODE_OUT_OD_HIZ_SLOW = (u8)0b10010000, /*!< Output open-drain, high-impedance level, 2MHz */
GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11010000 /*!< Output push-pull, high level, 2MHz */
}GPIO_Mode_TypeDef;
同样是GPIO_MODE_OUT_PP_HIGH_FAST,前者定义为 0b11010000,而后者则是 0b11110000。
后来从发行日志里也了解到,ST已经更正了这个错误。
使用FWLIB V1.1.1替换FWLIB V1.0.1过程中,需要注意新版本中不存在 stm8s_macro.h,stm8s_map.h,取而代之的是stm8s.h,而且stm8s.h中外设宏配置也与旧版本不同。对于外设的编译判断旧版采用的是stm8s_conf.h文件,而新版则是根据芯片的型号。
旧版: 在stm8s_map.h中进行编译宏条件判断
#ifdef _ADC1
#define ADC1 ((ADC1_TypeDef *) ADC1_BaseAddress)
#endif
#ifdef _ADC2
#define ADC2 ((ADC2_TypeDef *) ADC2_BaseAddress)
#endif
#ifdef _ITC
#define ITC ((ITC_TypeDef *) ITC_BaseAddress)
#endif
#ifdef _CFG
#define CFG ((CFG_TypeDef *) CFG_BaseAddress)
#endif
.......
.......
新版: 在stm8s.h中进行宏条件判断
#if defined(STM8S105) || defined(STM8S103) || defined(STM8S903)
#define ADC1 ((ADC1_TypeDef *) ADC1_BaseAddress)
#endif /* (STM8S105) ||(STM8S103) || (STM8S903) */
#if defined(STM8S208) || defined(STM8S207)
#define ADC2 ((ADC2_TypeDef *) ADC2_BaseAddress)
#endif /* (STM8S208) ||(STM8S207) */
#define AWU ((AWU_TypeDef *) AWU_BaseAddress)
#define BEEP ((BEEP_TypeDef *) BEEP_BaseAddress)
#ifdef STM8S208
#define CAN ((CAN_TypeDef *) CAN_BaseAddress)
#endif /* (STM8S208) */
#define CLK ((CLK_TypeDef *) CLK_BaseAddress)
......
......
新版固件库无需使用stm8s_conf.h来配置外设,转而是使用芯片的型号即可。如果使用了USE_STDPERIPH_DRIVER宏,则仍然会包含stm8s_conf.h配置文件。STM8S103,编译过程中自然就能够将ADC1等外设编译进去。
还有要注意的就是,不存在的外设不要加入到项目中,这样会导致编译不过。
剔除了stm8s_adc2.c、stm8s_can.c、stm8s_tim3.c、stm8s_tim5.c、stm8s_tim6.c、stm8s_uart2.c、stm8s_uart3.c,这些外设对于STM8S103是不存在的。