单片机定时器产生pwm

本文介绍了一种使用AVR单片机M128通过定时器产生不同占空比PWM波形的方法。代码中详细展示了如何初始化端口、设置定时器参数,并通过切换OCR1A寄存器的值来改变PWM信号的占空比。
 
利用定时器产生不同占空比的PWM波形输出.
//ICC-AVR application builder : 2006-7-14 16:54:48
// Target : M128
// Crystal: 14.7456Mhz

#include <iom128v.h>
#include <macros.h>

//#define PWM_select  (PINC&3)

void port_init(void)
{
 PORTA = 0xFF;
 DDRA  = 0x00;
 PORTB = 0xFF;
 DDRB  = 0xFF;
 PORTC = 0x03; //输入,上拉电阻使能
 DDRC  = 0xFf;
 PORTD = 0xFF;
 DDRD  = 0x00;
 PORTE = 0xFF;
 DDRE  = 0x00;
 PORTF = 0xFF;
 DDRF  = 0x00;
 PORTG = 0x1F;
 DDRG  = 0x00;
}

//TIMER1 initialisation - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Hz
// actual value: Out of range
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0x00 /*INVALID SETTING*/; //setup
 TCNT1L = 0x00 /*INVALID SETTING*/;
 OCR1AH = 0x00 /*INVALID SETTING*/;
 OCR1AL = 0x00 /*INVALID SETTING*/;
 OCR1BH = 0x00 /*INVALID SETTING*/;
 OCR1BL = 0x00 /*INVALID SETTING*/;
 OCR1CH = 0x00 /*INVALID SETTING*/;
 OCR1CL = 0x00 /*INVALID SETTING*/;
 ICR1H  = 0x00 /*INVALID SETTING*/;
 ICR1L  = 0x00 /*INVALID SETTING*/;
 TCCR1A = 0x91;//8位PWM,
 TCCR1B = 0x02; //预分频8
}

//call this routine to initialise all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();
 timer1_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

void main(void)

  unsigned int oldtogs; //storage for past walue of input
unsigned int PWM_select=3;
  port_init();
  timer1_init();
  init_devices();
 
  while(1)
  {
 //   if (PWM_select !=oldtogs)
// {
//    oldtogs=PWM_select;
   switch (PWM_select)
   {
     case 0:
    OCR1A=25;  //10%
break;
     case 1:
    OCR1A=51;  //20%
break;
 case 2:
    OCR1A=76;  //30%
break;
 case 3:
    OCR1A=102;  //40%
break;
}
// }
   }
}  
 
单片机定时器产生PWM的方法因单片机类型不同而有所差异,下面以51单片机和STM32单片机为例进行介绍: ### 51单片机 - **方法一:使用2个定时器实现PWM**:timer0用来控制工作频率(周期),timer1用来调节占空比,需注意timer0计时周期要比timer1时间长。示例代码如下: ```c void timer0() interrupt 1 { P0^0 = 1; TR1 = 1; // 启动定时器1 } void timer1() interrupt 3 { P0^0 = 0; TR1 = 0; } ``` - **方法二:配置定时器和计数周期**:先配置定时器,设置一个计数周期,以该周期时间为基准,设置引脚高低电平时间,从而输出特定占空比的PWM波。例如让定时器计一百个数产生溢出,这一百个数的时间就是一个周期,设置前五十个数的时间某引脚为高电平,后五十个数为低电平,该引脚就会输出一个占空比为50%的PWM波 [^3]。 - **方法三:通过按键调节占空比**:判断按键状态来改变占空比。如判断按键1是否按下,按下则占空比temp增加,每按一次增加10%;判断按键2是否按下,按下则占空比temp减小,每按一次减小10%。当占空比达到100%或0%时,保持该状态 [^4]。 ### STM32单片机 - **定时器配置与参数设置**:开启定时器,设置PWM波的频率、占空比、PWM模式、有效值等参数。以下是使用Hal库产生PWM实现呼吸灯程序的示例代码: ```c // 变量定义 uint16_t pwmVal = 0; // 调整PWM占空比 uint8_t dir = 1; // 设置改变方向 1 渐亮 0 渐灭 HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); // 使能 Timer4 第3通道 PWM 输出 while (1) { HAL_Delay(1); if (dir == 1) // 渐亮方向 pwmVal++; // 逐渐提高占空比 else // 渐灭方向 pwmVal--; // 逐渐降低占空比 if (pwmVal > 498) // 超过ARR 改变方向 dir = 0; else if (pwmVal == 0) dir = 1; // 修改比较值,修改占空比 __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值