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

发布者:谁与争锋1最新更新时间: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     

    

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

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init( GPIOB, &GPIO_InitStructure );

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

  

  GPIO_Write( GPIOC, 0xff0f ); // 11111111-00001111

    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_4

    | GPIO_Pin_5;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init( GPIOC, &GPIO_InitStructure );

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

  GPIO_Write( GPIOD, 0xffff ); // 11111111-11111111  

    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_2;

[1] [2] [3]
关键字:STM32  DMA功能  自动更新  PWM 引用地址:STM32学习日志--使用DMA功能自动更新PWM的输出

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

推荐阅读最新更新时间:2024-11-12 22:25

基于STM32芯片的电源监控器应用方案
电源对电子设备的重要性不言而喻,它是保证系统稳定运行的基础,而保证系统能稳定运行后,又有低功耗的要求。在很多应用场合中都对电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小,所以也很有必要从控制功耗入手,提高设备的续行时间。因此,STM32 有专门的电源管理外设监控电源并管理设备的运行模式,确保系统正常运行,并尽量降低器件的功耗。 电源监控器 STM32芯片主要通过引脚 VDD 从外部获取电源,在它的内部具有电源监控器用于检测 VDD的电压,以实现复位功能及掉电紧急处理功能,保证系统可靠地运行。
[单片机]
基于<font color='red'>STM32</font>芯片的电源监控器应用方案
无线节水滴灌自动控制系统的设计方案
  为实现实时适量的精准滴灌,本文提出了一种基于S3C6410和STM32的无线节水滴灌自动控制系统的设计方案。该方案利用ZigBee无线传感器网络的自组网特点,采用星型网络拓扑结构,实时监控多块田地的土壤温湿度变化,通过反馈传感信号,对滴灌动作进行精准判断和控制。田间试验期间测得土壤湿度最小值为30%,最大值为70%,处于理想范围内。实验结果表明,该方案所设计的系统能够实现滴灌自动控制,且性能良好,具有灵活性强、安全可靠、低功耗、低成本。   0 引言   随着人口的增长和农业的发展,随着全球变暖造成的干旱问题日益严重,世界水资源的需求量越来越大,水资源紧缺已成为全世界人民共同关注的问题。滴灌技术是通过干管、支管和毛管上的滴
[单片机]
无线节水滴灌自动控制系统的设计方案
iar下的stm32启动代码分析
使用的芯片是 STM32F103VET,编译器使用 IAR ARM V5.5 设置头文件查找路径,例如: $PROJ_DIR$.. $PROJ_DIR$......LibrariesCMSISCM3CoreSupport $PROJ_DIR$......LibrariesCMSISCM3DeviceSupportSTSTM32F10x $PROJ_DIR$......LibrariesSTM32F10x_StdPeriph_Driverinc 预定义的symbol 为,HD为high desity 的意思 USE_STDPERIPH_DRIVER STM32F10X_HD 有两个符号是系统默认的,看名字就应该知道什么了
[单片机]
STM32学习笔记:ADC理解
ADC 简介 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。 ADC 主要特性 可配置 12 位、10 位、8 位或 6 位分辨率 ● 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断 ● 单次和连续转换模式 ● 用于自动将通道 0 转换为通道“n”的扫描模式 ● 数据对齐以保持内置数据一致性 ● 可独立设置各通道采样时间 ● 外部触发器选项,可为规则转换和注入转换配置极性
[单片机]
<font color='red'>STM32</font>学习笔记:ADC理解
STM32_DCMI
1:DCMI简介 DCMI是STM32F4芯片自带的一个数字摄像头接口,该接口是一个同步并行接口,能够接受外部8位、10位、12位、14位CMOS摄像头模块发出的高速数据流 可支持的数据格式: YCbCr4:2:2 RGB565逐行视频 压缩数据 (JPEG) 2:DCMI功能概述 数字摄像头接口是一个同步并行接口,可接收 高速(可达 54 MB/s)数据流 。该接口包含多 达 14 条数据线 (D13-D0) 和一条像素时钟线 (PIXCLK)。像素时钟的极性可以编程,因此可 以在像素时钟的上升沿或下降沿捕获数据。 这些数据被放到 32 位数据寄存器 (DCMI_DR) 中,然后通过通用 DMA 进行传输。 图
[单片机]
STM32_DCMI
如何实现一种基于STM32单片机的智能浴室水温调控仪设计?
一、功能简介 本项目使用Proteus8.12仿真STM32单片机控制器,使用LCD1602、DS18B20、继电器加热、电机模块等。 系统运行后,LCD1602显示DS18B20采集温度值、温度上限阈值。开启加水,一段时间后开启加热,当水位到达后停止注水,继续加热到设定温度,可通过K1、K2键对温度上限设置,若检测温度大于或等于上限,关闭加热装置;若温度低于上限,开启加热装置; 主要功能如下: (1)水温,水位实时检测; (2)水温设定,超限关闭加热; (3)继电器控制加热、注水; (4)LCD1602液晶显示。 二、软件设计 //系统参数初始化 void sys_parm_init(void) { //初始自动模式
[单片机]
如何实现一种基于<font color='red'>STM32</font>单片机的智能浴室水温调控仪设计?
stm32利用oled显示屏与按键进行PID参数调节实现人机交互
上一个学期在学校做四轮车利用PID实现直线走,在调试过程中,我之前是每改一个参数就下载程序进控制板进行调试,观察车是否偏移来确定pid参数,但是后来我发现这样的效率很慢,经别人提醒后,我自己做了一个小小的人机交互界面,来显示pid的参数以及对pid参数进行调整。 以下是显示效果: 接着我在附上主要代码: // 功能描述 : OLED 7针SPI接口演示例程(STM32F103系列) // 说明: // ---------------------------------------------------------------- // GND 电源地 // VCC 3.
[单片机]
<font color='red'>stm32</font>利用oled显示屏与按键进行PID参数调节实现人机交互
基于ISL8201M电源PWM控制电路设计
  Intersil 公司的ISL8201M是 20V 10A输出电流的可变输出降压电源,是高性能PWM控制器,开关频率600kHz,它集成了功率MOSFET,电感和所有的无源元件,可以实现完整的 DC/DC电源解决方案。 ISL8201M输入电压从1V到20V, 采用单个分压电阻可实现输出电压从0.6V到5V, 峰值电流达17A,效率高达95%,可用在服务器,工业设备,POL稳压,电信和数据通信设备以及其它通用降压DC/DC转换器。本文介绍了 ISL8201M的主要特性,方框图,典型应用电路和ISL8201MEVAL1Z 评估板电路图与材料清单。    ISL8201M典型应用电路设计    ISL8201M主要特性:  
[电源管理]
基于ISL8201M电源<font color='red'>PWM</font>控制电路设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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