最近做了个SD卡BOOTLOARDER程序。在测试过程中,想到可以利用板子的LED灯进行萤火虫灯的制作,通过BOOTLOARDER将APP文件下载到板子里面查看LED灯的闪烁。可能是因为太过自信,这么个小程序能搞不定,所以并没有仔细阅读DATASHEET,导致最终费了半天时间才查出原因。
此为引子,便有了这篇文章。
我的板子LED灯引脚为PB5,引脚功能为:
该引脚TIM3_CH2为REMAP功能,引脚配置如下:
[cpp] view plain copy print?
GPIO_InitTypeDef GPIO_InitStructure;
/*配置时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE); //使能GPIOB以及复用功能时钟
/*配置PB5引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5复用为TIM3的通道2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*TIM3局部复用功能开启 在TIM3的局部复用开启时,PB5会被复用为TIM3_CH2*/
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE);
在定时器重映射说明中查到TIM3_CH2在PB5中是部分重映射,所以使用GPIO_PartialRemap_TIM3:
[cpp] view plain copy print?
/*-------------------------------------------------------------------
TIM3CLK=72MHz 预分频系数Prescaler=2 经过分频 定时器时钟为24MHz
根据公式 通道输出占空比=TIM3_CCR2/(TIM_Period+1),可以得到TIM_Pulse的计数值
捕获/比较寄存器2 TIM3_CCR2= CCR2_Val
-------------------------------------------------------------------*/
TIM3_TimeBaseStructure.TIM_Prescaler = 2; //预分频器TIM3_PSC=3
TIM3_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式 TIM3_CR1[4]=0
TIM3_TimeBaseStructure.TIM_Period =24000; //自动重装载寄存器TIM3_APR 确定频率为1KHz
TIM3_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子 TIM3_CR1[9:8]=00
TIM3_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseStructure); //写TIM3各寄存器参数
TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时,
//一旦TIMx_CNT
TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输入/捕获2输出允许 OC2信号输出到对应的输出引脚PB5
TIM3_OCInitStructure.TIM_Pulse = CCR2_Val; //确定占空比,这个值决定了有效电平的时间。
TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性 低电平有效 TIM3_CCER[5]=1;
TIM_OC2Init(TIM3, &TIM3_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3,ENABLE); //启动定时器3 TIM3_CR1[0]=1;
至此,各配置结束,以下只要配置系统时钟,使其在一定时间间隔中断,改变占空比。
关键字:STM32 GPIO配置 PWM波输出
引用地址:
STM32 重新理解GPIO配置以及配置PWM波输出
推荐阅读最新更新时间:2024-03-16 15:39
Python 和OpenMV如何玩转 STM32 MCU
如今网络边缘侧的机器学习现状如何?哪些工具可以帮助工程师收集数据并执行推断运算?在哪里可以找到ST MEMS,它们对现实生活中的产品有哪些影响?本文是我们即将举行的STM32全国研讨会系列的第二篇专题文章。在第14届STM32全国研讨会上,我们将通过应用演示、产品展示以及工程师与观众互动回答问题的方式,来与蝶粉社区近距离交流。在STM32全国研讨会专题系列报道第一部分我们着重介绍了云连接方面的用例,如一款新的智能门铃功能演示,还介绍了工业和数据安全相关应用。 今天,我们将重点探讨人工智能、计算以及感知技术。 人工智能与计算 Qeexo 和STM32Cube.AI 当今边缘机器学习解决方案的种类越来越多,本届STM32全国
[嵌入式]
stm32中的数据类型定义
STM32F10X.H 1 #include core_cm3.h 2 #include system_stm32f10x.h 3 #include stdint.h 4 5 /** @addtogroup Exported_types 6 * @{ 7 */ 8 9 /*! STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ 10 typedef int32_t s32; 11 typedef int16_t s16; 12 typedef int8_t s8; 13 14 typed
[单片机]
STM32 获取寄存器的地址
如果需要使用TX1的DMA传输,就会涉及到配置DMA的外设地址。在这里,外设地址应该是USART1的DR寄存器的地址。可是如何获取该寄存器的地址呢? 现在实测了3种方式,都可以实现。 方法1: 直接查询手册中寄存器映像(map),USART1的DR地址为0x40013804 方法2: 手册中查看,DR寄存器的偏移地址为0X04,那么USART1的DR地址可以写成(USART1_BASE + 0X04)。 其中USART1_BASE在stm32f10xb.h中有定义 #define USART1_BASE (APB2PERIPH_BASE + 0x00003800U) 方法3: 如果我们要修
[单片机]
HC-SR501热释电红外传感器驱动(STM32)
一、前期准备 单片机:STM32F103ZET6 开发环境:MDK5.14 库函数:标准库V3.5 HC-SR501热释电红外传感器模块:淘宝有售 二、实验效果 三、驱动原理 这个模块比较简单,当有人靠近时候其IO输出3.3V,STM32可以直接采集。 需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。 四、驱动代码 HC_SR501.h #ifndef __HC_SR501_H__ #define __HC_SR501_H__ #include stm32f10x.h #include gpio.h #include delay.h #define HC_SR501 PA
[单片机]
STM32高级开发(12)-在GCC中使用printf打印串口数据
在大家使用keil或是iar开发stm32等arm芯片的时候,想来最不陌生的就是使用print通过串口输出一些数据,用来调试或是其他作用。但是要明确的是由于keil iar gcc 他们使用的标准C语言库虽然都遵循一个标准,但他们底层的函数实现方式都是不同的,那么在GCC中我们能否像在keil中一样重映射print的输出流到串口上呢?答案是肯定的。 keil中的重映射方式及原理 /* * libc_printf.c * * Created on: Dec 26, 2015 * Author: Yang * * 使用标准C库时,重映射printf等输出函数的文件 * 添加在工程内即可生效(切勿选择semi
[单片机]
基于MDK编译器 STM32与12864液晶显示程序 和电路连接
里附上的是主程序部分和电路连接 这里用的12864液晶是5v的,电路链接部分 RS PE2 RW PE4 EN PE6 15口PSB串并 PE3 #include stm32f10x.h GPIO_InitTypeDef GPIO_InitStructure; #define RS_SET GPIO_SetBits(GPIOE, GPIO_Pin_2) #define RS_CLR GPIO_ResetBits(GPIOE, GPIO_Pin_2) #define RW_SET GPIO_SetBits(GPIOE, GPIO_Pin_4) #define RW_CLR GPIO_Re
[单片机]
玩转STM32(11)CPU的心跳历程
前面说CPU怎么样才有脉搏,也就是给CPU装了一个心脏,这样这个由泥沙组成的CPU才能开始拥有像生命的力量了。在前文后面,提到了使用25MHz晶振作为外部的频率来源,但是我们的目标是让CPU工作在168MHz的频率,这样才可以让CPU工作得更快,运行代码更快,效率更高。当然,如果你想让CPU工作在25MHz也是可以的,只是有点不值得,用这么贵的硬件,运行这么低的频率。要想快,就得提高CPU运行的频率,那么怎么样才可以把25MHz的频率转换为168MHz的频率呢?可以看到168M是比25M频率高很多,显然要使用到倍频电路,也要使用到分频电路。比如把25M按25分频系数来分频,那么得到频率就是1M,然后再使用倍频电路,比如使用336作
[单片机]
STM32外部中断执行过程
一、MCU中断程序执行过程 以MCU裸机程序框架为例,MCU 的主函数是个死循环: 主函数: main(void) { While(1) { //主程序 } } 如果没有中断或异常产生会一直在while(1)里执行主程序代码。当中断产生后,当前执行的任务会被打断,程序跳转到中断处理函数执行,执行完会返回之前的主程序断点处继续执行。 中断处理函数: void IRQ_handler(void) { //中断处理程序 //清除中断标志,否则会不停的进入中断处理程序。 } 在中断处理函数中不要做复杂费时的事情,中断内做的事情尽可能少。 二、中断使用实例 STM32的IO都可以配置成外部中断,但不是同时都可以配成外部中断。需要遵循如下
[单片机]