STM32学习之编写定时器3产生4路PWM

看了stm32定时器完爆51后,看了原子的定时器3产生一路PWM ,于是就想着写一个定时器3产生4路PWM的程序。搞了一个晚上,该了又改,MDK中仿真后,总是不出波形,以为自己代码有问题,最后用示波器一看,what!!有波形啊,坑啊,这软件有bug啊,一路PWM时,仿真还挺正常,换成4路后,就完蛋了,不出波形了。额,软件不可靠啊,下面看代码:

STM32学习之PWM程序编程总结

PWM:脉冲宽度调节。 参数: 1.频率:每秒信号重高电平到低电平回到高电平的次数。 2.占空比:搞电平持续的时间和一个完整的PWM信号周期持续的时间之比。 3.周期:一个完整PWM信号持续的时间。   步骤:   1.设置相应的时钟;通用定时器TIMX是由APB1这条总线提供时钟,而GPIO这些端口是由APB2这条总线提供时钟。注意: 如果需要对PWM的输出进行重映射的话,还需开启引脚复用时钟AFIO。 2设置相应的PWM输出引脚;对应的输出IO口应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映射的话,则需要用GPIO_PINRemapConfig()函数进行设置。 3设置TIMx定时器的相关寄存器。 4设置PWM相关寄存器,首先设置PWM模式(默认情况下PWM是冻结的),然后设置占空比,再设置输出比较极性:当设置为High时,输出信号不反相,当设 置为Low时,输出信号反相后再输出。最重要的是要使能TiMX的输出状态和使能TIMX的PWM输出使能。相关设置完成后,就 可以通过TIMx_Cmd()来打开TIMx定时器,从而的到PWM输出了  

STM32定时器学习

STM32F103系列的单片机一共有11个定时器,其中2个高级定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统滴答定时器。前8个定时器可分为3组:TIM1和TIM8是高级定时器,TIM2-TIM5是通用定时器,TIM6和TIM7是基本定时器,这8个定时器都是16位的,他们的计数器的类型除了基本定时器TIM6和TIM7都支持向上,向下,向上/向下(中央对齐模式)这3种计数模式。 主要说说中央对齐模式:技术器从0开始向上计数,计数到自动重装载寄存器的值时,产生一个计数器溢出事件,然后再向下计数,计数到了1以后还会再产生一个溢出事件;然后再重0开始重新计数,如此反复。 定时器功能: 1.基本定时器:只有计数功能; 2.通用定时器,除了基本定时器的功能,还具有测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM). 3.高级寄存器除了具有以上两种寄存器的功能外,还具有控制直流电动机所有的功能。

STM32学习笔记之使用外部IO口引脚中断总结

STM32F103系列的单片机的每个IO口都可以作为外部中断源的输入。 使用外部IO口引脚中断的基本步骤: IO口初始化。 设置好相应的时钟。 设置相应的中断。 把相应的IO口设置为中断线路并初始化配置。 编写中断服务函数。 STM32单片机的中断和事件的区别:从外部激励信号来看,中断和事件的产生源都可以是一样的,之所以分为两部分,是由于中断需要CPU参与,需要软件的中断服务函数才能完成中断后产生相应的结果;但是事件不是,事件是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件并且产生相应的结果,当然相应的联动部件需要设置好,比如DMA操作,AD转换等;举例:比如使用传统的中断通道,需要外部I/O引脚触发AD转换,来测量物品的重量;如果使用传统的中断通道,需要外部I/O引脚触发产生外部中断,在外部中断服务程序启动AD转换,AD转换完成才能在相应的显示设备显示结果,这是用中断的方式。再看一下使用事件通道的工作原理:I/O引脚触发产生事件,然后脉冲发生器产生一个脉冲信号触发AD转换,AD转换完成后就可以将相应的结果显示出来;相比之下,后者不需要软件参与直接就可以触发AD转换,并且响应速度也要比中断方式快很多。 总结一下:可以这样简单的认为,事件机制提供了一个完全有硬件自动完成触发到产生结果的这么一个通道,不需要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),事件是利用硬件来提升CPU芯片处理事件能力的一个有效方法。

