历史上的今天
返回首页

历史上的今天

今天是:2025年04月16日(星期三)

正在发生

2019年04月16日 | STM8L相关功能配置

2019-04-16 来源:eefocus

最近搞了搞STM8L系列的板子,感觉有些地方和S系列的不太一样,简单总结了相关外设的配置方法,相关的驱动都是可以运行的,详细内容如下

RCC时钟



概述:

系统时钟有四个时钟源,高速外部,高速内部,低速外部,低速内部,上电系统默认的时钟源为高速内部时钟,时钟频率为2M(16M/8).

HSI : 16M高速内部RC振荡器

HSE : 1-16M高速外部晶体振荡器

LSE : 32.768K低速外部晶体振荡器

LSI  : 38K低速内部振荡器

STM8L CLOCK寄存器:

时钟分频寄存器 : CLK_CKDIVR (系统时钟的分频系数设置)

实时时钟寄存器 : CLK_CRTCR   (RTC时钟源及分频系数,RTC忙状态)

内部时钟寄存器 : CLK_ICKCR    (内部时钟开关及状态)

二个外设时钟门控寄存器 : CLK_PCKENR1/CLK_PCKENR2(相关外设的时钟开关)

CCO寄存器 : CLK_CCOR (时钟输出)          

外部时钟寄存器 : CLK_ECKCR(外部时钟开关及状态)

系统时钟状态寄存器 : CLK_SCSR(系统时钟源选择)

 系统时钟切换寄存器 : CLK_SWR(系统时钟源切换)

切换控制寄存器 : CLK_SWCR      

CSS寄存器 : CLK_CSSR(时钟安全系统)

蜂鸣器时钟寄存器 : CLK_CBEEPR (时钟源选择及切换忙状态)

HSI校准寄存器 : CLK_HSICALR

HSI时钟校准微调寄存器 : CLK_HSITRIMR

HSI解锁寄存器 : CLK_HSIUNLCKR

主调节器控制状态寄存器 : CLK_REGCSR(时钟源的开启状态)

系统时钟分频系数,默认值为0x03(8分频),即默认值为2M(16M/8)



每个外设有相应的时钟开关,与stm32一样,在使用相应外设之前要打开时钟,寄存器为CLK_PCKENR1和CLK_PCKENR2


 

 

时钟源选择,我们可以使用默认值选择高速内部时钟



void InitSystemClock( void )

{

    CLK_CKDIVR = 0x00;//系统时钟分频

/*打开全部的外设时钟*/

CLK_PCKENR1 |= 0xff;

CLK_PCKENR2 |= 0xff;

}

STM8L与STM8S的时钟部分没有太大的区别,需要注意的就是STM8L的外设时钟是关闭的(为了降低功耗),而STM8S的外设时钟是打开的,这个大家看一下相关寄存器的复位值就可以了,因此在使用stm8l的时候要记得打开相应的外设时钟

 

GPIO

IO的配置比较简单,STM8L和STM8S没有什么区别,总共也就那么几个寄存器

STM8L GPIO寄存器

一个数据方向寄存器 : Px_DDR

一个输出数据寄存器 : Px_ODR

一个输入寄存器 : Px_IDR

二个控制寄存器 : Px_CR1/Px_CR2

可选择的输入模式:浮动输入和带上拉输入

可选择的输出模式:推挽式输出

关于复用功能,IO口寄存器中没有特定的给出,我们在用到相关复用功能时,在相应外设中进行设置

 端口输出寄存器


端口输入寄存器

端口方向寄存器

 

配置IO的时候要注意一下下面这两个寄存器,CR1主要选择输入输出的相应模式,CR2配置输出速度,要注意一下在适应外部中断的时候,相应的IO口的CR2要开启外部中断


 

 

 

void GPIOConfigure(void)

{

     /*LED灯(用作pwm呼吸灯配置输入模式)*/

PE_DDR &= ~0X80;

  PE_CR1 |= 0X80;

PE_CR2 |= 0X00;

 

 

#if 0

     /*UART 硬件串口可以不用配置*/

     PC_DDR |= 0X08; //输出TX---PC3

     PC_ODR |= 0X08; //拉高置1

     PC_CR1 |= 0X08; //推挽输出

     PC_CR2 |= 0X00; //10M

    

     PC_DDR &= ~0X04;  //输入RX---PC2

     PC_CR1 |= 0X04;   //上拉输入

#endif

/*EXIT---PB4---PB5*/

PB_DDR &= ~0X10; //输入

PB_CR1 |= 0X10; //上拉输入

PB_CR2 |= 0X10; //中断使能

 

PB_DDR &= ~0X20; //输入

PB_CR1 |= 0X20; //上拉输入

PB_CR2 |= 0X20; //中断使能

 

/*PWM---TIM2_CH2*/

PB_DDR |= 0X04;

PB_CR1 |= 0X04;

PB_CR2 |= 0X04;

PB_ODR |= 0X04;

 

/*led灯*/

PC_DDR |= 0X80; //输出

 PC_ODR |= 0X80; //拉高置1

  PC_CR1 |= 0X80; //推挽输出

  PC_CR2 |= 0X80; //10M

}

