论坛元老
 
- 积分
- 8024
- 金钱
- 8024
- 注册时间
- 2014-8-13
- 在线时间
- 1595 小时
|
发表于 2016-7-11 13:15:45
|
显示全部楼层
本帖最后由 mack13013 于 2016-7-11 13:20 编辑
贴个代码给你参考一下吧。 TIM1,TIM8各输出4路,还可以各加三路互补输出的。
程序里的标记、注释什么的不强制保留。
注释有地方不匹配,可自行修改。不匹配的原因是后期有些地方代码修改了,注释没有改
[mw_shl_code=c,true]
void Board_Init(void)
{
RCC ->AHB1ENR |= 0x0000007F; //PORT ABCDEFG 时钟使能
}
u8 PwmRun()
{
RCC ->APB1ENR |= 1 << 2; //使能TIM4
RCC ->AHB1ENR |= 1 << 3; //使能PortD时钟
GPIO_Set(GPIOD, PIN14 | PIN15, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU); //复用, 输出, 上拉
//PD14、PD15复用为TIM4的CH3和CH4
GPIO_AF_Set(GPIOD, 14, 2);
GPIO_AF_Set(GPIOD, 15, 2);
TIM4 ->ARR = 84 - 1;
TIM4 ->PSC = 0;
TIM4 ->CCMR2 |= 6 << 4; //CH3 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM4 ->CCMR2 |= 6 << 12; //CH4 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM4 ->CCMR2 |= 1 << 3; //CH3 预装载使能
TIM4 ->CCMR2 |= 1 << 11; //CH4 预装载使能
TIM4 ->CCER |= 1 << 8; //OC3输出使能
TIM4 ->CCER |= 1 << 12; //OC4输出使能
TIM4 ->CCER &= ~(1 << 9); //OC3高电平有效
TIM4 ->CCER &= ~(1 << 13); //OC4高电平有效
TIM4 ->CCR3 = 21;
TIM4 ->CCR4 = 63;
TIM4 ->CR1 |= 1 << 7; //ARR寄存器缓冲
//TIM4 ->BDTR |= 1 << 15; //MOE = 1
TIM4 ->CR1 |= 1 << 0; //使能定时器4,输出PWM
return 0;
}
//成功返回0,失败返回1:参数错误
u8 PulseParametersSet(u16 uwTime1, u16 uwTime2, u16 uwTime3, u16 uwTime4, u16 uwHoldLengthUs)
{
//添加差异补偿或者使用非常好的元件
u32 unArr;
u16 uwSparkCnt, uwIgnRestCnt, uwSmplCnt, uwHoldCnt;
// if(uwTime3 > uwTime1|| uwTime4 + uwHoldLengthUs > uwTime1)
// {
// return 1;
// }
unArr = (uwTime2 + uwTime1) * 2 - 1;
uwSparkCnt = uwTime1 * 2;
uwIgnRestCnt = uwTime3 * 2;
uwSmplCnt = uwTime4 * 2;
uwHoldCnt = (uwTime4 + uwHoldLengthUs) * 2;
RCC ->APB2ENR |= 3 << 0; //使能TIM1 TIM8时钟
RCC ->AHB1ENR |= 1 << 0; //使能PortA时钟
RCC ->AHB1ENR |= 1 << 2; //使能PortC时钟
RCC ->AHB1ENR |= 1 << 6; //使能PortE时钟
GPIO_Set(GPIOC, PIN6 | PIN7 | PIN8 | PIN9, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU); //复用, 输出,上拉
GPIO_Set(GPIOE, PIN11 | PIN13 | PIN14, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU); //复用, 输出,上拉
GPIO_Set(GPIOA, PIN8, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU); //复用, 输出,上拉
//PC6、7、8、9复用为TIM8的CH1、2、3、4
GPIO_AF_Set(GPIOC, 6, 3);
GPIO_AF_Set(GPIOC, 7, 3);
GPIO_AF_Set(GPIOC, 8, 3);
GPIO_AF_Set(GPIOC, 9, 3);
//PE11、13、14复用为TIM1的CH2、3、4
GPIO_AF_Set(GPIOE, 11, 1);
GPIO_AF_Set(GPIOE, 13, 1);
GPIO_AF_Set(GPIOE, 14, 1);
//PA8复用为TIM1的CH1
GPIO_AF_Set(GPIOA, 8, 1);
TIM1 ->ARR = unArr; //自动装填值,该值与分频数决定PWM的周期长度(从而也确定频率)
TIM8 ->ARR = unArr; //自动装填值,该值与分频数决定PWM的周期长度(从而也确定频率)
// TIM1 ->PSC = 0; //分频器。经过unPsc个TIM1的周期后,TIM1的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数 每个CNT为0.5us
// TIM8 ->PSC = 0; //分频器。经过unPsc个TIM8的周期后,TIM8的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数 每个CNT为0.5us
TIM1 ->PSC = 84 - 1; //分频器。经过unPsc个TIM1的周期后,TIM1的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数 每个CNT为0.5us
TIM8 ->PSC = 84 - 1; //分频器。经过unPsc个TIM8的周期后,TIM8的CNT计数器加1,CNT的数值达到unArr后,产生中断或者事件,然后从0开始计数 每个CNT为0.5us
TIM1 ->CCMR1 |= 6 << 4; //CH1 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM1 ->CCMR1 |= 6 << 12; //CH2 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM1 ->CCMR2 |= 6 << 4; //CH3 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM1 ->CCMR2 |= 6 << 12; //CH4 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM8 ->CCMR1 |= 6 << 4; //CH1 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM8 ->CCMR1 |= 6 << 12; //CH2 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM8 ->CCMR2 |= 6 << 4; //CH3 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM8 ->CCMR2 |= 6 << 12; //CH4 PWM模式1 先有效电平后无效电平 有效电平、无效电平是高还是低,由CCER的CCxP位决定
TIM1 ->CCMR1 |= 1 << 3; //CH1 预装载使能
TIM1 ->CCMR1 |= 1 << 11; //CH2 预装载使能
TIM1 ->CCMR2 |= 1 << 3; //CH3 预装载使能
TIM1 ->CCMR2 |= 1 << 11; //CH4 预装载使能
TIM8 ->CCMR1 |= 1 << 3; //CH1 预装载使能
TIM8 ->CCMR1 |= 1 << 11; //CH2 预装载使能
TIM8 ->CCMR2 |= 1 << 3; //CH3 预装载使能
TIM8 ->CCMR2 |= 1 << 11; //CH4 预装载使能
TIM1 ->CCER |= 1 << 0; //OC1输出使能
TIM1 ->CCER |= 1 << 4; //OC2输出使能
TIM1 ->CCER |= 1 << 8; //OC3输出使能
TIM1 ->CCER |= 1 << 12; //OC4输出使能
TIM8 ->CCER |= 1 << 0; //OC1输出使能
TIM8 ->CCER |= 1 << 4; //OC2输出使能
TIM8 ->CCER |= 1 << 8; //OC3输出使能
TIM8 ->CCER |= 1 << 12; //OC4输出使能
TIM1 ->CCER &= ~(1 << 1); //OC1高电平有效
TIM1 ->CCER &= ~(1 << 5); //OC2高电平有效
TIM1 ->CCER &= ~(1 << 9); //OC3高电平有效
TIM1 ->CCER |= 1 << 13; //OC4低电平有效
TIM8 ->CCER |= 1 << 1; //OC1低电平有效
TIM8 ->CCER &= ~(1 << 5); //OC2高电平有效
TIM8 ->CCER &= ~(1 << 9); //OC3高电平有效
TIM8 ->CCER &= ~(1 << 13); //OC4高电平有效
PULSE1_SPARK = uwSparkCnt;
PULSE1_IGN_RESET = uwIgnRestCnt;
PULSE1_SMPL = uwSmplCnt;
PULSE1_HOLD = uwHoldCnt;
PULSE2_SPARK = uwSparkCnt;
PULSE2_IGN_RESET = uwIgnRestCnt;
PULSE2_SMPL = uwSmplCnt;
PULSE2_HOLD = uwHoldCnt;
TIM1 ->CR1 |= 1 << 7; //ARR寄存器缓冲
TIM1 ->BDTR |= 1 << 15; //MOE = 1
TIM8 ->CR1 |= 1 << 7; //ARR寄存器缓冲
TIM8 ->BDTR |= 1 << 15; //MOE = 1
return 0;
}
//成功返回0
u8 PulseOutputStart(void)
{
u32 nus;
nus = TIM8 ->ARR;
if(TIM1 ->ARR != nus)
{
return 1;
}
nus += 2;
nus /= 4;
TIM8 ->CR1 |= 1 << 0; //使能定时器8,输出pulse1
delay_us(nus);
TIM1 ->CR1 |= 1 << 0; //使能定时器1,输出pulse2
return 0;
}
void PulseOutputStop(void)
{
TIM8 ->CR1 &= ~(1 << 0); //关闭定时器8,停止输出pulse1
TIM1 ->CR1 &= ~(1 << 0); //关闭定时器1,停止输出pulse2
//--zkek 这里要设置各输出至安全状态,比如,有些器件在PWM停止后,不允许长时间开启,就要置0
}
[/mw_shl_code]
|
|