STM32学习日志--使用DMA功能自动更新PWM的输出

2019-08-23来源: eefocus关键字:STM32  DMA功能  自动更新  PWM

/*******************************************************************************

 编译环境: EWARM V5.30

 硬件环境: DZY2.PCB

 STM32 FW:   V3.0.0

 作者 : szlihongtao

 ******************************************************************************

 REV  : V1.00

 DATE : 2011-04-18

 NOTE :  

 *******************************************************************************/

#include "stm32f10x.h"

#include "stm32_m.h"

#include "dzy.h"   

#include "myRCC.h"   

//******************************************************************************

#define TIM1_CCR3_Address    0x40012C3C


bit f_tb;    // 基本定时标志

bit f_100ms, f_1000ms;

INT16U cnt_test;  // 计数器,仅供软件调试使用

float clk_sys;   // 仅供软件调试使用

#if 1

uint16_t SRC_Buffer[ ] =

{ 72 * 5 };   // 由于载波频率取20kHZ,所以最大脉冲宽度不要超50us,即常数不要超过72*50

#else

uint16_t SRC_Buffer[]=

{ 72*2,72*5,72*10,72*20,72*40,72*10}; // 由于载波频率取20kHZ,所以最大脉冲宽度不要超50us,即常数不要超过72*50

#endif

//******************************************************************************

// 延时程序,单位为*1ms

//******************************************************************************

void delayms( INT16U cnt )

{

//#define   CONST_1MS  7333   // 72MhZ

//#define   CONST_1MS 3588   // 32MhZ

#define   CONST_1MS (105*FCLK) 

  

  INT16U i;

  

  __no_operation( );

  while ( cnt-- )

    for ( i = 0; i < CONST_1MS; i++ )

      ;

}

//******************************************************************************

// pcb上的指示灯

//******************************************************************************

static void led_toggle( void )

{

  GPIOC->ODR ^= GPIO_Pin_7;  // led2 toogle

  GPIOC->ODR ^= GPIO_Pin_6;  // led3 toogle

}

//******************************************************************************

// 时钟设置初始化

//******************************************************************************

static void RCC_Configuration( void )