GPIO的复用功能

STM8L内部集成了控制端口复用的寄存器,不想STM8S那样需要在stvp工具中设置,这一点是很方便的,配置起来也很简单,只需要简单的几个寄存器就可以了。


以串口为例,串口默认的接口为PC3和PC2,我们可以执行SYSCFG_RMPCR1 |= 0X20;就可以用PC5和PC6来进行串口通讯。

void GPIO_AF(void)

{

SYSCFG_RMPCR1 |= 0X20;

}

 

定时器

概述:

STM8L15X芯片有三种不同类型的定时器:

        高级控制型:Timer1;通用型:Timer2/3/5;基础型:Timer4


不同的定时器功能有所差异,无非也就是输入捕获,输出比较,更新溢出,PWM等,配置定时器必须要做的就是(时钟分频---重装载---计数方式---中断使能---开启计数)有其他功能就再配置其他的寄存器,PWM要配置起模式,通道,有效电平以及占空比

相关的寄存器默认值就行很方便

bit7:预装载使能

bit6:对齐方式

bit4: 计数方向

bit0: 计数使能

时钟源分频系数,3个bit,分频值为(1--128中2的整数次幂)



 

 

重装载寄存器,发生溢出事件后自动重新装载

bit7: BREAK中断

bit6:触发中断

bit2: 捕获比较2

bit1:捕获比较2

bit0:更新中断

定时器2有两路PWM(捕获比较通道)

寄存器有TIMx_CCMR1和TIMx_CCMR2在输入和输出模式下配置功能也不一样,以下介绍输出模式下的配置


 

bit4--bit6  PWM模式

bit3:预装载

 bit0--bit1:通道输入输出

bit4--bit5:配置通道2

 bit1:有效电平

bit0:输出使能

该寄存器集成了通道1和通道2的配置

void InitTimer2( void )

{

TIM2_CR1  |= 0x10; //向下计数

TIM2_PSCR = 0X07; //128分频

      

TIM2_ARRH = 0X07; //重装载值

     TIM2_ARRL = 0XD0;

 

TIM2_CCMR2 |= 0X70; //PWM2----使能预装载----通道1输出

TIM2_CCER1 |= 0X10; //高电平有效-----通道输出使能

TIM2_CCR2H = 0X03;

TIM2_CCR2L = 0XE8;

TIM2_BKR = 0x80; //必须加,使能通道输出

 

TIM2_CCR = (TIM2_ARRH << 8 | TIM2_ARRL);

TIM2_IER  = 0x01;  /*  允许更新中断*/

TIM2_CR1  |= 0x01;  /*  计数器使能,开始计数  */

}

需要注意的是在配置定时器2的PWM功能时,STM8L比STM8S要多配置一个寄存器

TIM2_BKR = 0x80; //必须加,使能通道输出

配置时也要讲相应的通道IO进行配置,相关的时钟开关也要打开

串口

串口配置有以下几处:

数据字长,奇偶检验,停止位个数,波特率配置

使用过程中要注意相应的状态为(发送完成,接收完成等)

状态寄存器USART_SR;

数据寄存器USART_DR;

波特率寄存器1 USART_BRR1;

波特率寄存器2 USART_BRR2;

控制寄存器1 USART_CR1;

控制寄存器2 USART_CR2;

控制寄存器3 USART_CR3;

控制寄存器4 USART_CR4;

控制寄存器5 USART_CR5;

保护时间寄存器 USART_GTR;

分频寄存器 USART_PSCR;

bit4: 字长                     

bit2:校验使能    

bit1:奇偶校验     

bit0:校验中断

 

 bit7:发送空中断

bit6:发送完成中断

bit5:接收中断

bit3:发送使能

bit2:接收使能

bit4--bit5:   停止位


 

 

需要注意的是波特率寄存器对接收和发送是一样的,通过对BRR1和BRR2的编程实现。写BRR2应当先于写BRR1,因为写BRR1会更新波特率计数器。