STM32学习笔记之库函数开发小结

         所有外设都有以下几类寄存器: 控制寄存器xxx_CR(Control/Configuration Register):这类寄存器是用来配置、控制相应外设的工作方式的。比如GPIOx_CRL、GPIOx_CRH、AFIO_EXTICR1~AFIO_EXTICR4,串口的USART_CR1~USART_CR3等。 数据寄存器xxx_DR(Data Register):这类寄存器主要是存储了外设进行输入输出的数据。如GPIOx_IDR、GPIOx_ODR、USART_CR3等。 状态寄存器xxx_SR(Status Register):这类寄存器主要存储了当前外设的运行状态,主要为一些标志位。如USART_SR、ADR_SR等。 初始化 使用ST库对外设进行初始化,一般有以下几个步骤: 1.定义一个xxx_InitTypeDef类型的初始化结构体。 2.根据使用需求,向这些初始化结构体成员写入特定的控制参数。 3.填充好结构体后,把这个结构体作为输入参数调用相应的外设库函数xxx_Init(),从而实现先寄存器写入控制参数,并配置好外设。 数据输入与输出 对于外设的使用,一般涉及其输入和输出数据,ST官方库有一类专门为此应用而生的函数。如GPIO的输入输出函数:GPIO_ReadOutputDataBit(),GPIO_ReadIntputData(),GPIO_SetBits();有USART的收发数据函数:USART_ReceiveData()、USART_SendData()。 这些函数控制相应外设数据寄存DR的内容,达到控制输入输出的目的。使用这些函数的方法也是类似的: 1.通过输入参数,向函数指定要使用的是什么外设,如用(GPIOA,GPIO_PIN_5)选定PA5进行控制,用(USART1)来指定使用使用串口1外设。 2.若要先外输出数据,则调用Output或者Send函数,把将要输出的数据变量作为函数的输入参数。 3.若为接收外部数据,则调用Read或Receive函数,读取函数的返回值来得到外部输入数据。 状态位、标志位: 1.事件 当外设完成了某些工作或出现某些状态的时候,会触发一些事件,这些事件会在状态寄存器SR中,以不同的寄存器来记录。这些寄存器称为相应的事件标志位。 如串口发送完成后,会在USART_SR寄存器中的位6置1,作为发送完成的事件标志。若发送完寄存器为空,则会在相应地在位7置1,作为发送寄存器已空的事件标志,如果我们不停地查询这个标志位,就可以得知串口的发送状态。 不停地查询标志位,会耗费内核宝贵的资源,ST以中断的方式解决这个问题,大部分事件都可以被配置中断。如把串口发送完成事件配置为可触发中断后,当串口发送完成时,外设不仅在USART_SR寄存器中记录事件,还会触发串口中断,从而可以进入相应的中断服务函数,针对不同的事件进行具体的处理,而内核也省去了不停查询标志位的工作。 2.标志位的检查与清除 对标志位进行检查的库函数,一般命名为xxx_GetFlagStatus()或xxx_Get ITStatus(),功能分别为获取事件标志位状态和中断标志位状态。如读取串口标志位的函数USART_GetFlagStatus();EXIT的获取EXIT线状态的函数EXIT_GetFlagStaus()。 既然有标志位检查,自然也有清除标志位功能的函数。对标志位进行清除的ST库函数,一般命名为xxx_ClearFlag()或xxx_ClearITPendingBit()函数,功能分别为清除事件标志位和清除挂起的中断标志位。比如串口的USART_ClearFlag(),EXTI的USART_ClearITPendingBit()。 对这些标志位进行操作的函数具有统一的方法。输入参数就是要检查的标志,如串口的发送完成标志USART_FLAG_TC、接受寄存器非空标志位USART_FLAG_RXNE.。检查函数是否具有返回值,返回值是SET或RESET,表示这个标志位被置位或没有被置位。而标志位清除函数就没有返回值了,调用函数后就直接把相应的标志位进行清除。

MDK升级后,J-LINK不能使用的解决方法

以前用的MDK版本是412。现在更新后使用的是MDK5。今天打算用J-link来调试来着,简单几个配置后出现下面信息:“The connected emulator is a J-Link clone……“,之后立即闪退。悲剧了,我的盗版J-Link被检查出来了。网上找了一下,发现这个方法最有效:把现在的Keil\ARM\Segger目录下的两个dll文件替换成以前能用的老版本对应文件。 这样就行了。