2019-07-21 08:07发布
banxiafeixia 发表于 2018-10-31 09:27 不嫌麻烦的话,初始化定时器,设置成一秒进入几十K次的中断,挨个设定翻转的时间。有点麻烦,但是可行。
最多设置5个标签!
说干就干,用原子的MINI的TIM1的4个通道配置输出4路不同频率的方波,频率可调,提供源码附件
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"
//下次增量值
uint16_t TIM1_OC1_PulseAdd = 3600; //72M/10K/2=3600
uint16_t TIM1_OC2_PulseAdd = 3600; //72M/10K/2=3600
uint16_t TIM1_OC3_PulseAdd = 3600; //72M/10K/2=3600
uint16_t TIM1_OC4_PulseAdd = 3600; //72M/10K/2=3600
//比较捕获值
uint16_t TIM1_OC1_PulseVal = 0;
uint16_t TIM1_OC2_PulseVal = 0;
uint16_t TIM1_OC3_PulseVal = 0;
uint16_t TIM1_OC4_PulseVal = 0;
void TIM1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
//使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//PA8 PA9 PA10 PA11复用推挽输出
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//配置定时器1
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0; //分频越小、精度越高、范围越小; 分频越大、精度越低、范围越大
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//清除比较捕获中断标志
TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
TIM_ClearFlag(TIM1, TIM_FLAG_CC2);
TIM_ClearFlag(TIM1, TIM_FLAG_CC3);
TIM_ClearFlag(TIM1, TIM_FLAG_CC4);
//配置比较捕获中断
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE);
//比较捕获初值(必须设置,不然波形不对齐)
TIM1_OC1_PulseVal = TIM1_OC1_PulseAdd;
TIM1_OC2_PulseVal = TIM1_OC2_PulseAdd;
TIM1_OC3_PulseVal = TIM1_OC3_PulseAdd;
TIM1_OC4_PulseVal = TIM1_OC4_PulseAdd;
//清除比较模式
TIM1->CCMR1 &= ~((7<<4) | (7<<12));
TIM1->CCMR2 &= ~((7<<4) | (7<<12));
//强制为无效电平(不设置,边沿不能对其)
TIM1->CCMR1 |= ((4<<4) | (4<<12));
TIM1->CCMR2 |= ((4<<4) | (4<<12));
//翻转模式
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Toggle; //翻转
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //有效电平
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
//比较捕获通道1
TIM_OCInitStruct.TIM_Pulse = TIM1_OC1_PulseVal;
TIM_OC1Init(TIM1, &TIM_OCInitStruct);
//比较捕获通道2
TIM_OCInitStruct.TIM_Pulse = TIM1_OC2_PulseVal;
TIM_OC2Init(TIM1, &TIM_OCInitStruct);
//比较捕获通道3
TIM_OCInitStruct.TIM_Pulse = TIM1_OC3_PulseVal;
TIM_OC3Init(TIM1, &TIM_OCInitStruct);
//比较捕获通道4
TIM_OCInitStruct.TIM_Pulse = TIM1_OC4_PulseVal;
TIM_OC4Init(TIM1, &TIM_OCInitStruct);
//使能中断线
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//主输出使能(高级定时器)
TIM_CtrlPWMOutputs(TIM1, ENABLE);
//使能定时器
TIM_Cmd(TIM1, ENABLE);
}
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组2
LED_Init(); //初始化与LED连接的硬件接口
TIM1_Init(); //PA8被配置为复用功能
//重新配置频率
TIM1_OC1_PulseAdd = 2400; //72M/15K/2=2400
TIM1_OC2_PulseAdd = 3600; //72M/10K/2=3600
TIM1_OC3_PulseAdd = 7200; //72M/ 5K/2=7200
TIM1_OC4_PulseAdd = 36000; //72M/ 1K/2=36000
while(1)
{
LED1 = !LED1;
delay_ms(300);
}
}
//定时器1比较捕获中断
void TIM1_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) //比较捕获通道1
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
TIM1_OC1_PulseVal += TIM1_OC1_PulseAdd; //计算下次的比较捕获值
TIM_SetCompare1(TIM1, TIM1_OC1_PulseVal);
}
if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET) //比较捕获通道2
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
TIM1_OC2_PulseVal += TIM1_OC2_PulseAdd; //计算下次的比较捕获值
TIM_SetCompare2(TIM1, TIM1_OC2_PulseVal);
}
if(TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET) //比较捕获通道3
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);
TIM1_OC3_PulseVal += TIM1_OC3_PulseAdd; //计算下次的比较捕获值
TIM_SetCompare3(TIM1, TIM1_OC3_PulseVal);
}
if(TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) //比较捕获通道4
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
TIM1_OC4_PulseVal += TIM1_OC4_PulseAdd; //计算下次的比较捕获值
TIM_SetCompare4(TIM1, TIM1_OC4_PulseVal);
}
}
不知道怎么上传代码,只能复制到上面
定时器翻转一路最快也就500K的频率,5路更低,要求不高的话确实可以。
一周热门 更多>