{

  ErrorStatus HSEStartUpStatus;

  /*

   RCC_AdjustHSICalibrationValue 调整内部高速晶振(HSI)校准值

   RCC_ITConfig 使能或者失能指定的RCC中断

   RCC_ClearFlag 清除RCC的复位标志位

   RCC_GetITStatus 检查指定的RCC中断发生与否

   RCC_ClearITPendingBit 清除RCC的中断待处理位

   */

  /* RCC system reset(for debug purpose) */

  // 时钟系统复位

  RCC_DeInit( );

  

  // 使能外部的8M晶振

  // 设置外部高速晶振(HSE)

  /* Enable HSE */

  RCC_HSEConfig( RCC_HSE_ON );

  

  // 使能或者失能内部高速晶振(HSI)

  RCC_HSICmd( DISABLE );

  

  // 等待HSE起振

  // 该函数将等待直到HSE就绪,或者在超时的情况下退出

  /* Wait till HSE is ready */

  HSEStartUpStatus = RCC_WaitForHSEStartUp( );

  

  if ( HSEStartUpStatus == SUCCESS )

  {

    // 设置AHB时钟(HCLK)

    RCC_HCLKConfig( RCC_HCLK_Div_ ); // 36 MHz

      

    // 设置低速AHB时钟(PCLK1)

    RCC_PCLK1Config( RCC_PCLK1_Div_ ); // 2.25 MHz

      

    // 设置高速AHB时钟(PCLK2)

    RCC_PCLK2Config( RCC_PCLK2_Div_ ); // 2.25 MHz

      

    /* ADCCLK = PCLK2/8 */

    // 设置ADC时钟(ADCCLK)

    RCC_ADCCLKConfig( RCC_ADC_DIV_ ); // 0.281Mhz

      

    // 设置USB时钟(USBCLK)

    // USB时钟 = PLL时钟除以1.5

    //RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

    

    // 设置外部低速晶振(LSE)

    RCC_LSEConfig( RCC_LSE_OFF );

    

    // 使能或者失能内部低速晶振(LSI)

    // LSE晶振OFF

    RCC_LSICmd( DISABLE );

    

    // 设置RTC时钟(RTCCLK)

    // 选择HSE时钟频率除以128作为RTC时钟

    //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);

    

    // 使能或者失能RTC时钟

    // RTC时钟的新状态

    RCC_RTCCLKCmd( DISABLE );

    

    /* Flash 2 wait state */

    FLASH_SetLatency( FLASH_Latency_2 );

    

    /* Enable Prefetch Buffer */

    FLASH_PrefetchBufferCmd( FLASH_PrefetchBuffer_Enable );

    

    /* PLLCLK = 8MHz * 9 = 72 MHz */

    // 设置PLL时钟源及倍频系数

    RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_ );

    

    /* Enable PLL */

    // 使能或者失能PLL

    RCC_PLLCmd( ENABLE );

    

    /* Wait till PLL is ready */

    // 检查指定的RCC标志位设置与否

    while ( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )

    {

    }

    

    /* Select PLL as system clock source */

    // 设置系统时钟(SYSCLK)

    RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );

    

    /* Wait till PLL is used as system clock source */

    // 返回用作系统时钟的时钟源

    while ( RCC_GetSYSCLKSource( ) != 0x08 )

    {

    }

  }

  

  // 使能或者失能AHB外设时钟

  RCC_AHBPeriphClockCmd(

    RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2 | RCC_AHBPeriph_SRAM

      | RCC_AHBPeriph_FLITF | RCC_AHBPeriph_CRC | RCC_AHBPeriph_FSMC

      | RCC_AHBPeriph_SDIO, DISABLE );

  // 使能或者失能APB1外设时钟

  RCC_APB1PeriphClockCmd( RCC_APB1Periph_ALL, DISABLE );

  

  // 强制或者释放高速APB(APB2)外设复位

  RCC_APB2PeriphResetCmd( RCC_APB2Periph_ALL, ENABLE );

  // 退出复位状态

  RCC_APB2PeriphResetCmd( RCC_APB2Periph_ALL, DISABLE );

  

  // 强制或者释放低速APB(APB1)外设复位

  RCC_APB1PeriphResetCmd( RCC_APB1Periph_ALL, ENABLE );

  

  // 强制或者释放后备域复位

  RCC_BackupResetCmd( ENABLE );

  

  // 使能或者失能时钟安全系统

  RCC_ClockSecuritySystemCmd( DISABLE );

}

//******************************************************************************

// NVIC设置

//******************************************************************************

void NVIC_Configuration( void )

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  /* Configure one bit for preemption priority */

  NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1 );

  

  NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  //NVIC_Init(&NVIC_InitStructure);

  

  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  //NVIC_Init(&NVIC_InitStructure);

  

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init( &NVIC_InitStructure );

}

//******************************************************************************

// SysTick设置初始化

//******************************************************************************

static void SysTick_Config1( void )

{

#if 1

#define SystemFreq  (FCLK*1000000.0)    // 单位为Hz

#define TB_SysTick  (TIME_TB*1000)  // 单位为uS,与示波器实测一致

  

  static INT32U ticks;

  

  ticks = ( INT32U )( ( TB_SysTick / 1000000.0 ) * SystemFreq );

  SysTick_Config( ticks );

#endif 

}

//******************************************************************************

// GPIO设置

//******************************************************************************

static void GPIO_Configuration( void )

