stm8寄存器.docx

上传人:b****3 文档编号:10534429 上传时间:2023-05-26 格式:DOCX 页数:11 大小:20.67KB
下载 相关 举报
stm8寄存器.docx_第1页
第1页 / 共11页
stm8寄存器.docx_第2页
第2页 / 共11页
stm8寄存器.docx_第3页
第3页 / 共11页
stm8寄存器.docx_第4页
第4页 / 共11页
stm8寄存器.docx_第5页
第5页 / 共11页
stm8寄存器.docx_第6页
第6页 / 共11页
stm8寄存器.docx_第7页
第7页 / 共11页
stm8寄存器.docx_第8页
第8页 / 共11页
stm8寄存器.docx_第9页
第9页 / 共11页
stm8寄存器.docx_第10页
第10页 / 共11页
stm8寄存器.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

stm8寄存器.docx

《stm8寄存器.docx》由会员分享,可在线阅读,更多相关《stm8寄存器.docx(11页珍藏版)》请在冰点文库上搜索。

stm8寄存器.docx

stm8寄存器

所用芯片stm8s105s4

开发环境:

STVisualDevelop

Stm8s的库为V1.1.1

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

系统复位后,所有外设时钟均处于开的状态。

用户可通过清除CLK_PCKENR1或CLK_PCKENR2中的PCKEN位来关闭相应的外设时钟。

但是在关闭外设的时钟前,用户必须设置相应的位禁用该外设。

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

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

例如禁用所有外设时钟:

CLK_PCKENR1=0x00;//closeallclksofPeripheral

CLK_PCKENR2=0x00;

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

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

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

ODR6

0

ODR5

0

ODR4

0

ODR3

0

ODR2

0

ODR1

0

ODR0

0

0x01

Px_IDR

复位值

IDR7

0

IDR6

0

IDR5

0

IDR4

0

IDR3

0

IDR2

0

IDR1

0

IDR0

0

0x02

Px_DDR

复位值

DDR7

0

DDR6

0

DDR5

0

DDR4

0

DDR3

0

DDR2

0

DDR1

0

DDR0

0

0x03

Px_CR1

复位值

C17

0

C16

0

C15

0

C14

0

C13

0

C12

0

C11

0

C10

0

0x04

Px_CR2

复位值

C27

0

C26

0

C25

0

C24

0

C23

0

C22

0

C21

0

C20

0

其中Px_ODR是ODR[7:

0]:

端口输出数据寄存器位;

(1)在输出模式下,写入寄存器的数值通过锁存器加到相应的引脚上。

读ODR寄存器,返回之前锁存的寄存器值。

(2)在输入模式下,写入ODR的值将被锁存到寄存器中,但不会改变引脚状态。

ODR寄存器在复位后总是为0。

位操作指令(BSET,BRST)可以用来设置DR寄存器来驱动相应的引脚,但不会影响到其他引脚。

Px_IDR:

IDR[7:

0]:

端口输入数据寄存器位

不论引脚是输入还是输出模式,都可以通过该寄存器读入引脚状态值。

该寄存器为只读寄存器。

0:

逻辑低电平1:

逻辑高电平

Px_DDR:

DDR[7:

0]:

数据方向寄存器位,这些位可通过软件置1或置0,选择引脚输入或输出0:

输入模式1:

输出模式

Px_CR1:

C1[7:

0]控制寄存器位

这些位可通过软件置1或置0,用来在输入或输出模式下选择不同的功能。

在输入模式时(DDR=0):

0:

浮空输入1:

带上拉电阻输入

在输出模式时(DDR=1):

0:

模拟开漏输出(不是真正的开漏输出)

1:

推挽输出,由CR2相应的位做输出摆率控制

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的寄存器的。

typedefstructGPIO_struct

