历史上的今天
返回首页

历史上的今天

今天是:2024年08月23日(星期五)

正在发生

2019年08月23日 | STM32学习日志--使用DMA功能自动更新PWM的输出

2019-08-23 来源:eefocus

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

 编译环境: 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;

推荐阅读

史海拾趣

Baneasa SA公司的发展小趣事

面对日益增长的市场需求,Baneasa SA意识到必须提升产能以满足客户的需求。于是,公司投入大量资金对生产线进行升级改造,引进了先进的生产设备和技术。这些举措使得Baneasa SA的产能得到了大幅提升,同时也保证了产品质量的稳定性和可靠性。

功得(CONQUER)公司的发展小趣事

在市场竞争日益激烈的环境下,功得公司意识到仅仅依靠创新是不够的,还需要有高品质的产品来赢得客户的信任。因此,公司开始注重产品质量管理,建立了完善的质量控制体系。功得公司严格把控原材料采购、生产工艺和成品检验等环节,确保每一件产品都符合高标准的质量要求。这种对品质的执着追求,使得功得公司的产品在市场上赢得了良好的口碑,品牌知名度也逐渐提升。

Custom LeatherCraft Manufacturing Co Inc公司的发展小趣事

CLC起源于一个对高质量手工皮革制品有着无限热情的小型工坊。创始人是一位经验丰富的皮革工匠,他看到了电子工程师和户外工作者对耐用、实用的工具包的需求。于是,他开始了自己的创业之路,以“定制皮革工艺”为核心理念,承诺每一件产品都经过精心制作和严格质检。凭借这份承诺和精湛的技艺,CLC逐渐在市场中赢得了口碑。

Genesis Microchip公司的发展小趣事

随着战后的经济复苏和科技的快速发展,GI开始积极寻求业务多元化和国际化的发展道路。公司不仅继续深耕电子技术领域,还逐渐涉足通信、计算机等多个领域,推出了包括通信设备、计算机硬件在内的多款新产品。同时,GI也积极开拓海外市场,通过设立分支机构、与当地企业合作等方式,成功将产品销往全球多个国家和地区。这一阶段的成功,使GI成为了名副其实的跨国电子巨头。

Coherent Inc公司的发展小趣事

Coherent Inc.在激光技术领域取得了多项技术突破,如固态激光器、半导体激光器、气体激光器、飞秒激光器等。这些技术的突破不仅提升了公司的产品性能和质量,也使其在行业中处于领先地位。公司的产品广泛应用于科学研究、工业制造、医疗诊断和治疗、通信等领域,为这些领域的发展做出了重要贡献。

BURGESS公司的发展小趣事

BURGESS公司于1975年3月13日在伦敦正式成立,这标志着它在游艇经纪行业的起点。创立之初,BURGESS就凭借其专业的知识和敏锐的市场洞察力,在短短四年内成功进驻摩纳哥这一游艇行业的重镇。更令人瞩目的是,在同一年,BURGESS成功售出了当时世界上最大的游艇,这一成就不仅彰显了其卓越的实力,也为其在行业内赢得了极高的声誉。

问答坊 | AI 解惑

电容器安装注意事项

1 安装电容器时,每台电容器的接线最好采用单独的软线与母线相连,不要采用硬母线连接,以防止装配应力造成电容器套管损坏,破坏密封而引起的漏油。 2 电容器回路中的任何不良接触,均可能引起高频振荡电弧,使电容器的工作电场强度增大和发热 ...…

查看全部问答>

PICC资料

PICC编程基础…

查看全部问答>

74系列资料

74系列资料 晚上补充附件…

查看全部问答>

关于STM32,TI,NXP的ARM Cortex-m3学习板申请体会

这三家的都申请过,有一些想法 ST最大方,板子,光盘,连接线一应俱全。 并且ST搞过好几次免费申请活动,每次免费送的套件数量还比较大。 拿到套件后就能直接上手练习了。 TI其次,申请的TI套件,使用手册里明明说的是有两块板子,可是我只收到 ...…

查看全部问答>

evc检测远程端口是否开放

代码如下:         SOCKET Sock = INVALID_SOCKET;     // Datagram window socket           SOCKADDR_IN source_sin;          &n ...…

查看全部问答>

来分析一下crc的误码率

在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,而CRC32的概率则是1/2^32,那已经是非常小了,所以一般在数据不多的情况下用CRC16校验就可以了,而在整个文件的校验中一般用CRC32校验。 如何理解,是否要用概率论的模型去解释? ...…

查看全部问答>

正弦曲线迷茫中,大家帮帮忙

之前关于EVC下图形编程画二维曲线问题已经有了进展,现在刚画出简单的二维曲线,就是随机折线那样的,主要通过两个随机数nRandomX = rand() % 10;nRandomY = rand() % 10; 主要代码如下: BOOL CDraw2DGraphDlg::OnInitDialog() {     ...…

查看全部问答>

C8051F温度计电源问题解决了

我的解决方法是用1117-3.3,相信这个芯片大家都有。它的引脚和BL相同,但板上封装是sot89,我手头只有sot223,我把1脚和3脚向里折了一下,注意不要折断,然后再焊上就可以了。这时板子上D2不要焊,L1用焊锡直接连上就可以了。 现在板子的电压是3.3V ...…

查看全部问答>

MSP430 入门及常见问题解答

Ver 0.1 - Jeffrey1.MSP430 入门2.如何为我的应用选择最合适的MSP430 芯片?3.与MSP430 的引导加载程序通信的开发工具4.MSP430 需配合何种晶振工作?5.使用哪款MSP430 编程器可以用来烧断JTAG 熔丝?6.要实现MSP430 编程,应如何连接JTAG?7 ...…

查看全部问答>

晒WEBENCH设计的过程+DIY飞利浦HUE供电电源

1设计要求 2设计方案 3选便宜的看看,效率和下边那个是什么 4原理图 在选择方案时会出现相关LED厂家产品的选择很方便,可以参考修改设计,找到更加合适方案 …

查看全部问答>