stm8学习笔记

2020-06-05 10:35

所用芯片 stm8s105s4 开发环境:ST Visual Develop Stm8s的库为V1.1.1

CPU频率及所有外设频率/时钟

系统复位后,所有外设时钟均处于开的状态。用户可通过清除CLK_PCKENR1或CLK_PCKENR2中的PCKEN位来关闭相应的外设时钟。但是在关闭外设的时钟前,用户必须设置相应的位禁用该外设。

为了使能一个外设,用户必须先设置寄存器CLK_PCKENR中对应的PCKEN位,然后设置外设控制寄存器中的外设使能位。

AWU计数器是由独立于fMASTER的内部或外部时钟(LSI或HSE)驱动,因此,即使寄存器的时钟已被关掉,该外设依然可以继续运行。 例如禁用所有外设时钟:

CLK_PCKENR1 = 0x00;// close all clks of Peripheral CLK_PCKENR2 = 0x00;

开启定时器TIME1定时器时钟:

CLK_PCKENR1 |= 0x20; //具体参考STM8S_Reference 59页

CPU分频因子:CPU时钟(fCPU)由主时钟(fMASTER)分频而来,分频因子由时钟分频寄存器(CLK_CKDIVR)中的位CPUDIV[2:0]决定。共7个分频因子可供选择(1至128中,2的幂)。如图13所示。 fCPU为CPU和窗口看门狗提供时钟。 时钟分频寄存器(CLK_CKDIVR) 通用端口GPIO

和其他的单片机一样,我是习惯从端口开始学习。Stm8s105s系列最多有7组I/O端口,A~G,而根据不同的封装可能没有其中的一些,在这里根据具体项目,我选择的是44脚封装的。使用任何的外设前,我们都要根据需要的将参考手册和数据手册看一边,当然端口也不能另外了。 作为通用的IO口,每一个GPIO端口都有5个对应的寄存器如下表: 注意:初始复位时,所有引脚设置为浮空输入。 地址偏移寄存器 值 7 6 5 4 3 2 1 0 0x00 Px_ODR 复位值 ODR7 0 IDR7 0 DDR7 0 C17 0 C27 0 ODR6 0 IDR6 0 DDR6 0 C16 0 C26 0 ODR5 0 IDR5 0 DDR5 0 C15 0 C25 0 ODR4 0 IDR4 0 DDR4 0 C14 0 C24 0 ODR3 0 IDR3 0 DDR3 0 C13 0 C23 0 ODR2 0 IDR2 0 DDR2 0 C12 0 C22 0 ODR1 0 IDR1 0 DDR1 0 C11 0 C21 0 ODR0 0 IDR0 0 DDR0 0 C10 0 C20 0 0x01 Px_IDR 复位值 0x02 Px_DDR 复位值 0x03 Px_CR1 复位值 0x04 Px_CR2 复位值 其中

1. Px_ODR是ODR[7:0]:端口输出数据寄存器位; (1)在输出模式下,写入寄存器的数值通过锁存器加到相应的引脚上。读ODR寄存器,返回之前锁存的寄存器值。 (2)在输入模式下,写入ODR的值将被锁存到寄存器中,但不会改变引脚状态。ODR寄存器在复位后总是为0。位操作指令(BSET, BRST) 可以用来设置DR寄存器来驱动相应的引脚,但不会影响到其他引脚。 2. Px_IDR: IDR[7:0]:端口输入数据寄存器位

不论引脚是输入还是输出模式,都可以通过该寄存器读入引脚状态值。该寄存器为只读寄存器。 0:逻辑低电平 1:逻辑高电平

3. Px_DDR: DDR[7:0]:数据方向寄存器位 ,这些位可通过软件置1或置0,选择引脚输入或输出 0: 输入模式 1: 输出模式

4. Px_CR1: C1[7:0]控制寄存器位

这些位可通过软件置1或置0,用来在输入或输出模式下选择不同的功能。在 输入模式时(DDR=0): 0:浮空输入 1::带上拉电阻输入

在 输出模式时(DDR=1): 0:模拟开漏输出(不是真正的开漏输出) 1: 推挽输出, 由CR2相应的位做输出摆率控制

5. Px_CR2: C2[7:0]控制寄存器位 相应的位通过软件置1或置0,用来在输入或输出模式下选择不同的功能。在输入模式下,由CR2相应的位使能中断。如果该引脚无中断功能,则对该引脚无影响。 在输出模式下,置位将提高IO速度。此功能适用O3和O4输出类型。(参见引脚描述表) 在 输入模式时(DDR=0): 0: 禁止外部中断 1: 使能外部中断

在 输出模式时(DDR=1): 0:输出速度最大为2MHZ. 1:输出速度最大为10MHZ

在stm8的库里面已经将这些外设都进行了封装定义,并提供这些外设的SPI,也就是我们所说的stm8的库函数。下面我们看看任何结构化的定义这些IO的寄存器的。

typedef struct GPIO_struct /*typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(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;

所有的IO通用寄存器,定义成GPIO_TypeDef这种类型的结构体,结构体中的每个寄存器都是u8类型,这个可以查看stm8库函数类型声明,其实等价于volatie unsigned char这种类型。那么我们就有了GPIO_TypeDef这种类型。下面是各个端口的结构化定义: #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) 下面是各个端口的起始地址: #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 GPIOG_BaseAddress 0x501E #define GPIOH_BaseAddress 0x5023 #define GPIOI_BaseAddress 0x5028

上面的部分是硬件的抽象成软件的部分,有了这些我们就可以进行对寄存器操作了,比如上面的PA_DDR的操作,现在就可以写成GPIO->DDR=VALUE;/*指针GPIO当前指向的结构体变量中的成员DDR赋值为VALUE */ 这样进行每个端口设置时,肯定要设置使用哪个引脚,速度是多少,哪种模式,这几个对每组端口都是一样的,st有对他进行了封装,如下: 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_TypeDef;可以查看库中的GPIO.H文件中的详细定义。 看下st给出的库提供了那些操作端口的函数吧:

这些函数的详细信息可以参考st的库说明,最好去看下函数的原型代码,这样会有更好的理解。当然了,我在使用的时候也会做一般的说明。 void GPIO_DeInit(GPIO_TypeDef* GPIOx);

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode); void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal);

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);

BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin);

void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState);

介绍到这里,对通用的I/O口有个大概的了解了吧,下面我说说我自己使用的情况: 1、首先新建工程Project,将库文件GPIO.c和GPIO.h复制到该过程目录下, 2、调用st库函数初始化端口IO:

/*函数名(端口PA口,端口第几个引脚PA4,PA5,PA6,IO模式推挽式输出_低电平_10M)*/ GPIO_Init(PORTA, (PIN4 |PIN5 |PIN6), GPIO_MODE_OUT_PP_LOW_FAST); GPIO_Init(PORTB, (PIN0 |PIN1 |PIN2 |PIN3), GPIO_MODE_OUT_PP_HIGH_SLOW);

/*函数名(端口名PB,端口第几个引脚PB0,PB1,PB2,PB3,IO模式推挽式输出_高电平_2M)*/ 这样调用函数,初始化端口完毕。

3、在控制输出时,可以调用st库函数,这里我为了快捷,是直接对输出寄存器进行操作。如:GPIOA->ODR |= (1<<4); PA口的的第5为置高。


stm8学习笔记.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:苏格兰政府行政机构

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: