新手上路
- 积分
- 27
- 金钱
- 27
- 注册时间
- 2018-7-10
- 在线时间
- 38 小时
|
50金钱
各位大佬好,我参考网友@nashui_sx的代码,设置定时器1 通道3输出SPWM波形,现已实现通道1输出了互补的波形,
现按照如下通道设置DMA通道6,TIM1_CH3通道3输出SPWM,但是如下代码只能输出互补的方波,没有可变PWM,定时器与DMA都对应手册设置,感觉DMA设置有问题,但又不知道问题在那,恳请各位解惑,谢谢!
备注:如下代码更改位DMA通道2,设置定时器为通道1,不用改为其他代码,即可在A8/B13输出互补的SPWM

u16 TIM1_Spwm_Buf[TIM1_Spwm_Buf_Size]; //发送数据缓冲区 ,控制占空比
void TIM1_Spwm_Creat_Buf(void)
{
u32 i;
float inc=2*PI/TIM1_Spwm_Buf_Size; //计算增量
for(i=0;i<TIM1_Spwm_Buf_Size;i++)
{
TIM1_Spwm_Buf=(u16)(TIM1_Spwm_Buf_Zhouqi/2*(1+sin(inc*i))+0.5); //得到一个0-TIM1_Spwm_Buf_Zhouqi的正弦波控制spwm +0.5是为了最大值能够达到TIM1_Spwm_Buf_Zhouqi 最小能到0
}
}
void TIM1_Spwm_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; //输出通道配置
TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //死区和刹车配置
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM1_Spwm_Creat_Buf();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
// //初始化TIM1
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//初始化TIM1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);
TIM_TimeBaseStructure.TIM_Period = TIM1_Spwm_Buf_Zhouqi-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =35; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision =0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //初始化通道3
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在通道3上的预装载寄存器
/*TIM1高级定时器互补通道输出配置*/
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //PWM互补输出使能
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补PWM极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //输出空闲状态
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; //PWM互补输出空闲状态
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM1 OC3
/*死区和刹车功能配置*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 0x1F; //设置TIM1_BDTR的DTG[7:0]
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
/*DMA功能配置*/
DMA_DeInit(DMA1_Channel6); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&TIM1->CCR1; //DMA外设基地址 问题在这里
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&TIM1_Spwm_Buf; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //DMA_DIR_PeripheralSRC:从外设读 DMA_DIR_PeripheralDST:从内存读
DMA_InitStructure.DMA_BufferSize = TIM1_Spwm_Buf_Size; //DMA通道的DMA缓存的大小,实测不加1少一个,应该是最后一个还没输出就中断关闭定时器了,+1就好了
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //是否开启内存到内存传输(关闭表示只有事件产生才传输一次数据,开启表示一直传输)DMA_M2M_Disable:非存储器到存储器模式(关闭内存到内存模式) DMA_M2M_Enable:启动存储器到存储器模式(开启内存到内存模式)
DMA_Init(DMA1_Channel6, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
DMA_Cmd(DMA1_Channel6,ENABLE); //DMA使能
TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE); //定时器TIM_DMA_CC1 TIM_DMA_Update使能
// TIM_DMACmd(TIM1, TIM_DMA_Update,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ClearFlag(DMA1_Channel6_IRQn); //清除DMA所有标志
DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,ENABLE); //开传输完成中断
TIM_SetCompare3(TIM1,TIM1_Spwm_Buf[0]); //通道1
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
|
|