×
嵌入式 > 技术百科 > 详情

初识STM8S105K心得

发布时间:2021-05-28 发布时间:
|

最近由于公司项目需要STM8S105K这颗芯片,这两天我也捣鼓了下,正好现在开通了博客,以此记录下自己的工作。

开发环境:

window10操作系统;

IAR for STM8;

开发工具;

window10电脑;

STM8S105K4t6最小系统;

ST-link烧录器

本人之前工作上主要使用STM32芯片,开发STM8S时,是使用ST的库开发还是直接操作寄存器开发的选择上,考虑到STM32上主要使用的库,而STM8S是八位单片机,寄存器相对于STM32简单不少,故本人使用寄存器操作开发。我以讲解程序案列来与大家分享心得。

实验案例使用到的资源:

1,IO口的位操作

2,串口发送以及串口接收与空闲中断

3,定时器1的使用

首先,使用IAR新建一个基础工程

对于STM8S的IO口操作,我们可以向使用51单片机那样简单直接位操作,我通过宏定义来对于位操作:

#defineLED0_TogglePE_ODR_bit.ODR5=!PE_ODR_bit.ODR5//LED接在PE5上

#defineLED1_TogglePC_ODR_bit.ODR1=!PC_ODR_bit.ODR1//LED接在PC1上

#defineLED0PE_ODR_bit.ODR5

#defineLED1PC_ODR_bit.ODR1

上面代码中对于了两个LED灯,然后配置下IO口就可以实现灯的亮灭,IO配置如下:

voidGPIO_init(void)

{

PE_DDR=(1<<5);//配置PE端口的方向寄存器PD3输出

PE_CR1=(1<<5);//设置PE5为推挽输出



PC_DDR=(1<<1);//配置PC端口的方向寄存器PD3输出

PC_CR1=(1<<1);//设置PC1为推挽输出

}

STM8S的串口使用前,我们实现要清楚STM8S的系统时钟,我使用的时STM8S的内部16M时钟作为时钟源,然后1分频作为系统时钟,时钟设置代码如下:

/*******************************************************************************

*函数名:CLK_init

*描述:内部16M时钟作为系统时钟

*输入:

*输出:

*返回:

*注意:

*******************************************************************************/

voidCLK_init(void)

{



CLK_CKDIVR=0x00;//16M内部RC经1分频后系统时钟为16M



}

我们知道系统设置后对串口波特率就好计算了。串口设置:波特率115200,数据位8,停止位1,奇偶校验None,串口初始化主要进行串口参数设置,使能发送与接收,以及开通接收中断与空闲中断,最后开启总中断。初始化函数如下:

/*******************************************************************************

*函数名:GPIO_init

*描述:GPIO初始化

*输入:

*输出:

*返回:

*注意:

*******************************************************************************/

voidUART2_Init(void)

{

asm("sim");//关全局中断

/*寄存器恢复到默认值*/

UART2_CR3=0x00;

UART2_CR2=0x00;

UART2_CR3=0x00;



UART2_CR2=0x3c;//使能发送和接收,及使能接收中断和空闲中断



UART2_BRR2=0x0b;//波特率115200

UART2_BRR1=0x08;	

asm("rim");//关全局中断

}

STM8S串口接收数据,我使用接收中断和空闲中断来完成数据的接收。当发送字符串时,每收到一个字符时触发接收中断,而只有当数据接收完检测到空闲时才触发空闲中断,中断代码如下:

#pragmavector=UART2_R_RXNE_vector

__interruptvoidUART2_RX_IRQHandler(void)

{

staticunsignedchari=0;

staticunsignedcharRXBuff[20];





if(UART2_SR&0x20)

{



RXBuff[i++]=UART2_DR;//对UART_DR的读操作可以将该位清零

;

}

if(UART2_SR&0x10)

{



printf("%sn",RXBuff);

i=UART2_SR;//对UART_DR的读操作可以将该位清零

i=UART2_DR;

i=0;



}



}

而串口发送数据使用printfd的话就很方便,我也添加实现printf的代码,代码如下:

/*******************************************************************************

*函数名:UART2_SendByte

*描述:uart发送一个字符

*输入:u8Dat发送的字符

*输出:无

*返回:

*注意:

*******************************************************************************/

voidUART2_SendByte(unsignedchardat)

{

UART2_DR=dat;	

while(!(UART2_SR&0x40));	//发送标志位是否为空	

}



/*******************************************************************************

*函数名:UART2_SendString

*描述:uart发送字符串

*输入:u8*Data,u16len

*输出:无

*返回:

*注意:

*******************************************************************************/

voidUART2_SendString(unsignedchar*Data,unsignedshortlen)

{

unsignedshorti=0;

for(;i

关于定时器的使用,比较简单,主要实现LED灯的亮灭,我就不多讲,附上代码,代码上有很多注释,代码如下

/*******************************************************************************

*函数名:TIM1_init

*描述:定时器1初始化

*输入:

*输出:

*返回:

*注意:中断周期500ms

*******************************************************************************/

voidTIM1_init(void)

{

asm("sim");//关全局中断

TIM1_PSCRH=0x3F;//8M系统时钟经预分频f=fck/(PSCR+1)

TIM1_PSCRL=0x7F;//PSCR=0x1F3F,f=16M/(0x3F7F+1)=1000Hz,每个计数周期1ms

TIM1_ARRH=0x01;//自动重载寄存器ARR=0x01F4=500

TIM1_ARRL=0xF4;//每记数500次产生一次中断,即500ms

TIM1_IER=0x01;//允许更新中断

TIM1_CR1=0x01;//计数器使能,开始计数

asm("rim");//开全局中断

}







/*******************************************************************************

*函数名:TIM1_OVR_UIF

*描述:定时器1中断函数,处理中断事物

*输入:

*输出:

*返回:

*注意:一点要清除中断标志

*******************************************************************************/

#pragmavector=TIM1_OVR_UIF_vector

__interruptvoidTIM1_OVR_UIF(void)

{

if(TIM1_SR1&0x01)

{

LED0=!LED0;

LED1=!LED1;

TIM1_SR1=0x00;//清除更新中断标记,这步不能漏掉,否则会连续进入中断程序

}



}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器