• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

stm32DMA与tim产生spwm

程序如下:

 #include "DMA_SPWM.h"
#define TIM1_CCR1_Address    ((uint32_t)0x40012C34)
#define TIM8_CCR2_Address    ((uint32_t)0x40013438)

//ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
float data[506]={
                0.012516,0.02503,0.03754,0.050044,0.062541,0.075027,0.087502,0.099963,0.11241,0.12484,
    0.13724,0.14963,0.16199,0.17433,0.18664,0.19893,0.21118,0.22339,0.23557,0.24772,0.25983,
    0.27189,0.28392,0.29589,0.30783,0.31971,0.33154,0.34333,0.35505,0.36673,0.37834,0.3899,
    0.40139,0.41283,0.42419,0.43549,0.44673,0.45789,0.46898,0.48,0.49094,0.50181,0.51259,
    0.5233,0.53392,0.54446,0.55492,0.56529,0.57557,0.58576,0.59586,0.60586,0.61577,0.62558,0.6353,
    0.64492,0.65443,0.66384,0.67315,0.68235,0.69145,0.70044,0.70932,0.71808,0.72674,0.73528,0.7437,
    0.75201,0.7602,0.76827,0.77623,0.78406,0.79176,0.79935,0.8068,0.81414,0.82134,0.82841,0.83536,
    0.84218,0.84886,0.85541,0.86182,0.8681,0.87425,0.88026,0.88613,0.89186,0.89745,0.9029,0.90821,
    0.91338,0.9184,0.92328,0.92802,0.93261,0.93705,0.94135,0.9455,0.9495,0.95335,0.95705,0.96061,
    0.96401,0.96726,0.97036,0.97331,0.97611,0.97875,0.98124,0.98358,0.98576,0.98779,0.98966,0.9913,
    0.99294,0.99435,0.9956,0.99669,0.99763,0.99841,0.99904,0.99951,0.99982,0.99998,0.99998,0.99982,
    0.99951,0.99904,0.99841,0.99763,0.99669,0.9956,0.99435,0.99294,0.99138,0.98966,0.98779,0.98576,
    0.98358,0.98124,0.97875,0.97611,0.97331,0.97036,0.96726,0.96401,0.96061,0.95705,0.95335,0.9495,
    0.9455,0.94135,0.93705,0.93261,0.92802,0.92328,0.9184,0.91338,0.90821,0.9029,0.89745,0.89186,
    0.88613,0.88026,0.87425,0.8681,0.86182,0.85541,0.84886,0.84218,0.83536,0.82841,0.82134,0.81414,
    0.8068,0.79935,0.79176,0.78406,0.77623,0.76827,0.7602,0.75201,0.7437,0.73528,0.72674,0.71808,
    0.70932,0.70044,0.69145,0.68235,0.67315,0.66384,0.65443,0.64492,0.6353,0.62558,0.61577,0.60586,
    0.59586,0.58576,0.57557,0.56529,0.55492,0.54446,0.53392,0.5233,0.51259,0.50181,0.49094,0.48,
    0.46898,0.45789,0.44673,0.43549,0.42419,0.41283,0.40139,0.3899,0.37834,0.36673,0.35505,0.34333,
    0.33154,0.31971,0.30783,0.29589,0.28392,0.27189,0.25983,0.24772,0.23557,0.22339,0.21118,0.19893,
    0.18664,0.17433,0.16199,0.14963,0.13724,0.12484,0.11241,0.099963,0.087502,0.075027,0.062541,0.050044,
    0.03754,0.02503,0.012516,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0, 
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,
    
       };
uint16_t data1[506],data2[506];
//uint16_t iodata[2]={0x0001,0x0000};
//TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
//TIM_OCInitTypeDef  TIM_OCInitStructure;
uint16_t TimerPeriod = 0;
uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void TIM_Configuration(void);
//void ADC1_Configuration(void);

void spwminit(void)
{
  int i;
 
  RCC_Configuration();

  /* GPIO Configuration */
  GPIO_Configuration();
 
  DMA_Configuration();
 
  TIM_Configuration();
 
  for(i=0;i<506;i++)
  {
 data1[i]= (uint16_t)(data[i]*(TimerPeriod - 1));
 /*i++;              */
 data2[505-i]= (uint16_t)(data[i]*(TimerPeriod - 1))*0.9655;
  }
 

}

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{
 
  //RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1|RCC_AHBPeriph_DMA2, ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1|RCC_APB2Periph_TIM8|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);
 
}

