一、时钟配置
在芯片中存在的针对所有设备的时钟管理器,通过RCC可以配置所有总线和外设的时钟,包括内核的时钟。在使用每一个外设和功能前必须使能时钟。
1.外设复位,外设时钟关闭 RCC->APB2RSTR、RCC->APB1RSTR、RCC->APB2ENR、RCC->APB1ENR、RCC->AHBENR
2.清除/使能时钟就绪中断(一般清除) RCC->CIR
3.HSI、HSE、LSE等外部时钟使能RCC->CR
4.等待外部时钟就绪 RCC->CR
5.时钟源选择,PLL分频系数确定 RCC->CFGR
6.使能PLL,并等待PLL锁定 RCC->CR
7.选择系统时钟 RCC->CFGR
8.等待设置成功
while(temp!=0x02) //等待PLL作为系统时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
9.外设使能,外设得到时钟
二、SysTick滴答时钟(每过一个时钟周期RELOAD寄存器的值减1)
源于内核的滴答计数器,它被放置在内核的NVIC中,采用该计数器的延时函数可以直接应用于所有COM3内核的芯片中。
1.systick时钟源选择,由此得到时钟周期 systick_ctrl
2.计算产生1us需要多少个时钟周期 fac_us=SYSCLK/8;
3.计算产生1ms需要多少时钟周期fac_ms=fac_us1000;
(开始写延时函数)
4.计算出RELOAD寄存器的值,也是产生相应延时所需要的时钟周期数
RELOAD=fac_usnus
5.设置LOAD寄存器,清空计数器systick_reload
6.开启倒数 systick_ctrl
7.循环检测计数到0的标志位,等待时间到达
while(!((systick_ctrl>>16)&0x00000001));
8.关闭计数器,清空计数器 systick_ctrl、systick_val
三、GPIO
1.开启RCC外设时钟
2.设置GPIO模式:输出/输入
3.输出:设置GPIO初始化电平;输入:设置上拉/下拉
4.逻辑控制
AFIO是设置重映射和调试IO的功能寄存器,通过对AFIO寄存器的配置可以完成IO重映射的设置。
三、定时器中断
1.设置时钟来源(一般使用内部时钟) TIMx->SMCR
2.使能时钟 RCC->APB1ENR
3.设置计数器时钟频率 TIMx->PSC
4.设置计数器的计数初值 TIMx->ARR
5.使能定时器,允许更新中断 TIMx->CR1,TIMx->DIER
6.设置中断优先级
7.执行中断服务程序
8.在中断服务程序中
判断溢出中断 if(TIM3->SR&0X0001)//溢出中断
逻辑程序
清中断标志位 ==TIM3->SR &= ~(1<<0);//清除中断标志位 ==
计数器输入时钟频率计数方法:
四、串行通信
通信分为并行和串行两种,并行的8位数据同时传输,串行的8位数据按顺序一个一个传输。串行通信又分单工,半双工,全双工。其通信方式分为同步和异步两种,同步通信带有时钟同步信号,如SPI,IIC;异步通信不带有时钟同步信号,如UART,单总线。
1.串口时钟使能,GPIO时钟使能 RCC->APB2ENR
2.串口复位,而后停止复位 RCC->APB2RSTR
3.GPIO端口模式设置,TX输出50MHZ,RX输入上拉/下拉模式 GPIOA->CRH
4.串口参数初始化 USART1->BRR、USART1->CR1
5.开启中断并且初始化NVIC(需要中断时才有这个步骤)
6.使能串口 USART1->CR1
7.编写中断处理函数,在中断里判断接收、发送状态
五、外部中断
1.使能外部中断时钟
2.设置中断线对应的IO输入,使能IO复用时钟 AFIO->EXTICR
3.设置中断参数,触发模式,是否屏蔽以及中断
4.相应的中断参数配置,向量表,中断等级,中断函数
5.写中断服务函数,清标志位 EXTI->PR
六、独立看门狗
一般的看门狗功能,必须在计数值减到0之前喂狗,一般总是提前些许喂狗。
1.取消寄存器写保护(向IWDG_KR写入0x5555)
2.设置预分频系数和重装载值 IWDG_PR 、IWDG_RLR
T o u t = ( 4 ∗ 2 p r e r ∗ r l r ) / 40 Tout=(4*2^{prer}*rlr)/40 Tout=(4∗2prer∗rlr)/40
Tout为看门狗溢出时间,单位ms,prer为看门狗预分频值IWDG_PR的值,rlr为看门狗重装载值IWDG_RLR的值。我们必须在Tout时间内进行喂狗才不会产生复位。
3.重载计数值喂狗(向IWDG_KR写入0xAAAA)
4.启动看门狗(向IWDG_KR写入0xCCCC)
5.不停喂狗(向IWDG_KR写入0xAAAA)
七、窗口看门狗
窗口看门狗的计数器的比较值有两个,上限和下限,下限固定为0x40,上限由寄存器设定。在计数器值比上限还大时不可以喂狗,一旦喂狗会产生复位,在计数器值低于0x40时还没有喂狗会产生复位。同时计数器值在0x40时会有一个标志位“提前唤醒中断标志位”被硬件置1,此为用于产生中断,及时喂狗。
1.使能WWDG时钟 RCC_APB1ENR
2.设置窗口值和分频数 WWDG_CFR
3.设置计数器初始值 WWDG_CR
4.开启WWDG中断并分组 WWDG_CFR、NVIC
5.使能看门狗 WWDG_CR
6.清除提前唤醒中断标志位 WWDG_SR
7.使能提前唤醒中断 WWDG_CFR
5.编写中断服务函数 (函数中需要重设WWDG_CFR窗口值并对WWDG_SR的EWIF位清0)
八、PWM输出
PWM处在定时器当中,是对定时器的一种应用方式。定时器计数值从0递增1,在计数值低于阈值(寄存器设定)时输出为低电平,在高于或等于阈值时输出为高电平。通过设置计数器上限设定频率,设定 阈值确定占空比。上述只是原理,具体工作模式可以通过寄存器设定。
重映射表示切换PWM输出通道与IO引脚的对应关系,如没有重映射时CH1对应PA6,部分重映射后CH1对于PB4
1.开启定时器时钟、IO时钟 RCC_APB1ENR、RCC_APB2ENR
2.配置对应IO为复用输出 具体可查看《STM32中文参考手册》第八章 外设的GPIO配置、GPIOx_CRL
(在需要重映射时)
3.开启辅助时钟 RCC_APB2ENR|=1<<0,开启辅助功能IO即AFIO的时钟
4.清除TIMx_REMAP设置 AFIO_MAPR
5.设置重映射 AFIO_MAPR
(重映射结束)
3.设置定时器的ARR和PSC
4.设置定时器通道的PWM模式 TIMz_CCMR1
5.通道预装载使能 TIMx_CCMR1
6.使能通道输出 TIMx_CCER
7.自动重装载使能 TIMx_CR1
6.使能定时器 TIMx_CR1
7.修改占空比 TIMx_CCR2
九、输入捕获
输入捕获在定时器中,在第一次捕获发生时记录计数器的值N1,在第二次捕获发生时记录计数器的值N2,取两者差值,并根据计数器频率计算两次捕获的时间差。
1.开启定时器时钟和IO时钟
2.配置IO为复用输入 具体可查看《STM32中文参考手册》第八章 外设的GPIO配置、GPIOx_CRL
(在需要重映射时)
3.开启辅助时钟 RCC_APB2ENR|=1<<0,开启辅助功能IO即AFIO的时钟
4.清除TIMx_REMAP设置 AFIO_MAPR
5.设置重映射 AFIO_MAPR
(重映射结束)
3.初始化定时器,设置定时器的ARR和PSC
4.设置定时器的输入比较参数(滤波、分频、捕获、映射方式)
5.允许计数器的值保存至寄存器 TIM5->CCER
6.使能捕获和更新中断
7.设置中断分组
8.使能定时器 TIMx_CR1
9.编写中断服务函数
考虑计数器溢出后仍没有捕获的情况
十、FSMC灵活的静态存储控制器
是一种接口,能够与同步/异步存储器的16位PC存储器卡连接,支持包括SRAM、NAND FLASH、NOR FLASH和PSRAM等存储器。FSMC能够与LCD相连是因为它可以为LCD提供所有的控制器信号。
通过对FSMC相应寄存器的配置可以设定一定规律的读写时序,当对FSMC进行操作时,FSMC就能够从硬件层面自动完成读写时序的变化,而用户软件只需要在FSMC的数据地址中写入或者读取相应数据即可。
1.使能FSMC时钟 RCC_AHBENR
2.使能对应IO时钟
3.配置IO工作模式
4.根据硬件连接确定使用的区域块,32例程里使用BANK1,区域4
5.确定区域对应寄存器
6.寄存器清0
7.操作BCR寄存器(片选以及状态控制)
8.操作BTR寄存器(设定读时序)
9.操作BWTR寄存器(设定写时序)
10.使能BANK1,区域4
FSMC_Bank1->BTCR[6]|=1<<0;
十一、RTC实时时钟
RTC时钟位于后备区域,不会被系统复位、电源复位等复位,只要Vbat有电就可以继续运行。在对RTC进行操作时必须经过以下几步:
1.使能电源和备份域时钟
2.取消备份区写保护
3.允许配置
4.设置配置
5.更新配置
6.等待RTC寄存器操作完成
1.使能电源时钟与备份域时钟 RCC->APB1ENR
2.取消备份区写保护 PWR->CR
3.复位备份区域,复位之后必须结束复位
RCC->BDCR|=1<<16; //备份域软复位
RCC->BDCR&=~(1<<16); //备份域软复位结束
4.开启外部低速振荡器 RCC->BDCR
5.外部振荡器就位 RCC->BDCR
while((!(RCC->BDCR&0X02))&&temp<250)//等待外部时钟就绪
{
temp++;
delay_ms(10);
};
if(temp>=250)return 1;//初始化时钟失败
6.使能外部低速振荡器时钟,RTC时钟 RCC->BDCR
7.等待RTC寄存器操作完成 RTC->CRL
8.等待RTC寄存器同步 RTC->CRL
9.设置中断类型 RTC->CRH
10.等待RTC寄存器操作完成 RTC->CRL
11.允许配置RTC RTC->CRL
12.设置RTC的分频、配置RTC时钟
13.更新RTC配置,退出配置模式RTC->CRL
14.等待RTC寄存器操作完成 RTC->CRL
15.使能相应中断
16.设置RTC中断分组
17.编写中断服务函数
十二、待机唤醒实验
32的低功耗模式共有三种,睡眠模式、待机模式、停止模式,其中待机模式功耗最低。
1.使能电源时钟RCC->APB1ENR
2.设置唤醒源(参看下表)PWR->CSR
3.清除唤醒标志PWR->CR
4.设置SLEEP DEEP位,PDDS位,WUF位,执行WFI指令,进入待机模式SCB->SCR、PWR->CR、PWR->CSR
WFI_SET();//执行WFI指令
__asm void WFI_SET(void)
{
WFI;
}
5.编写唤醒源的中断函数(在中断函数中设置两种情况,情况一进入待机,情况二不进入待机)
十三、ADC实验
ADC分为规则通道和注入通道,注入通道可以打断规则的进行,等注入通道ADC转换完成才会继续规则通道转换。ADC的时钟不能超过14MHZ。
1.初始化IO口(时钟与输入配置)RCC
2.ADCx时钟使能 RCC
3.ADCx复位 RCC
4.复位结束 RCC
5.配置ADC参数(分频因子,工作模式,转换模式,扫描模式,转换类型,采样时间等) RCC_CFGR、ADCx_CR1、ADCx_CR2、ADCx_SQR1、ADCx_SMPR2
6.使能ADCx ADCx_CR2
7.使能复位校准 ADCx_CR2
8.等待校准结束 ADCx_CR2
9.开启AD校准 ADCx_CR2
10.等待校准结束 ADCx_CR2
以下为获取ADC值
11.设置转换序列 ADCx_SQR3
12.启动转换通道ADCx_CR2
13.等待转换结束ADCx_SR
14.读取转换结果ADCx_DR
十四、DAC实验
一旦使能DACx通道,相应的GPIO引脚(PA4或者PA5)就会自动与DAC的模拟输出相连(DAC_OUTx)。为了避免寄生的干扰和额外的功耗,引脚PA4或者PA5在之前应当设置成模拟输入(AIN)。不能直接对寄存器DAC_DORx写入数据,任何输出到DAC通道x的数据都必须写入DAC_DHRx寄存器,该数值会在开始DAC时由硬件转移至DAC_DORx。
1.初始化IO口(时钟与输入配置)RCC
2.DACx时钟使能 RCC
3.配置DAC参数(输出通道,输出缓存,触发功能,TRGO,波形发生,屏蔽幅值设置,DMA等) DAC_CR
4.输出初始化为0
5.使能DAC
6.改变输出值
十五、DMA实验
每个通道都有3个事件标志(DMA半传输、 DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。源和目标地址必须按数据传输宽度对齐。
下面是配置DMA通道x的过程(x代表通道号):
- 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将 是数据传输的源或目标。
- 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数 据将从这个地址读出或写入这个地址。
- 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
- 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
- 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外 设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
- 设置DMA_CCRx寄存器的ENABLE位,启动该通道。 一旦启动了DMA通道,它既可响应连到该通道上的外设的DMA请求。 当传输一半的数据后,半传输标志(HTIF)被置1,当设置了允许半传输中断位(HTIE)时,将产生
一个中断请求。在数据传输结束后,传输完成标志(TCIF)被置1,当设置了允许传输完成中断位 (TCIE)时,将产生一个中断请求。
1.开启DMA时钟,并延时5ms等待时钟稳定 RCC
2.设置DMA外设地址和存储器地址 DMA_CHx->CMAR、DMA_CHx->CPAR
3.保存DMA传输数据长度 DMA_CHx->CNDTR
4.DMA配置复位
5.配置DMA工作模式(从存储器读,普通模式,外设地址模式,存储器地址模式,外设数据宽度,存储器数据宽度,优先级,传输模式等)
以下为开启DMA传输内容
6.关闭DMA传输
7.设置DMA传输数据长度 DMA_CHx->CNDTR
8.启动传输
9.等待传输完成 DMA1->IFCR
十六、SPI实验
SPI是4线全双工串行外围设备接口,分别有
MOSI:主发从收
MISO:主收从发
SCLK:时钟
CS:片选
在SPI运行过程中,首先CS选中一个外设,而后SCLK与该外设时钟线连接用于同步时钟。时钟同步后,在一个时钟周期内,主机与从机会完成一个bit的数据交换,注意是交换,即主机给从机1bit,从机给主机1bit。
1.使能SPI对应IO时钟
2.使能SPI时钟(开启IO复用功能)
3.配置IO工作模式
4.配置SPI参数(工作模式,主从机,数据宽度,极性,相位,时钟频率等) SPIx_CR1
5.SPI设备使能 SPIx_CR1
6.启动传输
等待发送区空 SPIx_SR
发送一个byte SPIx_DR
等待接受完一个byte SPIx_SR
返回接收的数据 SPIx_DR
十七、串口IAP
IAP即在应用编程,是用户在程序运行过程中对Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。通常IAP包含两段代码,第一段通过莫种方式接收数据,并对第二段代码更新;第二段代码是用户程序。在芯片上电后首先执行第一段代码,检查是否需要对第二段代码更新,不需要更新则跳过,直接执行第二段代码。第一段代码称Bootloader,第二段代码称APP程序。
1.判断是否接收到数据
2.计算数据长度、保存数据内容
3.判断是否需要更新APP程序,需要则继续,不需要则IAP结束
4.根据数据长度确定新程序的偏移量
5.擦除原有程序,或部分程序
6.写入数据
7.写入完成
8.跳转至新的程序代码入口地址开始执行
十八、NVIC中断管理
NVIC的管理源自COM3内核,故而想要真正会用NVIC必须了解COM3内核,内核提供16个内核中断与240个外部中断,起始地址为0xE000E000,当然有许多寄存器用于控制NVIC。具体的寄存器在末尾列出
1、当系统启动后,先设置优先级组寄存器,即分组
2、如果需要重定位向量表,先把硬fault和NMI服务例程的入口地址写到新表项所在的地址中
3、配置向量表偏移量寄存器,使之指向新的向量表(如果有重定位的话)
4、为该中断建立中断向量,因为向量表可能已经重定位了,保险起见需要先读取向量表偏移量寄存器的值,再根据该中断在表中的位置,计算出服务例程入口地址应写入的表项,再填写之。如果一直使用ROM中的向量表,则无需此步骤。
5、设置中断优先级
6、使能中断
(以上均是针对内核的描述)
STM32支持的中断共84个,16个内核中断,68个外部中断(已经分配给相应的外部设备)每个中断通道都具备自己的中断优先级控制字节 PRI_n(8 位,但在 STM32 中只使用 4 位,高 4 位有效)
1、设置向量表偏移地址
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置向量表偏移量寄存器
}
NVIC_VectTab:基地址,若在RAM中为0x20000000,在CODE中为0x08000000
Offset:偏移量,值为0x0
2、设置分组
1)取出分组数
2)读取AIRCR寄存器原先的值
3)计算需要写入的值
4)写入钥匙
5)写入新数值
3、设置抢占优先级、响应优先级、中断编号
注意优先级不能超过设定的组的范围
4、内核使能中断
5、外设使能中断
十九、USMART属于一种调试工具,工作时通过串口发送命令给单片机,单片机之后调用单片机里面对应的相关函数并执行,同时支持返回结果。在经常需要修改函数入口参数,查看运行效果的情况下应用很方便,无需多次下载代码或使用JLINK调试。
使用资源:定时器、串口通信
说明:使用USMART工具需要把5个文件加入工程,
usmart.c、usmart.h:负责与外部交互
usmart_config.c:由用户添加需要由usmart管理的函数usmart_str.c、usmart_str.h:负责命令解析和参数解析
使用步骤:
1、把USMART包添加到工程,头文件要包含path
2、在usmart_config.c中添加需要调用的用户函数
3、主函数中调用usmart_dev.init()初始化函数
4、通过串口助手发送命令,调用在usmart注册过的函数