biying 发表于 2014-6-12 00:47:55

关于ATtiny85的互补PWM功能及死区调节(问题己解决)

本帖最后由 biying 于 2014-6-12 02:11 编辑

为了用于压电蜂鸣器推挽驱动(2.66KHZ)兼密码锁功能,我选ATtiny85,片内8M时钟,快速PWM,我进ICC和CVAVR的向导功能设置发现,这两个软件居然都没有死区调节的设置。ICC更是没有互补PWM的设置,且它的PWM频率计算中,TCNT1计算的值会误导人,其实值为0就行了。cvavr中关于ATtiny85手册中DT1A寄存器的定义更是命名为:DTVALC,为什么不定义为:DTVALA?,还有DTPS1是命名为:DTPS,用它的向导出来的PWMA & B top=OCR1C模式中怎么没有这三个(DTPS1、DT1A、DT1B)寄存器的初始化?实验的结果是OC1A和OC1B有2.7KHZ的输出,但是为什么它们的互补端PB0(_OC1A) and PB3(_OC1B)没有输出呢?我自己加了以上三个寄存器的初始值也不行。有懂的朋友可以指点一下吗?谢谢!这是我用CVAVR的向导做出来的代码

找到原因了,原来CVAVR的向导不会判断你是否需要输出反相PWM,所以端口输出是错误的,改为DDRB=0x1B就可以输出两组互补PWM了。对我这个初学者来说,这向导并不可靠,一定要熟读Datasheet啊!

#include <tiny85.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=Out Func3=In Func2=In Func1=Out Func0=In
// State5=T State4=0 State3=T State2=T State1=0 State0=T
PORTB=0x00;
DDRB=0x12;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 500.000 kHz
// Mode: PWMA & B top=OCR1C
// OC1A output: Non-Inv., /OC1A connected
// OC1B output: Non-Inv., /OC1B connected
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
PLLCSR=0x00;

TCCR1=0x55;
GTCCR=0x50;
TCNT1=0x00;
OCR1A=0x5A;
OCR1B=0x5A;
OCR1C=0xBB;
DTPS=0x03;
DTVALC=0x55;
DTVALB=0x55;

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

while (1)
      {
      // Place your code here

      }
}


然后做了个LED灯明暗变化程序

#include <tiny85.h>
#include<delay.h>
// Declare your global variables here
unsigned char LIGHT;
void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=Out Func3=In Func2=In Func1=Out Func0=In
// State5=T State4=0 State3=T State2=T State1=0 State0=T
PORTB=0x00;
DDRB=0x1B;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 500.000 kHz
// Mode: PWMA & B top=OCR1C      2.666khz2组互补PWM实验,接上4只LED灯测试结果
// OC1A output: Non-Inv., /OC1A connected
// OC1B output: Non-Inv., /OC1B connected
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
PLLCSR=0x00;
// 没有以下三行,反相端就不会有输出
DTPS=0x00;
DTVALC=0x55;
DTVALB=0x55;

TCCR1=0x55;
GTCCR=0x50;
TCNT1=0x00;
OCR1A=0x5D;
OCR1B=0x5D;
OCR1C=0xBB;


// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

while (1)
      {
      // Place your code here
       for(LIGHT=187;LIGHT>0;LIGHT--)//改变LIGHT数数值即改变PWM输出的占空比,为什么是187?因为频率设置的是2.666KHZ,OCR1C=0xBB,也就是187
                {
         OCR1A=LIGHT;
         OCR1B=LIGHT;
         delay_ms(15); //改变延时时间,就可以改变LED灯明暗变化的速度
      }
      }
}

machao 发表于 2014-6-21 23:42:13

我的方法:用向导后,再看手册确认

biying 发表于 2014-6-22 02:48:01

machao 发表于 2014-6-21 23:42
我的方法:用向导后,再看手册确认

是啊,之前我还以为向导就是万能的不会出错,这次让我明白必须熟读数据手册
页: [1]
查看完整版本: 关于ATtiny85的互补PWM功能及死区调节(问题己解决)