/**
  * @brief  Configure the TIM 1 Pins.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* GPIOA Configuration: Channel 1, 2 and 3 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;       //tim8_ch2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;   //tim1_ch1,2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_0;   //tim1_chn1,tim8_chn2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void DMA_Configuration(void)
{
/* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel5);
  DMA_DeInit(DMA2_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&data1;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 506;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM8_CCR2_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&data2;
  DMA_Init(DMA2_Channel1, &DMA_InitStructure);
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel5, ENABLE);
  DMA_Cmd(DMA2_Channel1, ENABLE);
}

void TIM_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  TIM_BDTRInitTypeDef TIM1_BDTRInitStructure;
  /*
   TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
   SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density
   and Connectivity line devices and to 24 MHz for Low-Density Value line and
   Medium-Density Value line devices
   The Timer pulse is calculated as follows:
     - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100
  ----------------------------------------------------------------------- */
  TimerPeriod = (SystemCoreClock / 25300 ) - 1;
  /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 and 1N */
  Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
  /* Compute CCR2 value to generate a duty cycle at 37.5%  for channel 2 and 2N */
  Channel2Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000);
 
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
 
  TIM_DMACmd(TIM8,  TIM_DMA_Update,ENABLE);
  TIM_DMACmd(TIM1,  TIM_DMA_Update,ENABLE);
 // TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );
 
  /*TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);*/
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
 // TIM_OCStructInit(& TIM_OCInitStructure);
  TIM_OC2Init(TIM8, &TIM_OCInitStructure);
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
 
  TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  TIM1_BDTRInitStructure.TIM_DeadTime = 0;
  TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
  TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
  TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStructure);
  TIM_BDTRConfig(TIM8,&TIM1_BDTRInitStructure);
 
  TIM_Cmd(TIM1, ENABLE);
  TIM_Cmd(TIM8, ENABLE);
  TIM_CtrlPWMOutputs(TIM1, ENABLE);
  TIM_CtrlPWMOutputs(TIM8, ENABLE);
}

全部回复(7)
正序查看
倒序查看
123sky
LV.2
2
2013-08-02 15:22

    

波形的中间部分怎么会这样呢?

 

    

0
回复
xd
LV.1
3
2013-08-03 08:48
@123sky
[图片]   [图片] 波形的中间部分怎么会这样呢? [图片]    
不错的帖子值得学习~~
0
回复
123sky
LV.2
4
2013-08-03 09:11
@xd
不错的帖子值得学习~~

虽然正弦波出来了,可还是感觉这spwm和正常的不大一样

0
回复
xd
LV.1
5
2013-08-03 10:42
@123sky
虽然正弦波出来了,可还是感觉这spwm和正常的不大一样

波形变形了是吧

还是说你的示波器测出来的波形导致变形啦??

0
回复
123sky
LV.2
6
2013-08-03 14:38
@xd
波形变形了是吧还是说你的示波器测出来的波形导致变形啦??

正弦波是有点畸变的,示波器出来的spwm如上图,感觉是不对的,不知道是不是示波器测得不对,还是本身spwm不对。。。。。不过用其他写法做出的spwm用示波器显示是对的

0
回复
2013-11-05 23:45
@123sky
[图片]   [图片] 波形的中间部分怎么会这样呢? [图片]    

楼主也太烧包了吧

输出spwm用浮点,103没有浮点处理器呀

直接先用整数换算一下不是更好吗

for(i=0;i<506;i++)  { data1[i]= (uint16_t)(data[i]*(TimerPeriod - 1)); /*i++;              */ data2[505-i]= (uint16_t)(data[i]*(TimerPeriod - 1))*0.9655;  } 

这一段完全可以在pc上算好了再写到程序里面

0
回复
ymhujiang
LV.4
8
2013-11-20 17:05
@wangshujun
楼主也太烧包了吧输出spwm用浮点,103没有浮点处理器呀直接先用整数换算一下不是更好吗for(i=0;i
我是来学习的。
0
回复