void UART_Init(void)

{

    USART1_CR1=0x00;          //设置M字长,8位数据位

    USART1_CR2=0x2c;          //使能发送、接收;

    USART1_CR3=0x00;         //1位停止位

    

    USART1_BRR2=0x03;       //设置波特率为9600

    USART1_BRR1=0x68;

}

外部中断

关于外部中断,STM8L和STM8S的区别还是比较大的,STM8L可以对具体的某一位开启外部中断,也可以对一组IO开启中断,而STM8S只能对一组IO开启中断,这也是STM8L低功耗的表现,相应的STM8L也多了几个外部中断向量,这个可以在头文件中看到。

在配置外部中断时我们首先要CPU_CCR = 0X28;I1 I0全部写1时才可以配置其他的寄存器

 

下面的程序是配置PB4的外部中断

1:CPU_CCR(I1 I0全部写1)

2:EXTI_CR2(配置PB4)

STM8L提供了EXTI_CR1和EXTI_CR2两个寄存器来配置每组IO的某个位的中断边沿

EXTI_CR1:配置每组IO的bit0---bit3

 

EXTI_CR2:配置每组IO的bit4---bit6

 

void InitEXTI( void )

{

CPU_CCR = 0X28;

EXTI_CR2 |= 0x02;//下降沿触发

}

 

#pragma vector = EXTI4_vector

__interrupt void EXTI1_ISR( void )

{

if(EXTI_SR1 == 0X10)//外部中断4产生

{

EXTI_SR1 = 0x10;


GPIOC_BIT7_FLASH;

EXTI_FLASH = 1;

}

}

如果要配置PB口的外部中断我们需要执行

1:EXTI_CR3 |= 0x02;//下降沿触发

2:EXTI_CONF |= 0X02;

STM8L提供了两个寄存器来配置每组IO的中断EXTI_CR3和EXTI_CR4

EXTI_CR3:配置端口BDEF

 

EXTI_CR4:配置端口GH

 

另外要配置整组的中断,我们还需要进行中断向量的配置EXTI_CONF

 

 

此寄存器的复位值为0x00,默认我们的IO口的中断向量为EXTI0----EXTI7(所以上面程序中我们并没有对这个寄存器操作,因为默认就是EXTI4),如果要使用EXTIA----EXTIF(某些IO没有)我们还需要配置此寄存器

相应的产生中断标志位的寄存器也是不一样,上面的是EXTI_SR1,这里是EXTI_SR2

EXTI_SR1

 

EXTI_SR2

 

void InitEXTI( void )

{

CPU_CCR |= 0X28;

        

EXTI_CR3 |= 0x02;//下降沿触发

EXTI_CONF |= 0X02;

}

 

#pragma vector = EXTIB_vector

__interrupt void EXTI1_ISR( void )

{

if(EXTI_SR2 == 0X01)//外部中断4产生

{

EXTI_SR2 = 0x01;


GPIOC_BIT7_FLASH;

EXTI_FLASH = 1;

}

}

 

另外还要注意一点,在配置中断前关全局中断,配完相应的外设中断后,再开全局中断,这是一个标准操作,如果在外部中断配置前开全局中断,会导致CPU_CCR的值无法写入

配置的外部中断的IO也要配置为输入模式,并打开IO口寄存器的外部中断,另外在产生中断后在中断处理函数中EXTI_SR1 = 0x10;要对中断标志位写1来清除中断标志

下面的程序配置了PB4和PB5,相对应的中断向量也不同 EXTI4_vector和EXTI5_vector

void InitEXTI( void )

{

CPU_CCR |= 0X28;

        

EXTI_CR2 |= 0x0a;//下降沿触发bit4--bit5

        

//EXTI_CR3 |= 0x02;//下降沿触发

//EXTI_CONF |= 0X02;

}

 

#pragma vector = EXTI4_vector

__interrupt void EXTI1_ISR( void )

{

if(EXTI_SR1 == 0X10)//外部中断4产生

{

EXTI_SR1 = 0x10;

GPIOC_BIT7_FLASH;

EXTI_FLASH = 1;

}

}

 

#pragma vector = EXTI5_vector

__interrupt void EXTI1_5ISR( void )

{

if(EXTI_SR1 == 0X20)//外部中断4产生

{

EXTI_SR1 = 0x20;

GPIOC_BIT7_FLASH;

//EXTI_FLASH = 1;

}

}

 

AD转换

ADC配置寄存器1 ADC_CR1

ADC配置寄存器2 ADC_CR2