{

vu8ODR;/*!

vu8IDR;/*!

vu8DDR;/*!

vu8CR1;/*!

vu8CR2;/*!

}GPIO_TypeDef;

所有的IO通用寄存器,定义成GPIO_TypeDef这种类型的结构体,结构体中的每个寄存器都是u8类型,这个可以查看stm8库函数类型声明,其实等价于volatieunsignedchar这种类型。

那么我们就有了GPIO_TypeDef这种类型。

下面是各个端口的结构化定义:

#defineGPIOA((GPIO_TypeDef*)GPIOA_BaseAddress)

#defineGPIOB((GPIO_TypeDef*)GPIOB_BaseAddress)

#defineGPIOC((GPIO_TypeDef*)GPIOC_BaseAddress)

#defineGPIOD((GPIO_TypeDef*)GPIOD_BaseAddress)

#defineGPIOE((GPIO_TypeDef*)GPIOE_BaseAddress)

#defineGPIOF((GPIO_TypeDef*)GPIOF_BaseAddress)

下面是各个端口的起始地址:

#defineGPIOA_BaseAddress0x5000

#defineGPIOB_BaseAddress0x5005

#defineGPIOC_BaseAddress0x500A

#defineGPIOD_BaseAddress0x500F

#defineGPIOE_BaseAddress0x5014

#defineGPIOF_BaseAddress0x5019

#defineGPIOG_BaseAddress0x501E

#defineGPIOH_BaseAddress0x5023

#defineGPIOI_BaseAddress0x5028

上面的部分是硬件的抽象成软件的部分,有了这些我们就可以进行对寄存器操作了,比如上面的PA_DDR的操作,现在就可以写成GPIO->DDR=VALUE;

这样进行每个端口设置时,肯定要设置使用哪个引脚,速度是多少,哪种模式,这几个对每组端口都是一样的,st有对他进行了封装,如下:

typedefenum

{

GPIO_MODE_IN_FL_NO_IT=(u8)0b00000000,/*!

GPIO_MODE_IN_PU_NO_IT=(u8)0b01000000,/*!

GPIO_MODE_IN_FL_IT=(u8)0b00100000,/*!

GPIO_MODE_IN_PU_IT=(u8)0b01100000,/*!

GPIO_MODE_OUT_OD_LOW_FAST=(u8)0b10100000,/*!

GPIO_MODE_OUT_PP_LOW_FAST=(u8)0b11100000,/*!

GPIO_MODE_OUT_OD_LOW_SLOW=(u8)0b10000000,/*!

GPIO_MODE_OUT_PP_LOW_SLOW=(u8)0b11000000,/*!

GPIO_MODE_OUT_OD_HIZ_FAST=(u8)0b10110000,/*!

GPIO_MODE_OUT_PP_HIGH_FAST=(u8)0b11110000,/*!

GPIO_MODE_OUT_OD_HIZ_SLOW=(u8)0b10010000,/*!

GPIO_MODE_OUT_PP_HIGH_SLOW=(u8)0b11010000/*!

}GPIO_Mode_TypeDef;

具体GPIO_Mode_TypeDef;可以查看库中的GPIO.H文件中的详细定义。

看下st给出的库提供了那些操作端口的函数吧:

这些函数的详细信息可以参考st的库说明,最好去看下函数的原型代码,这样会有更好的理解。

当然了,我在使用的时候也会做一般的说明。

voidGPIO_DeInit(GPIO_TypeDef*GPIOx);

voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefGPIO_Pin,GPIO_Mode_TypeDefGPIO_Mode);

voidGPIO_Write(GPIO_TypeDef*GPIOx,u8PortVal);

voidGPIO_WriteHigh(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefPortPins);

voidGPIO_WriteLow(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefPortPins);

voidGPIO_WriteReverse(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefPortPins);

u8GPIO_ReadInputData(GPIO_TypeDef*GPIOx);

u8GPIO_ReadOutputData(GPIO_TypeDef*GPIOx);

BitStatusGPIO_ReadInputPin(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefGPIO_Pin);

voidGPIO_ExternalPullUpConfig(GPIO_TypeDef*GPIOx,GPIO_Pin_TypeDefGPIO_Pin,FunctionalStateNewState);

介绍到这里,对通用的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为置高。

例如:

Main()

{u16i;

GPIO_Init(PORTA,(PIN4|PIN5|PIN6),GPIO_MODE_OUT_PP_LOW_FAST);

While

(1)

{GPIOA->ODR^=(1<<4);//灯闪烁

For(i=0;i<3000;i++);//延时

}

}

串口通信UART

Stm8微控制器家族的通用同步异步收发器(UART1,UART2或UART3)提供了一种灵活的方法与使用工业标准NRZ异步创行数据格式的外部设备之间进行全双共数据交换。

Stm8的UART提供宽范围的波特率选择,并且支持多处理器通讯。

后面关于宏定义有关的都不再介绍,详情请看st固件库,从这里开始只介绍如何使用st提供的固件库搭建自己的程序。

因为我用的芯片stm8s105s4只有UART2,所有这里直接调用固件库中的uart2.c和uart2.h就可以了。

Uart初始化函数如下:

UART2_DeInit();//uart2中的个寄存器清零

/*UART1configuration------------------------------------------------------*/

/*UART1configuredasfollow:

-BaudRate=9600baud

-WordLength=8Bits

-OneStopBit

-Oddparity

-Receiveandtransmitenabled//允许发送、接收

-UART1Clockdisabled*/

/*ConfiguretheUART1*/

UART2_Init((u32)9600,UART2_WORDLENGTH_8D,UART2_STOPBITS_1,UART2_PARITY_NO,UART2_SYNCMODE_CLOCK_DISABLE,UART2_MODE_TXRX_ENABLE);

//*EnabletheUART1Receiveinterrupt:

thisinterruptisgeneratedwhenthe

//UART1receivedataregisterisnotempty

UART2_ITConfig(UART2_IT_RXNE_OR,ENABLE);//开uart2接收中断

需要了解UART2_Init();可以查看uart2.c中的原型函数

这样,UART2通信已经配置好了,接下来就是使用了。

发送函数如下:

voidUART2_SendData8(u8Data)

{u8i;

/*TransmitData*/

UART2->DR=Data;

while((UART2->SR&0x40)==0);//我修改的

UART2->SR&=~(1<<6);//我修改的

}

在你需要发送数据的时候,直接调用UART2_SendData8(u8Data)就可以了。

在串口接收中断中调用读取数据函数:

u8UART2_ReceiveData8(void)

{

return((u8)UART2->DR);

}

也可以直接读取寄存器中的数据,

注意:

在中断中读完数据后,退出中断前都需要先清中断标志位,调用函数如下:

UART2_ClearITPendingBit(UART2_IT_LBDF);否则中断一直存在。

ADC转换配置:

ADC1和ADC2是10位的逐次比较型模拟数字转换器。

提供多达16路多功能的输入通道(实际准确的通道数量在数据手册的引脚描述说明)。

A/D转换的各通道可以执行单次和连续的转换模式。

相对与ADC2、ADC1具有一些扩展功能,包括扫描模式,带缓存的连续模式以及模拟看门狗。

请参考数据手册来了解不同型号的ADC1和ADC2的功能信息。

ADC开—关控制

通过置位ADC_CR1寄存器的ADON位来开启ADC。

当首次置位ADON位时,ADC从低功耗模式唤醒。

为了启转换必须第二次使用写指令来置位ADC_CR1寄存器的ADON位。

在转换结束时ADC会保持在上电状态,用户只需要置位ADON位来启动下次转换。

如果长时间没有使用ADC,推荐ADC切换到低功耗模式来降低功耗,这可以通过清零ADON位来实现。

当ADC模块上电后,所选通道对应的I/O输出模块是被禁用的,因此推荐在ADC上电前要选适合的ADC转换通道。

ADC时钟

ADC的时钟是由Fmaster时钟经过预分频后提供的。

时钟的预分频因子是由ADC_CR1寄存器的SPSEL[2:

0]决定的。

数据对齐

ADC_CR2寄存器中的ALIGN位于选择转换后数据的对齐方式:

右对齐:

8个低位数据被写入ADC_DL中,其余在ADC_DH中,读取时必须先读低位再读高位。

左对齐:

8个高位数据被写入ADC_DH中,其余在ADC_DL中,读取时必须先读高位再读低位。

我利用ST公司提供的固件库实验如下:

初始化如下(单次转换):

voidSys_ADC1_3_Int(void)

{

/*InitGPIOforADC1*/

GPIO_Init(GPIOB,(GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2),GPIO_MODE_IN_FL_NO_IT);//初始化ADC端口

CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC,ENABLE);

ADC1_DeInit();

//InitADC2peripheral

ADC1_Init(ADC1_CONVERSIONMODE_SINGLE,ADC1_CHANNEL_0,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);

//ADC1_ITConfig(ADC1_IT_EOCIE,ENABLE);//EnableEOCinterrupt只有在使用ADC中断的时候才打开这一项

/*StartConversion*/

//ADC1_StartConversion();//启动ADC转换

}

这里ADC读取分使用中断方式和不使用两种

不使用中断,启动ADC后等待转换完毕:

ADC1_Init(ADC1_CONVERSIONMODE_SINGLE,ADC1_CHANNEL,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_CHANNEL,DISABLE);//配置ADC通道及ADC转换模式/*数据右对齐*/

ADC1_StartConversion();//启动ADC转换/*StartConversion*/

while((ADC1->CSR&0x80)!

=0x80);//等待ADC转换完毕

Adc_Value=ADC1_GetConversionValue();//读取ADC转换数据,先低位,后高位

中断方式:

在ADC中断函数中,直接读取ADC转换数据,

Adc_Value=ADC1_GetConversionValue();//读取ADC转换数据,先低位,后高位

在主程序中隔一段时间选择ADC通道和启动ADC就可以了。

ADC1_Init(ADC1_CONVERSIONMODE_SINGLE,ADC1_CHANNEL_0,ADC1_PRESSEL_FCPU_D2,ADC1_EXTTRIG_TIM,DISABLE,ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_CHANNEL0,DISABLE);

//ADC1_ITConfig(ADC1_IT_EOCIE,ENABLE);//EnableEOCinterrupt只有在使用ADC中断的时候才打开这一项

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2