关键配置
对应GPIO
NVIC中断管理
定时器初始化
定时器输出模式TIM_OC初始化(模式为TIM_OCMode_Toggle)
频率与占空比的计算
计数频率的计算
若使用比较输出,则ARR表示计数的上限,基本无用。计数频率由TIM_Prescaler成员变量配置。若配置TIM_Prescaler=71,输入时钟为72 M H z 72MHz72MHz,则计数频率为:
计数规则
当计数器数到CCR所储存的值时,输出电平就会翻转。
频率和占空比的配置
由计数规律我们可以通过修改CCR值的方法来得到我们想要的频率和占空比。
比如:计数频率为 1 M 1M1M,想要得到10 K 10K10K,占空比为80 % 80%80%的PWM波。
令空闲输出电平为0,关闭影子寄存器以便立即赋值。
当程序开始,立即进入中断,为CCR赋值为20,此时电平为低电平;
当计数器数过20,翻转电平,变为高电平,再次进入中断,为CCR赋值为20+80;
当计数器再数80,翻转电平,变为低电平,再次进入中断,为CCR赋值为20+80+20;
…
于是可见,数100为一个周期,其中20为低电平,80为高电平。输出PWM波频率1 M 1000 = 10 K H z frac{1M}{1000}=10KHz
1000
1M
=10KHz,占空比80 % 80%80%.
示例代码
从PA6和PA7输出两路PWM;PA6频率为10KHz,占空比为80% ;PA7频率为1KHz,占空比为20%
PWM驱动配置:
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
// PA1 PA2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void PWM_Config()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_Configuration();
NVIC_Configuration();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535; // 在TIM_OCMode_Toggle模式下ARR几乎无用
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72分频,计数频率为72M/72=1M
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数方式为向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; // 空闲状态为低电平
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); // 关闭影子寄存器,当给CCR赋值时,即刻赋值
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
}
中断代码如下:
extern __IO uint16_t CCR1_Val;
extern __IO uint16_t CCR2_Val;
uint16_t capture = 0;
u8 pa6_state=0,pa7_state=0;
float zhankong1=0.2;
float zhankong2=0.2;
void TIM3_IRQHandler(void)
{
/* TIM3_CH1 toggling with frequency = 10K Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM3);
if(pa6_state ==0)
{
TIM_SetCompare1(TIM3, capture + CCR1_Val*zhankong1 );
pa6_state = 1;
}
else
{
TIM_SetCompare1(TIM3, capture + CCR1_Val*(1-zhankong1) );
pa6_state = 0;
}
}
/* TIM3_CH2 toggling with frequency = 1k Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
if(pa7_state ==0)
{
TIM_SetCompare2(TIM3, capture + CCR2_Val*zhankong2 );
pa6_state = 1;
}
else
{
TIM_SetCompare2(TIM3, capture + CCR2_Val*(1-zhankong2) );
pa6_state = 0;
}
}
}
上一篇:STM32 EXTI外部中断小结
下一篇:STM32固件库的小结
推荐阅读最新更新时间:2024-11-16 20:01
推荐帖子
- 3DG6C
- 本帖最后由paulhyde于2014-9-1508:56编辑请问有人知道3DG6C的引脚怎么分布吗?哪个是e,c,b脚。。。。3DG6C本帖最后由paulhyde于2014-9-1508:56编辑数字向上,自左向右:EBC本帖最后由paulhyde于2014-9-1508:56编辑脚朝上,外壳上的那个突起放在左边,其对应的管脚是e,然后顺时针方向依次为b和c。3DG6可以用9013代替。
- cary334002 电子竞赛
- 伺服电机转子反馈的检测相位与转子磁极相位的对齐方式
- 永磁交流伺服电机的编码器相位为何要与转子磁极相位对齐其唯一目的就是要达成矢量控制的目标,使d轴励磁分量和q轴出力分量解耦,令永磁交流伺服电机定子绕组产生的电磁场始终正交于转子永磁场,从而获得最佳的出力效果,即“类直流特性”,这种控制方法也被称为磁场定向控制(FOC),达成FOC控制目标的外在表现就是永磁交流伺服电机的“相电流”波形始终与“相反电势”波形保持一致,如下图所示:图1因此反推可知,只要想办法令永磁交流伺服电机的“相电流”波形始终与“相反电势”波形保持一致,
- eeleader 工控电子
- mini2440上USB转串口的问题,大家是如何解决的?
- 试过好几根了,都是乱码在开发ARM9mini2440时,有谁用过好用的USB转串口啊?mini2440上USB转串口的问题,大家是如何解决的?恩,我的也有问题:只能从开发板接收数据没法发送数据回复楼主bootloader的帖子Z-TEK力特的USB转通用串口线不错,收发数据正常。这个没用过呢就进入BOOTLOADER了
- bootloader 嵌入式系统
- 一个较大型的单片机系统如何设计,急!
- 各位大虾们,我刚上班不久,单片机知识只限于书本的知识,根本没实际经验,现在碰到一个设计一个单片机控制系统的难题,望各位哥哥姐姐们帮偶看下,能不能讲的详细些(最好帮我出个电路原理图),在此先谢过了~开关量:69个38输入31输出温度模拟量3路压力模拟量3路另两路模拟量输出以控制阀门开度另外从一测速电机得到一高速脉冲,对其计数而换算的到电机的速度系统的28种故障信息将与另一单片机系统通过通讯方式进行显示这系统我改如何下手啊,硬件选型我都没点眉目,各位帮下偶啊~一个较大型的单片机系
- suifengmomo 单片机
- 问个linux core文件机制相关的问题
- 内核2.6.21root文件系统下的/etc/sysctl.conf中-------------------------------kernel.core_uses_pid=1kernel.core_pattern=/logdir/core-------------------------------------(logdir目录有可写权限)/etc/profile中-------------------------------#Nocorefilesbyd
- xzl Linux与安卓
- 在工程Rebuild All 正确,但Load Program时有问题的原因!!
- 我在CCS环境中编译一个数据采集工程,结果都正确,无错误,无警告!但是在LoadProgram时出现:Dataverificationfailedataddress0x****.Pleaseverifytargetmemoryandmemorymap.这种对话框出现次数达10以上,但是每次点击确定后LoadProgram仍然会继续,最终也会出现反汇编程序.点击RUN后,程序也能运行,只是没有数据采集的结果!!请问这
- huadousjw999 模拟与混合信号
设计资源 培训 开发板 精华推荐
- 使用 Infineon Technologies AG 的 OMR7812NH 的参考设计
- 使用 NXP Semiconductors 的 TDF8541 的参考设计
- EVAL-INAMP-82RZ,用于评估仪表放大器 AD8228 的评估板
- 使用 LT3045HDD 并联多个线性稳压器以提供 2A 输出电流的典型应用
- 使用 Analog Devices 的 LT3091IT7 的参考设计
- 交通信号控制系统
- 电路显示了一个使用 LT1616 的 2.5V 输出电路
- DRV8870&AT8221
- STGIPS30C60 SLLIMM 小型低损耗智能模塑模块 I PM、三相逆变器的典型应用 - 30 A、600 V 短路坚固型 IGBT
- ADA4610-2BRZ-R7等效前置放大光电二极管电路典型应用电路