ADC配置寄存器3 ADC_CR3

ADC状态寄存器   ADC_SR

ADC数据高位寄存器ADC_DRH

ADC数据低位寄存器ADC_DRL

ADC高阈值高位寄存器ADC_HTRH

ADC高阈值低位寄存器ADC_HTRL

ADC低阈值高位寄存器ADC_LTRH

ADC低阈值低位寄存器ADC_LTRL

ADC通道序列寄存器1 ADC_SQR1

ADC通道选择扫描寄存器2 ADC_SQR2

ADC通道选择扫描寄存器3 ADC_SQR3

ADC通道选择扫描寄存器4 ADC_SQR4

ADC触发禁能1-4 ADC_TRIGR1/2/3/4

具体的转换通道要看手册,开始转换后要等待几,转换完成后,读取数据会清除相应的标志位,当不选择触发输入时,要ADC1_SQR3 |= 0X40; //选择扫描通道,不然无法转换

 

   bit5--bit6:精度配置

bit4:模拟看门狗

 bit2: 连续/单次

bit1:开始

bit0:开关

 

bit5--bit7:采样时间

bit0--bit4:转换通道

 

                                                   选择要扫描的通道                                                                        

unsigned intReadSTM8AD(char idx )

{

 

ADC1_CR1 |= 0X01; //使能ADC

ADC1_CR3 |= idx; //选择转换通道

ADC1_SQR3 |= 0X40; //选择扫描通道

 

 

ADC1_CR1 |= 0x02; //开始转换;

asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

while(!(ADC1_SR & 0X01));

return ADC1_DRH;

}

EEPROM

eeprom来说,stm8L和stm8S的寄存器配置都是一样的,只是eeprom的起始地址不一样,起始地址为0x1000

 

顺序写入FLASH_DUKR=0xAE;FLASH_DUKR=0x56;来进行解锁,

 

 

void InitEEPROM(void)

{

/*解锁*/

do

  {

FLASH_DUKR=0xAE;

FLASH_DUKR=0x56;

}while((FLASH_IAPSR & 0x08)== 0x00);

}

 

 

unsigned char Stm8lEepromRead( unsigned char ucAddress )

{

unsigned char ucReturn;

unsigned char *p;

p = (unsigned char *)(0x1000 + ucAddress * 0x04);//读数据

ucReturn = *p;

 

return(ucReturn);

}

 

 

void Stm8lEepromWrite( unsigned char ucAddress, unsigned char ucData )

{

unsigned char *p;

p = (unsigned char *)(0x1000 + ucAddress * 0x04);//转换地址

*p = ucData; //写数据

while((FLASH_IAPSR & 0x04) == 0x00); //等待写操作完成

 

}

独立看门狗

 

IWDG_KR用来配置开启看门狗,重装载,解锁控制命令

 

时钟源是低速内部时钟,在此寄存器中分频

 

重装载数值寄存器,在往IWDG_KR中写0xAA时重新装载喂狗

void IWDG_SetPrescaler(void)

{

IWDG_PR = 0x06;//时钟源分频

}

 

void IWDG_SetReload(void)

{

IWDG_RLR = 0xFF;//看门狗重装载值

}

 

void IWDG_Refresh(void)

{

IWDG_KR = (unsigned int)0xAA;//重装载看门狗

}

 

void IWDG_Enable(void)

{

IWDG_KR = (unsigned int)0XCC;//开启看门狗

}

 

void IWDG_Access(void)

{

IWDG_KR = (unsigned int)0X55;//允许访问看门口狗寄存器

}

 

void IWDG_Configuration(void)

{

IWDG_Enable();

IWDG_Access();

IWDG_SetPrescaler();

IWDG_SetReload();

IWDG_Refresh();

}

推荐阅读

史海拾趣

HTC Korea(TAEJIN Technology )公司的发展小趣事

进入安卓时代,HTC再次展现了其敏锐的市场洞察力和强大的技术实力。2008年,HTC联合电信运营商T-Mobile推出了世界上第一款安卓手机T-Mobile G1,这款手机的成功标志着HTC正式进入了安卓阵营。随后,HTC推出了多款备受好评的安卓手机,如HTC Hero(G3)等,进一步巩固了其在智能手机市场的地位。与谷歌和安卓的合作,为HTC带来了前所未有的发展机遇。

Crydom公司的发展小趣事

