用STM32F103单片机输出脉冲程序DMA传输PWM脉冲数据不连续。

查看: 6329|回复: 11
STM32学习-使用DMA功能自动更新PWM的输出
完整程序源代码工程文件下载地址:
(253.23 KB, 下载次数: 77)
17:41 上传
点击文件名下载附件
下载积分: 黑币 -5
//------------------------------------------------------------------------------
#if& & & & (RCC_PLLMul==2)& && && && & // ok
& & & & #define RCC_PLLMul_&&RCC_PLLMul_2
#elif (RCC_PLLMul==4)
& & & & #define RCC_PLLMul_&&RCC_PLLMul_4
#elif (RCC_PLLMul==8)
& & & & #define RCC_PLLMul_&&RCC_PLLMul_8
#elif (RCC_PLLMul==9)
& & & & #define RCC_PLLMul_&&RCC_PLLMul_9
#elif (RCC_PLLMul==16)
& & & & #define RCC_PLLMul_&&RCC_PLLMul_16
#else
& & & & error
#endif
#define SYSCLK&&(float)(FREQ_HSE*RCC_PLLMul)
//------------------------------------------------------------------------------
#if& & & & (RCC_AHB_Div==1)& & & & & & & & & &&&// ok
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div1
#elif (RCC_AHB_Div==2)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div2
#elif (RCC_AHB_Div==4)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div4
#elif (RCC_AHB_Div==8)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div8
#elif (RCC_AHB_Div==16)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div16
#elif (RCC_AHB_Div==64)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div64
#elif (RCC_AHB_Div==128)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div128
#elif (RCC_AHB_Div==256)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div256
#elif (RCC_AHB_Div==512)
& & & & #define RCC_HCLK_Div_ RCC_SYSCLK_Div512
#else
& & & & error
#endif
#define HCLK (float)(SYSCLK/RCC_AHB_Div)
#define FCLK (float)(HCLK)
//------------------------------------------------------------------------------
#if (RCC_APB1_Div==1)& & & & & & & & & & & &&&// ok
& & & & #define RCC_PCLK1_Div_ RCC_HCLK_Div1
#elif (RCC_APB1_Div==2)
& & & & #define RCC_PCLK1_Div_ RCC_HCLK_Div2
#elif (RCC_APB1_Div==4)
& & & & #define RCC_PCLK1_Div_ RCC_HCLK_Div4
#elif (RCC_APB1_Div==8)
& & & & #define RCC_PCLK1_Div_ RCC_HCLK_Div8
#elif (RCC_APB1_Div==16)
& & & & #define RCC_PCLK1_Div_ RCC_HCLK_Div16
#else
& & & & error
#endif
#define PCLK1 (float)(HCLK/RCC_APB1_Div)
//------------------------------------------------------------------------------
#if (RCC_APB2_Div==1)& & & & & & & & & & & &&&// ok
& & & & #define RCC_PCLK2_Div_ RCC_HCLK_Div1
#elif (RCC_APB2_Div==2)
& & & & #define RCC_PCLK2_Div_ RCC_HCLK_Div2
#elif (RCC_APB2_Div==4)
& & & & #define RCC_PCLK2_Div_ RCC_HCLK_Div4
#elif (RCC_APB2_Div==8)
& & & & #define RCC_PCLK2_Div_ RCC_HCLK_Div8
#elif (RCC_APB2_Div==16)
& & & & #define RCC_PCLK2_Div_ RCC_HCLK_Div16
#else
& & & & error
#endif
#define PCLK2 (float)(HCLK/RCC_APB2_Div)
//------------------------------------------------------------------------------
#if (RCC_ADC_DIV==2)
& & & & #define RCC_ADC_DIV_ RCC_PCLK2_Div2
#elif (RCC_ADC_DIV==4)
& & & & #define RCC_ADC_DIV_ RCC_PCLK2_Div4
#elif (RCC_ADC_DIV==6)
& & & & #define RCC_ADC_DIV_ RCC_PCLK2_Div6
#elif (RCC_ADC_DIV==8)
& & & & #define RCC_ADC_DIV_ RCC_PCLK2_Div8
#else
& & & & error
#endif
//------------------------------------------------------------------------------
#if (RCC_APB1_Div==1)
& & & & #define FACTOR_TIM234567& & & & 1
#else
& & & & #define FACTOR_TIM234567& & & & 2
#endif
#define TIM234567CLK & & & & (PCLK1*FACTOR_TIM234567)
#define TIM2CLK & & & & & & & & TIM234567CLK
#define TIM3CLK & & & & & & & & TIM234567CLK
#define TIM4CLK & & & & & & & & TIM234567CLK
#define TIM5CLK & & & & & & & & TIM234567CLK
#define TIM6CLK & & & & & & & & TIM234567CLK
#define TIM7CLK & & & & & & & & TIM234567CLK
//------------------------------------------------------------------------------
#if (RCC_APB2_Div==1)
& & & & #define TIM1CLK & & & & (PCLK2)&&
& & & & #define TIM8CLK & & & & (PCLK2)&&
#else
& & & & #define TIM1CLK & & & & (PCLK2*2)& &
& & & & #define TIM8CLK & & & & (PCLK2*2)& &
#endif
//------------------------------------------------------------------------------
#define ADCCLK & & & & & & & & ((float)PCLK2/RCC_ADC_DIV)&&
#define ADCCLKx10 & & & & (10*FREQ_HSE*RCC_PLLMul/(RCC_AHB_Div*RCC_APB2_Div*RCC_ADC_DIV))&&// 仅仅用于下面的判断
#if (ADCCLKx10&6)
& & & & error& &&&& & & & & & & & // adc的时钟最小为0.6MHz
#elif (ADCCLKx10&140)
& & & & error& &&&& & & & & & & & // adc的时钟最大为14MHz
#else
& & & & & & & & & & & & & & & & & & & & // 正常的adc频率范围
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
复制代码/*******************************************************************************
编译环境:& & & & EWARM V5.30
硬件环境:& & & & DZY2.PCB
STM32 FW:& &V3.0.0
作者& & & & :& & & & szlihongtao
******************************************************************************
REV& & & & & & & & :& & & & V1.00
DATE& & & & :& & & &
NOTE& & & & :&&
*******************************************************************************/
#include &stm32f10x.h&
#include &stm32_m.h&
#include &dzy.h&& &
#include &myRCC.h&& &
//******************************************************************************
#define TIM1_CCR3_Address& & 0x40012C3C
bit f_& & & & & & & & & & & & & & & & // 基本定时标志
bit f_100ms,f_1000& & & & & & & & & & & &&&
INT16U cnt_& & & & & & & & // 计数器,仅供软件调试使用
float clk_& & & & & & & & & & & & // 仅供软件调试使用
#if 0
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
& &__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 HSEStartUpS
/*
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_InitS
&&& & & & /* 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*)& & // 单位为Hz
& & & & #define TB_SysTick& & & & & & & & (TIME_TB*1000)& & & & & & & & // 单位为uS,与示波器实测一致
& & & & static INT32U
& & & & ticks=(INT32U)((TB_SysTick/)*SystemFreq);
& & & & SysTick_Config(ticks);
#endif& & & &
}
//******************************************************************************
// GPIO设置
//******************************************************************************
static void GPIO_Configuration(void)
{
& & & & GPIO_InitTypeDef GPIO_InitS
& & & & 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);& & & & // 11111& &&&
& &
& &&&/* 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);& & & & // 01111
&&& & & & 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);& & & & // 11111& &
&&& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_2;
&&& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
&&& & & & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
&&& & & & GPIO_Init(GPIOD, &GPIO_InitStructure);
}
//******************************************************************************
void DMA_Configuration(void)
{
& & & & DMA_InitTypeDef DMA_InitS
& & & & RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);& & & & & & & & // dma1时钟使能
& & & &
& & & & DMA_DeInit(DMA1_Channel5);& & & & & & & & & & & & // DMA复位
& & & & DMA_StructInit(&DMA_InitStructure);// DMA缺省的参数
&&& & & & DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR3_A& & & & & & & & //外设地址
&&& & & & DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_B//内存地址
&&& & & & DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;& & & & //dma传输方向,单向
&&& & & & DMA_InitStructure.DMA_BufferSize = sizeof(SRC_Buffer)/2;& & & & & & & & //设置DMA在传输时缓冲区的长度
&&& & & & DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D//设置DMA的外设递增模式,一个外设
&&& & & & DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E//设置DMA的内存递增模式,
&&& & & & DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW //外设数据字长
&&& & & & DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW& & & & & & & & & & & & //内存数据字长
& & & & //循环模式开启,Buffer写满后,自动回到初始地址开始传输
& & & & DMA_InitStructure.DMA_Mode = DMA_Mode_C& & & & & & & & //设置DMA的传输模式
& & & & DMA_InitStructure.DMA_Priority = DMA_Priority_H& & & & //设置DMA的优先级别
&&& & & & DMA_InitStructure.DMA_M2M = DMA_M2M_D& & & & & & & & //设置DMA的2个memory中的变量互相访问
&&& & & & DMA_Init(DMA1_Channel5, &DMA_InitStructure);
& & & & DMA_ClearFlag(DMA1_IT_TC5);
& & & & DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
&&& & & & DMA_Cmd(DMA1_Channel5, ENABLE);
}
/* TIM1 DMA Transfer example -------------------------------------------------
&&TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz
&&The TIM1 Channel3 is configured to generate a complementary PWM signal with
&&a frequency equal to: TIM1 counter clock / (TIM1_Period + 1) = 17.57 KHz and
&&a variable duty cycle that is changed by the DMA after a specific number of
&&Update DMA request.
&&The number of this repetitive requests is defined by the TIM1 Repetion counter,
&&each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new
&&value defined by the SRC_Buffer .
&&-----------------------------------------------------------------------------*/
//******************************************************************************
void Tim1_Configuration(void)
{
& & & & INT16U TIM_Prescaler,TIM_P
& & & & INT32U
& & & & TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
& & TIM_OCInitTypeDef TIM_OCInitS
& & & &
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
& & & &
& & & & TIM_DeInit(TIM1);& && && &
& & & & utemp=(INT32U)(TIM1CLK*)/Freq_PWM;
& & & & TIM_Prescaler=utemp/65536;
& & & & ++TIM_P& && && && && && && &&&// 注意这句话,一定要++
& & & & utemp=(INT32U)(TIM1CLK*)/TIM_P&&// 分频后的定时器输入频率
& & & & TIM_Period=utemp/Freq_PWM;& && && && && &// 周期常数
&&
& & TIM_TimeBaseStructure.TIM_Period = TIM_Period-1;
& & & & TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler-1;
&&& & & & TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
&&& & & & TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
& & TIM_TimeBaseStructure.TIM_RepetitionCounter = 1-1;// 每次直接更新
&&& & & & TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//------------------------------------------------------------------------------
& & & & /* PWM1 Mode configuration: Channel1 */& &
&&& & & & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
&&& & & & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E // 使能输出比较状态
&&& & & & TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_D // 失能输出比较N状态
&&& & & & TIM_OCInitStructure.TIM_Pulse = 72;& && & & && && &
/*& && && &&&
& & & & TIM_OCMode_PWM2&&TIM_OCPolarity_Low& & 正脉冲模式
& & & & TIM_OCMode_PWM2&&TIM_OCPolarity_High& &负脉冲模式
& & & & TIM_OCMode_PWM1&&TIM_OCPolarity_Low& & 负脉冲模式
& & & & TIM_OCMode_PWM1&&TIM_OCPolarity_High& &正脉冲模式
& & & & TIM1_OCPolarity输出极性---TIM_OCPolarity_High,输出比较极性高,输出的是正脉冲
& & & & TIM1_OCPolarity输出极性---TIM_OCPolarity_Low, 输出比较极性低,输出的是负脉冲
*/
&&& & & & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_L
&&& & & & TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_L // 互补输出极性
&&& & & & // 选择空闲状态下的非工作状态
&&& & & & // 当MOE=0设置TIM1输出比较空闲状态& && &
&&& & & & // 默认输出位低电平& && && && && &
&&& & & & TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_R
&&& & & & // 选择空闲状态下的非工作状态
&&& & & & // 当MOE=0重置TIM1输出比较N空闲状态
&&& & & & TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_R
&&& & & & TIM_OC3Init(TIM1, &TIM_OCInitStructure);
&&& & & & TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);// 使能TIMx在CCR1上的预装载寄存器
& && &/* TIM1 Update DMA Request enable */& && && &
& & TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
& && & & & //TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);& & & & // 定时中断使能
& && & & & //TIM_ITConfig(TIM1,TIM_IT_CC3,ENABLE);& & & & // 定时中断使能
& & TIM_Cmd(TIM1, ENABLE);& & & & & & & & & & & & & & & & & & & &&&// 定时器开始运行
& && && && && &&&
& & & & // 这条语句必须要有!!!
& & & & TIM_CtrlPWMOutputs(TIM1, ENABLE);& & & & & & & &&&/* Main Output Enable */& &
}
//******************************************************************************
// 基本定时程序,周期为 TIME_TB
//******************************************************************************
static func_tb(void)
{
& & & & static INT16U tmr_100
& & & & static INT16U tmr_1000
& & & &
& & & & if (!f_tb)& && && && && && && && &&&
& & & & & & & &
& & & & f_tb=0;
& &
& & & & if (++tmr_100ms&=(100/TIME_TB))
& & & & {
& & & & & & & & tmr_100ms=0;
& & & & & & & & f_100ms=1;& &&&
& && &
& & & && &&&GPIOC-&ODR ^= GPIO_Pin_4;& & & & & & & & // led5 toogle& && && &
& & & & }
& & & & if (++tmr_1000ms&=(1000/TIME_TB))
& & & & {
& & & & & & & & tmr_1000ms=0;
& & & & & & & & f_1000ms=1;
& & & && &&&GPIOC-&ODR ^= GPIO_Pin_5;& & & & & & & & // led4 toogle& && &
& & & & }& & & &
//******************************************************************************
// 进入睡眠模式
// 自行编写
//******************************************************************************
void myPWR_EnterSleepMode(void)
{
&&& & & & //PWR-&CR |= CR_CWUF_S& & & & /* Clear Wake-up flag */
&&& & & & /* Set SLEEPDEEP bit of Cortex System Control Register */
&&& & & & //*(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_S
& & & & /* This option is used to ensure that store operations are completed */
& & & & __WFI(); & & & & & & & & /* Request Wait For Interrupt */
}
//******************************************************************************
// 主程序
//******************************************************************************
void main(void)
{& && && &
& &
& &
& & & & RCC_Configuration();& &
&&& & & & GPIO_Configuration();
& & & & delayms(100);& & & & & & & & & & & & // 延时,等待电压稳定
& & & & Tim1_Configuration();& &&&
& & & & DMA_Configuration();
&&& & & & SysTick_Config1();
& & & & NVIC_Configuration();& & & &
//------------------------------------------------------------------------------
& & for(i=0;i&6;++i)
& & & & {
& & & & & & & & //i=0;
& & & & & & & & //GPIOA-&ODR ^= GPIO_Pin_10;& & & & & & & & // led3 toogle
& & & & & & & & //GPIOA-&ODR ^= GPIO_Pin_11;& & & & & & & & // led3 toogle
& & & &
& & & & & & & & delayms(1);& & & &
& && &&&led_toggle();& & & & & & & &
& & }
//------------------------------------------------------------------------------ & & & &
& & & & for(;;)
& & & & {& & & & & & & &
& & & & & & & & //if (set_sw&0x01)
& & & & & & & & & & & & //myPWR_EnterSleepMode(); // 休眠,降低功耗
& & & & & & & & func_tb();
& & }
}
//******************************************************************************
#ifdef&&USE_FULL_ASSERT
/**
&&* @brief&&Reports the name of the source file and the source line number
&&*& &where the assert_param error has occurred.
&&* @param file: pointer to the source file name
&&* @param line: assert_param error line source number
&&* @retval : None
&&*/
void assert_failed(uint8_t* file, uint32_t line)
{
&&/* User can add his own implementation to report the file name and line number,
& &&&ex: printf(&Wrong parameters value: file %s on line %d\r\n&, file, line) */
&&/* Infinite loop */
&&while (1)
&&{
&&}
}
#endif
//******************************************************************************
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
//******************************************************************************
/*
& & & & LED2---------PC7
& & & & LED3---------PC6
& & & & LED4---------PC5
& & & & LED5---------PC4
& & & & KEY2---------PD3
& & & & KEY3---------PD4
@par Example Description
This example provides a description of how to use DMA with TIM1 Update request
to transfer Data from memory to TIM1 Capture Compare Register3.
TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz
The TIM1 Channel3 is configured to generate a complementary PWM signal with
a frequency equal to: TIM1 counter clock / (TIM1_Period + 1) = 17.57 KHz
The TIM1 Channel3 is configured to generate a complementary PWM signal with
a frequency equal to 17.578 KHz and a variable duty cycle that is changed
by the DMA after a specific number of Update event.
The number of this repetitive requests is defined by the TIM1 Repetion counter,
each 3 Update Requests, the TIM1 Channel3 Duty Cycle changes to the next new value
defined by the SRC_Buffer.
&&- STM3210E-EVAL and STM3210B-EVAL Set-up
& & - Connect the following pins to an oscilloscope to monitor the different waveforms:&&
& && &&&- TIM1 CH3&&(PA.10)& &pin69
& && &&&- TIM1 CH3N (PB.15)& &pin54
*/
东西不错啊。。。
谢谢分享,51黑有你更精彩!!
所有的好东西我都要&&哇哈哈哈哈
正是我想要的,谢谢
正是我想要的,谢谢
木有黑币,下载不了源码
这能改变PWM频率吗?还是只改变占空比?
正在做自动改变PWM频率的项目,对我帮助很大,但下不了啊!
好资源,谢谢
Powered by

我要回帖

更多关于 单片机数据传输 的文章

 

随机推荐