初级会员

- 积分
- 51
- 金钱
- 51
- 注册时间
- 2017-6-18
- 在线时间
- 16 小时
|

楼主 |
发表于 2018-9-12 16:58:27
|
显示全部楼层
void TIM1_DMA_S_Uni(DMA_Channel_TypeDef* DMA_CHx,u32 Memory,u32 cpar,u16 cndtr)
{
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //ê1ÄüDMA′«êä
DMA_DeInit(DMA_CHx);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA1_MEM_LEN=cndtr;
DMA_InitStructure.DMA_MemoryBaseAddr = Memory;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = cndtr;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
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(DMA_CHx, &DMA_InitStructure);
DMA_ITConfig(DMA_CHx, DMA_IT_TC, ENABLE);
DMA_ClearITPendingBit(DMA_IT_HT);
DMA_ClearITPendingBit(DMA_IT_TC);
}
void TIM1_S(uint16_t ARR,uint16_t CCR)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_PinRemapConfig( GPIO_FullRemap_TIM1, ENABLE); //ÖØDÂó3éätim11ü½Å
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PWMÂö3åêä3öê1Äüòy½Å
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
TIM_DeInit(TIM1);
TIM_BaseInitStructure.TIM_Period = ARR; //ÖüÆúêy¾Y
TIM_BaseInitStructure.TIM_Prescaler = 100; //Ô¤·ÖÆμêyá¿
TIM_BaseInitStructure.TIM_ClockDivision = 0;
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure);
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 = CCR;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM1,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
// TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Trigger);
TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
// TIM_SelectInputTrigger(TIM1,TIM_TS_ITR0);
// TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); //
TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_1Byte);
TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
// TIM_ClearFlag(TIM1, TIM_FLAG_Update);
// TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE); //DISABLE
TIM_CtrlPWMOutputs(TIM1,ENABLE);
}
int main()
{
while(1)
{
delay_ms(1000);
TIM1_DMA_S_Uni(DMA1_Channel5,(u32)&M1_Uni_Speed,(u32)&TIM1->DMAR,3200);
TIM1_S(571,285);
DMA_Cmd(DMA1_Channel5, ENABLE);
while(Get_DMA_Staus()==false)
{
delay_ms(100);
}
TIM_Cmd(TIM1, DISABLE); //DISABLE
DMA_Cmd(DMA1_Channel5, DISABLE);
Set_DMA_Status(false);
delay_ms(1000);
delay_ms(1000);
}
}
我采用了DMA循环发送的方式发送了3200次,最终检测发现脉冲数多发了(3200个脉冲电机转一圈),我不懂,定时器和DMA如何启动,同时启动吗?还是只需要启动定时器就可以自动触发DMA传输?还是只启动DMA传输,寄存器数据更新会自动启动定时器?
在加速阶段结束之后我在中断里面设置了匀速阶段的DMA配置,但是发现电机这时候会出现很短暂的卡顿,如果想要更改DMA配置的内存地址和DMA传输模式,如何能尽量在中断里面缩短代码执行时间,精简代码? 比如说我是不是可以不需要完全重新配置DMA参数就可以更改DMA传输模式为循环传输模式,并且设定传输次数?
|
|