HTC Korea(前身为TAEJIN Technology Co., Ltd.)成立于2000年,最初以Linear IC产品的研发及生产为主,逐步在通信、消费类及PC等应用领域稳步发展。然而,公司的真正突破发生在2006年,这一年HTC决定从OEM代工厂转型为自主品牌制造商。这一转型并非易事,面临着合作伙伴转变为竞争对手的风险,导致股价一度暴跌。但HTC坚持下来,推出了HTC Touch和HTC Diamond等经典机型,成功吸引了市场的关注,股价逐渐回升,最终奠定了其在手机市场的重要地位。

Global Components & Controls公司的发展小趣事
在保证性能和质量的前提下,合理控制元件成本,以提高产品的市场竞争力。
Coors Components Inc公司的发展小趣事

除了关注经济效益外,Coors Components Inc公司还积极履行社会责任。公司积极参与公益事业,为社会做出贡献;同时,公司也注重环保和可持续发展,努力降低生产过程中的环境污染。这些举措不仅提升了公司的品牌形象,还赢得了社会各界的广泛赞誉。

以上是关于电子行业公司发展的通用框架,你可以根据这些框架来进一步了解“Coors Components Inc”公司的具体发展故事。请注意,在编写故事时,应确保所描述的事实准确无误,避免夸大或缩小事实。

Blue Creation公司的发展小趣事

Blue Creation公司在电子行业的起步并不顺利,一度面临资金短缺和技术瓶颈。然而,公司创始人凭借对技术的深厚理解,带领团队开发出一款革命性的电源管理技术。这项技术不仅大幅提高了电子设备的续航能力,还降低了能耗,迅速赢得了市场的青睐。随着技术的不断迭代和完善,Blue Creation逐渐在电子行业崭露头角。

Headland Technology Product Group公司的发展小趣事

近年来,随着环保意识的日益增强,HBControls积极响应国家号召,致力于绿色环保产品的研发和生产。公司投入大量资金引进环保设备和技术,对生产流程进行改造升级,以减少对环境的影响。同时,HBControls还积极推广绿色供应链理念,与供应商共同构建绿色、低碳的供应链体系。这些举措不仅提升了公司的社会形象,也为企业的可持续发展奠定了坚实的基础。

问答坊 | AI 解惑

如何快速创建开关电源的PCB版图设计

如今的开关稳压器和电源越来越紧凑,性能也日益强大,而越来越高的开关频率是设计人员面临的主要问题之一,正是它使得PCB的设计越来越困难。事实上,PCB版图已经成为区分好与差的开关电源设计的分水岭。本文针对如何一次性创建优秀PCB版图提出一些 ...…

查看全部问答>

我想要份单片机方面的中英资料

我想要份单片机方面的中英资料,大家帮帮我…

查看全部问答>

看《风声》电影 谈数据传输加密

来源:http://bbs.c114.net/viewthread.php?tid=372433 国庆60周年,电影市场中涌现出大量关于抗ri、建国的影片,如***、风声、邓稼先等,其中风声让我感觉特别亲切。不是周迅一贯冷酷的演技感动了我,也不是李冰冰优美气质的身段刺激了我;而是风 ...…

查看全部问答>

BSP移植问题

我在CE6上面克隆了一个BSP,是DeviceEmulator, 我是第一次接触,现在想问个简单的问题, 在FILES目录中的platform.bib文件中,有一些像 ; @CESYSGEN IF CE_MODULES_WAVEAPI IF BSP_NOAUDIO !     s3c2410x_wavedev.dll    ...…

查看全部问答>

pxa 2360-2大家帮忙。

最近在看这个: -----i2c源代码情景分析(Beta2)---------- 但是上面提到的-----本文档中的源代码以i2c-2.9.1包及www.arm.linux.org.uk上下载的pxa的i2c适配器的补丁2360-2为准 ----------2360-2的源码一直没有找到,网站也看了,可能我水平不行 ...…

查看全部问答>

MSP430的PWM输出脉冲上下不对称是什么问题啊?新手求指导,谢谢。

MSP430的PWM输出脉冲上下不对称是什么问题啊?新手求指导,谢谢。…

查看全部问答>

关于uCOS-ii的一些其他问题,求解释啊

第一个问题: /* ********************************************************************************************************* *                         ...…

查看全部问答>

UCOS移植到MSP430过程与心得体会《3》

static void OS_InitRdyList (void){     INT16U    i;     INT8U    *prdytbl;      OSRdyGrp       = 0x00;    ready list& ...…

查看全部问答>

大家一起来赚积分啊。。。。。。

大家一起来赚积分啊。。。。。。…

查看全部问答>

炫3D 元件模型

那个贴子不能编辑了。所以在此发个新贴,目前最新模型 …

查看全部问答>