最近搞了搞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();
}
STM8L相关功能配置相关推荐
- 神州数码DCN交换机 DHCP相关功能配置
目录 交换机DHCP Server典型配置 一.组网说明 二.组网图 三.配置步骤 四.注意事项 交换机DHCP Relay典型配置 一.组网说明 二.组网图 三.配置步骤 四.注意事项 交换机DHC ...
- 神州数码DCN交换机 SAVI相关功能配置
目录 SAVI功能简介 一.SAVI技术简介 二.SAVI技术原理 1.SAVI原理 2.NDP Snooping功能 3.DHCPv6 Snooping功能 SAVI DHCP-Only模式典型配置 ...
- Linux下PHOEBUS的编译及相关功能配置
前言 Phoebus是一个框架和一系列工具,用于监视和操作大规模控制系统,例如加速器社区中的系统.phoebus是控制系统工作室工具集的更新,它消除了Eclipse RCP和SWT的依赖性 1. 下载 ...
- Cisco PT模拟实验(19) 路由器的NAT功能配置
Cisco PT模拟实验(19) 路由器的NAT功能配置 实验目的: 掌握NAT网络地址转换的原理及功能 掌握NAT地址映射和端口映射的配置方法 掌握广域网(WAN)接入技术的原理 实验背景: 情景一 ...
- Nginx相关基础配置详解
一.I/O类型及与其相关概念: 1.1同步和异步:synchronous, asynchronous [关注的是消息通知机制] 同步:调用发出不会立即返回,但一旦返回就可以返回最终结果: 异步:调用 ...
- [转载] FatFs模块功能配置选项
本文使用的FatFs版本为:V0.12b(2016年9月4发布) Fatfs模块的功能可以裁剪,通过配置宏定义实现,宏定义位于文件ffconf.h中. 1.功能配置 1.1 _FS_READONLY ...
- 关于fckEditor的功能配置-PHP版
FCKeidtor是个国外的多语言编辑器,你可以对其配置文件进行简单修改使之支持目前常用Web开发语言的应用,下面是在php的具体配置过程. 精简: 因为这个编辑器是支持多语言的,所以我们需要对使用对 ...
- Spark性能相关参数配置详解
随着Spark的逐渐成熟完善, 越来越多的可配置参数被添加到Spark中来, 本文试图通过阐述这其中部分参数的工作原理和配置思路, 和大家一起探讨一下如何根据实际场合对Spark进行配置优化. 由于篇 ...
- iOS--百度地图相关功能的实现
###一.配置百度地图SDK ####1. 申请密钥 进入应用管理平台,点击创建应用然后点击提交 密钥就申请成功了!! 在左侧的查看应用里面,就可以看到刚刚申请好的密钥. ####2. 下载百度地图S ...
最新文章
- C4D和Redshift:2D矢量到三维渲染 Cinema 4D and Redshift: 2D vector to 3D render
- linux shell 按行 逐行 读取文件
- java生成xsd_java 生成XSD
- 概述 互联网时代的商业挑战
- sourcetree,创建工作流报错:Fatal: Not a gitflow-enabled repo yet. Please run 'git flow init' first.-》解决办法...
- Spring AOP 面向切面编程
- mysql通用日志不打印_解决logback不打印mybatis的SQL日志的问题
- jquery cookie的用法
- linux开机自启服务命令,linux开机自启服务命令
- php文件上传sha1,PHP中sha1_file与md5_file哪个更快?
- 微软 exFAT 技术将进入 Linux 内核
- 人脸识别 Face Recognition安装使用
- 《系统集成项目管理》第十六章 变更管理
- 联想,华为,惠普的服务器和存储的管理口默认地址与默认用户名密码!
- 阿里云企业物联网平台推出千里传音播报服务 高效打造云端一体智能硬件
- PHPStorm 配置 debug 默认参数
- 遇到UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xa3 in position 4: invalid start byte的几种处理方法
- Go语言中的字符串拼接方法介绍
- 刚子扯谈:未完待续的微信5.0
- OLED屏幕和LCD屏幕的区别与优劣
热门文章
- windows无法完成安装,若要在此计算机上安装windows,请重新启动安装
- deepnode软件下载地址_Flash cs6软件下载地址及安装教程
- MapGIS地图导入
- 区块链在改善网络安全方面的潜力?
- IIC(I2C)协议详解
- 人家裁员我加薪, 这个80后凭什么身价1200亿?
- J2EE框架设计技术分析
- [原创]jQuery小插件-collapsible
- 188.武士风度的牛
- CenterOS 处理php环境