{

  GPIO_InitTypeDef GPIO_InitStructure;

  

  RCC_APB2PeriphClockCmd(

    RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC

      | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE );

  

//------------------------------------------------------------------------------

  GPIO_Write( GPIOA, 0xffff );

  

  /* GPIOA Configuration: Channel 3 as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init( GPIOA, &GPIO_InitStructure );

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  // GPIO_Init(GPIOA, &GPIO_InitStructure);

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init( GPIOA, &GPIO_InitStructure );

//------------------------------------------------------------------------------

  

  GPIO_Write( GPIOB, 0xffff ); // 11111101-11111111     

    

/*

[1] [2] [3]

关键字:STM32  DMA功能  自动更新  PWM

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic472317.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32控制SG90舵机
下一篇:CubeMX Stm32F407生成一定周期的占空比不同的方波DMA+定时器

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8S学习01——SPI&IIC

1、温习IIC总线协议1)I2C 总线的一些特征1> 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL2> 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地址 主机可以作为主机发送器或主机接收器3> 它是一个真正的多主机总线 如果两个或更多主机同时初始化数据传输可以通过冲突检测和仲裁,防止数据被破坏4> 串行的 8 位双向数据传输位速率在标准模式下可达 100kbit/s 快速模式下可达 400kbit/s 高速模式下可达 3.4Mbit/s5> 片上的滤波器可以滤去总线数据线上的毛刺波 保证数据完整6> 连接到相同总线的 IC 数量只受到总线的
发表于 2019-09-16

STM8S学习02——ADC

一、ADC_转换模式1、ADC支持5种转换模式:单次模式,连续模式,带缓存的连续模式,单次扫描模式,连续扫描模式。2、单次模式在单次转换模式中, ADC仅在由ADC_CSR寄存器的CH[3:0]选定的通道上完成一次转换。该模式是在当CONT位为0时通过置位ADC_CR1 寄存器的ADON位来启动的。一旦转换完成,转换后的数据存储在ADC_DR寄存器中, EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断。3、连续和带缓存的连续模式在连续转换模式中,ADC在完成一次转换后就立刻开始下一次的转换。当CONT位被置位时即将ADC设为连续模式,该模式是通过置位ADC_CR1寄存器的 ADON 位来启动的。(1)如果缓冲功能没有
发表于 2019-09-16

STM8S学习05——EEPROM读写操作C语言程序

/*这两天项目开发中,用到STM8的EEPROM功能,几个数据要掉电保存,在网上也查了一下EEPROM操作,发现网上出现的问题主要有两点:1、EEPROM读写不成功;2、EEPROM读写的时间太长;看了一下ST的库函数,自己测试了一下,没有发现什么问题,比较正常;在读写EEPROM期间,也有动态扫描LED数码管,没有发现数码管有闪烁。操作过程中:1、开发平台:STM8S105K4T6 IAR6.3 ST库版本 V2.1.02、操作EEPROM,使用到的库函数:  FLASH_Unlock(FLASH_MEMTYPE_DATA);  while (FLASH_GetFlagSt
发表于 2019-09-16

STM8S学习04——网关学习

连接到另一个网络的“关口”。也就是网络关卡。网关(Gateway)又称网间连接器、协议转换器。默认网关在网络层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连。说明:由于历史的原因,许多有关TCP/IP的文献曾经把网络层使用的路由器称为网关,在今天很多局域网采用都是路由来接入网络,因此通常指的网关就是路由器的IP!在OSI中,网关有两种:一种是面向连接的网关,一种是无连接的网关。当两个子网之间有一定距离时,往往将一个网关分成两半,中间用一条链路连接起来,我们称之为半网关。(OSI是Open Syst
发表于 2019-09-16

STM8S学习03——寄存器版本的一些程序

();while(1){GPIO_WriteReverse(GPIOG, GPIO_PIN_0);Delay(50000);}}void Delay(unsigned int t){while(t--);}#ifdef USE_FULL_ASSERT;void assert_failed(u8 *file, u32 line){while(1){}}#endif/* stm8s_it.c 中的代码如下: *//*...INTERRUPT_HANDLER(CLK_IRQHandler,2){//清除中断标志位CLK_ClearITPendingBit(CLK_IT_SWIF);//完成切换CLK_ClockSwitchCmd(ENABLE
发表于 2019-09-16

解决stm8会卡在串口中断的问题

原因串口进入了OR(过载错误)中断解决方法必须添加if(UART1_GetITStatus(UART1_IT_RXNE )!= RESET),若不添加,会导致UART1->DR被异常读取,不断进入中断处理函数若UART的RXNE状态位已经被置1,串口又收到数据,将会进入OR(过载错误)中断,需要先读取UART_SR,再读取UART_DR才可把OR位中断状态清零,调用UART1_GetITStatus(UART1_IT_RXNE )即是读取UART_SR在调用UART1_ReceiveData8()读取了UART1->DR后即可清除中断UART1_IT_RXNE标志位INTERRUPT_HANDLER
发表于 2019-09-16

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved