AVRPWM波设置
AVR汇编百例 - 脉宽调制(PWM)

;脉宽调制(PWM)输出程序;范例50 ;以定时器定时产生精确半秒信号,以PD5输出精确秒号.ORG $000 ;晶体实测频率为8000367HZSTRT40: RJMP RST40 ;USE 8535.ORG $008 ;t/C1 overflow vectorRJMP T1_OVF.ORG $011RST40: LDI R16,HIGH(ramend)OUT SPH,R16LDI R16,LOW(ramend)OUT SPL,R16SBI DDRD,5 ;PD5(OC1A)为输出CBI PORTD,5 ;初始输出为低LDI R16,2 ;8分频INT(8000367/8)=1000046) 折半500023定半秒OUT TCCR1B,R16 ;T/C1控制寄存器(I/O ADDR:$2E)LDI R16,$5E ;500023=65536*8-24265=$10000*8-$5EC9OUT TCNT1H,R16 ;TCC=$5EC9 先写高位字节LDI R16,$C9OUT TCNTIL,R16LDI R16,$04OUT TIMSK,R16 ;允许T/C1溢出中断/8535C/t1:timsk,2&t0:timsk,0LDI R17,8 ;8次中断定半秒CLR R16OUT TIFR,R16 ;清除定时/计数器中断标志SEI ;HH40: RJMP HH40 ;背景程序略T1_OVF: IN R5,SREG ;保存状态寄存器DEC R17BRNE COMP1 ;定时时间到?IN R16,PORTD ;读入PD5当前状态LDI R17,$20EOR R16,R17 ;求反PD5(OC1A)输出OUT PORTD,R16IN R17,TCNT1L ;*IN R16,TCNT1H ;*读回TCNT1计数值SUBI R17,$37 ;*SBCI R16,$A1 ;*减去$5EC9之补码$A137SUBI R17,$FF ;*补偿指令8条占一个计数单位SBCI R16,$FF ;*补偿后TCC=$5EC9+(TCNT1)+1OUT TCNT1H,R16 ;*OUT TCNT1L,R17 ;*写入TCNT1LDI R17,8 ;重新写入中断次数COMP1: OUT SREG,R5RETI;范例51 ;以比较匹配A达到时交替输出高低电平及写入其维持;时间常数之方法实现脉宽调制输出.ORG $000STRT41: RJMP RST41 ;5.008MS(高):10.000MS(低) 晶振4MHZ .ORG $006RJMP T1_CMPA ;USE 8535.ORG $011RST41: LDI R16,HIGH(RAMEND)OUT SPH,R16LDI R16,LOW(RAMEND)OUT SPL,R16LDI R16,$80 ;T/C1比较匹配A达到时,清除输出脚oc1aOUT TCCR1A,R16LDI R16,$0B ;64分频ctc1=1 比较匹配达到清tcnt1OUT TCCR1B,R16SBI DDRD,5SBI PORTD,5 ;pd5(oc1a)初始化输出为高CLR R16OUT TCNT1H,R16 ;予清除tcnt1OUT TCNT1L,R16LDI R16,1OUT OCR1AH,R16LDI R16,$39 ;写比较匹配寄存器(313*0.25*64=5.008MS)OUT OCR1AL,R16LDI R16,$10OUT TIMSK,R16 ;允许比较匹配A中断SEIHH41: RJMP HH41 ;背景程序略T1_CMPA:IN R5,SREGIN R16,TCCR1ASBRS R16,6RJMP OUTLOW ;当前输出低电平,转LDI R16,1OUT OCR1AH,R16LDI R16,$39 ;写入高电平维持时间313OUT OCR1AL,R16LDI R16,$80 ;比较匹配A达到时,OC1A输出为低OUT TCCR1A,R16OUT SREG,R5RETIOUTLOW: LDI R16,2OUT OCR1AH,R16LDI R16,$71 ;写入低电平维持时间625(=$271) (625*0.25*64=10.000MS) OUT OCR1AL,R16LDI R16,$C0 ;比较匹配A达到时,OC1A输出为高OUT TCCR1A,R16OUT SREG,R5RETI;范例52 ;以比较匹配达到时求反输出并按高低电平写入.ORG $000 ;维持时间之方法实现脉宽调制输出STRT42: RJMP RST42 ;5.008MS(高):10.000MS(低) 晶振4MHZ .ORG $006RJMP T1_CMPA.ORG $011RST42: LDI R16,HIGH(ramend)OUT SPH,R16LDI R16,LOW(RAMEND)OUT SPL,R16LDI R16,$40 ;比较匹配A达到时,对OC1A输出求反OUT TCCR1A,R16LDI R16,$0C ;256分频ctc1=1 比较匹配达到时清除cnt1 OUT TCCR1B,R16SBI DDRD,5 ;PD5(oc1a)为输出SBI PORTD,5 ;初始输出为高CLR R16OUT TCNT1H,R16 ;清除tcnt1OUT TCNT1L,R16OUT OCR1AH,R16LDI R16,78 ;高电平时间常数78OUT OCR1AL,R16LDI R16,$10OUT TIMSK,R16 ;允许比较匹配A中断SEIHH42: RJMP HH42 ;背景程序略T1_CMPA:IN R5,SREG ;IN R16,PORTDSBRC R16,5RJMP T1CM1 ;当前oc1a为高,转LDI R16,0OUT OCR1AH,R16LDI R16,156 ;低电平时间常数156OUT OCR1AL,R16OUT SREG,R5RETIT1CM1: LDI R16,0OUT OCR1AH,R16LDI R16,78 ;高电平时间常数78OUT OCR1AL,R16OUT SREG,R5RETI;模/数转换和数/模转换及脉宽调制输出应用;范例53 ;模拟量采集和3路脉宽调制输出(OCR1A/OCR1B&OCR2)综合程;序/晶振4MHZ.ORG $000STRT50: RJMP RST50 ;avr is AT90S8535.ORG $00ERJMP ADCOM ;模数转换完成中断.ORG $011RST50: LDI R16,HIGH(ramend)OUT SPH,R16LDI R16,LOW(ramend)OUT SPL,R16 ;堆栈指针初始化CLR R11 ;通道号初始化CLR R12CLR R13 ;累加和予清除OUT $07,R11 ;ADC通道初始化,指向0#通道LDI R16,$6C ;T/C2为自运行pwm输出,加法计数匹配清除OC2,减法计;数匹配置位OC2(正向PWM);对晶振64分频OUT TCCR2,R16 ;tccr2' ADDR.:$25LDI R16,$ED ;使能,启动ADC/自由运行/转换完成中断/对晶振32分频OUT ADCSR,R16 ;ADDR:$06 adc控制状态寄存器IN R16,ASSRCBR R16,8OUT ASSR,R16 ;TCNT2 用主时钟!INC R11OUT $07,R11 ;予切换到1号ADC通道SBI DDRD,4SBI PORTB,4 ;pd4:oc1bSBI DDRD,5 ;pd5:oc1a pd4,pd5 皆为输出oc1b初始输出为高SBI DDRD,7 ;oc2 输出LDI R16,$E3 ;0B11100011,自运行PWM,COM1A1/0=11,COM1B1/0=10 OUT TCCR1A,R16 ;减法计数匹配清除OC1A,加法计数匹配置位OC1A(反向PWM);加法计;数匹配清除OC1B,减法计数匹配置位OC1B(正向PWM)LDI R16,2OUT TCCR1B,R16 ;tcnt1 8分频LDI R16,0OUT TCNT1H,R16 ;wr.high B at firstOUT TCNT1L,R16 ;清除TCNT1OUT TCNT2,R16 ;清除TCNT2OUT DDRA,R16 ;A口输入OUT PORTA,R16 ;输入为高阻态SEICOMLP: CPI R11,1BREQ COMLP ;通道号初始为1,等待切换过去COML0: CPI R11,1BRNE COML0 ;通道号再次为1时,0#通道正在转换,7#通道已转换完毕,;已得到8个A/D采样累加和ASR R12ROR R13ASR R12ROR R13ASR R12ROR R13 ;累加和除以8BRCC COML1CLR R16ADC R13,R16ADC R12,R16 ;四舍五入COML1: OUT OCR1AH,R12OUT OCR1AL,R13OUT OCR1BH,R12OUT OCR1BL,R13 ;10位数据写入比较匹配寄存器ASR R12ROR R13ASR R12ROR R13BRCC COML2INC R13BRNE COML2DEC R13COML2: OUT OCR2,R13 ;8位数据写入比较匹配寄存器CLR R12CLR R13 ;累加和清除RJMP COMLPADCOM: IN R15,ADCL ;ADC完成中断IN R14,ADCHADD R13,R15 ;模拟数值加入累加和ADC R12,R14INC R11SBRC R11,3CLR R11 ;total 8 chanales!&8 CHANGED TO 0OUT $07,R11 ;$07:admux'address REGISTERRETI;范例54 ;以R-2R电阻网络和C口配合组成DAC与输入模拟量比较实现模数转换.ORG $000 ;电阻网络DAC最大输出(AIN0)只能达到3.32V(PCi输出只能达到5V)STRT51: RJMP RST51 ;输入模拟量最大为4.98V,故应将DAC输出放大1.5倍再与前者比较.ORG $011 ;也可将输入模拟量衰减为2/3再与DAC输出比较RST51: LDI R16,2 ;但应将转换结果乘以1.5以使其复原,程序取后者OUT SPH,R16 ;堆栈指针初始化LDI R16,$5FOUT SPL,R16SER R16OUT DDRC,R16 ;C口全部为输出,DAC输出为AIN0输入CLR R16OUT DDRB,R16 ;B口为输入LDI R16,$F3OUT PORTB,R16 ;PB2(AIN0),PB3(AIN1)输入为高阻状态CLR R15 ;模数转换结果予清除LDI R16,$80 ;逼近增量初始值CMPLP: ADD R15,R16 ;模数转换阶段值加逼近增量OUT PORTC,R15 ;转成模拟量NOPNOPNOP ;4MHZ/等待1微秒SBIC ACSR,ACO ;输入模拟量大于DAC模拟量,清除ACOSUB R15,R16 ;否则去掉逼近增量LSR R16 ;逼近增量折半BRNE CMPLP ;逼近增量变为0?MOV R16,R15 ;*是,转换结束LSR R15 ;*ADC R15,R16 ;*将转换结果乘以1.5HH50: RJMP HH50 ;背景程序略范例55 ;40点平均在r18r19,累加和在r5r6r7;20点平均在R14R15,累加和在R1R3R4 SLPA V: PUSH R26 ;采样在R8R9,采样数据存储区$150--$19F/工作寄存器r1--r19&r26 r27PUSH R27LDI R27,1LDS R26,$14F ;数据存储区首地址$14FADD R7,R9ADC R6,R8 ;采样加入40点平均累加和BRCC SLP1INC R5 ;有进位,高位字节增1ADC R3,R8 ;采样加入20点平均累加和BRCC SLP2INC R1 ;有进位,高位字节增1SLP2: LD R16,XST X+,R9MOV R9,R16 ;置换出最旧采样低位字节LD R16,XST X+,R8MOV R8,R16 ;置换出最旧采样高位字节CPI R26,$A0BRNE SLPA1LDI R26,$50 ;采样放满存储区后,指针初始化($1A0=$150)STS $14F,R26LDS R16,$A4SBRC R16,4RJMP SLPA2 ;40点平均时间达到,转SBR R16,$10 ;设置40点平均时间达到标志STS $A4,R16RJMP SLDIV ;转去计算40点平均SLPA1: STS $14F,R26 ;暂存指针LDS R16,$A4SBRS R16,4RJMP SLPB0 ;还未到40点平均,转SLPA2: SUB R7,R9SBC R6,R8 ;到40点平均后除加上新采样外,还要减去最旧采样BRCC SLDIVDEC R5 ;不够减,高位字节减1SLDIV: CLR R12LDI R16,40MOV R11,R16CLR R10MOV R13,R5MOV R14,R6MOV R15,R7RCALL DIV165 ;计算40点平均MOV R18,R14MOV R19,R15 ;存入r18r19SLPB0: CPI R26,$78BRNE SLPB1LDS R16,$A4SBRC R16,3RJMP SLPB2SBR R16,8 ;建20点平均时间到标志RJMP SLPDV ;SLPB1: LDS R16,$A4SBRS R16,3RJMP SLRET ;20点平均时间未到SLPB2: SUBI R26,42 ;指针退回42字节,指向20点平均最旧数据CPI R26,$50 ;不小于80,未超出采样数据存储区BRCC SLPB20SUBI R26,-80 ;否则加80调整回$150-$19FSLPB20: LD R11,X+ ;LD R10,XSUB R4,R11SBC R3,R10 ;找到20点平均最旧采样,并将其从累加和中减去!BRCC SLPDVDEC R1SLPDV: LDI R16,20MOV R11,R16CLR R10CLR R12MOV R13,R1MOV R14,R3MOV R15,R4RCALL DIV165 ;20点平均在r14r15中SLRET: POP R27POP R26RET。
AVR单片机项目8.4 PWM

项目8.4 PWM模式调光控制
【项目任务】
利用ATmega16单片机内部的定时/计数器的PWM 功能,对LED灯进行调光控制,通过外部信号触 发,改变PWM的占空比实现LED灯渐明渐暗显示 效果。
【项目任务】
自主搭建硬件电路(硬件实际电路图)
【项目知识点与技能点】
知识点:
1、ATmega16单片机的定时/计数器2的结 构、类型及其功能。 2 、与定时 / 计数器 2 有关的寄存器的功能 及设置。 3、定时/计数器2快速PWM模式
【项目知识准备】
二、定时器工作模式:快速PWM模式
OC2---PD7
OC2输出的PWM波形的频率:
256
N代表分频因子(1、8、64、256或1024)。
【项目知识准备】
二、定时器工作模式:快速PWM模式
PWM原理框图如下图所示:
S1
时钟源
定时器计数器
溢出标志TF
S2 中断请求
比较器
PWM输出
比较寄存器
PWM输出的最大特点是波形的频率恒定,波 形的占空比D却可以改变。占空比的改变很具有实 际意义,例如小功率直流电机的驱动与调速,其方 法就是控制电机电枢电压接通和断开的比值来驱动 电机和改变电机的转速,这种方法称为脉宽调速法。
【项目知识准备】
一、 PWM输出原理与方法 PWM为脉冲宽度调制。PWM输出的一般形式为一系列 的脉冲波形。如下图所示。 设脉冲的周期为,高电平持续时间为t,则t与之比定义 为PWM的“占空比”,用D表示,即D=t/。
【项目知识点与技能点】
技能点:
1 、掌握单片机系统内部定时 / 计数器 2 和定 时的使用方法,并能合理运用到实际项目 中; 2、通过C语言和汇编语言编程实现对单片机 内部定时计数器2的配置; 3、系统硬件设计的实现,功能的软件技术实 现以及功能实现的综合调试能力。
AVR 快速PWM模式

第7.3章快速PWM模式7.3.1概述嗯~自从编辑上一篇CTC笔记,心理就产生了这样一个问题?应不应该加入逻辑框图|逻辑单位呢?我承认自己本身是想象力丰富概念能力好,但是不能承认所有人都是我,而且自己的学习习惯一向都是“先建立概念,明白原理,实践,最后就是记录”,所以呢,“适合”就成为问题了...7.3.2快速PWM概念提起快速PWM就越来越不佩服AVR的强大,很显然AVR就是c51的杀手。
其实快速PWM 的概念也很简单,首先我们依然先假设OCnx就是PD4或者PD5引脚输出的电平。
比起CTC,快速PWM多出这样的概念:就是匹配值(COMPARE),和第最高值(TOP)。
在初始阶段里,TCNTn计数器会一直进行1累加,在前两个最大值的产生不影响OCnx的电平变化(传言中,是采集初始化中所以电平没有变化),但是依然会产生中断。
当地三个TCNTn计数期里,就有明显的作用了。
当TCNTn的值匹配与匹配值时(黄色圆点),OCnx的电平就开始置零,该匹配不产生中断。
随着TCNTn的值会继续累加,当TCNTn的值达TOP值时,换一句话说,OCnx的电平就会置一,然后产生中断(该中断是溢出中断还是匹配中断,视设置为定)。
该过程会一直重复,直到永远。
从上面的分析中,我们知道我们需要一个匹配值和一个TOP值,而TOP值可以是固定的8~10位,或者由OCR1A决定(视方波产生模式位而定),如果以OCR1A决定TOP值,那么就得牺牲OCRA该输出引脚了,这里就不详细的介绍了,后文会继续。
在快速PWM模式中,匹配值和TOP值是与OCRxA或者OCRxB有关,除此之外还与预分频设置,工作模式,引脚设定,方波产生模式位有莫大的关系。
在以上的时序图中,Period就是我们想要的频率。
7.3.3与快速PWM相关的寄存器(定时器1为例)为了能更好的明白,我们先看以上的图先,快速PWM所选择的模式有5,6,7,14,15。
而5,6,7的TOP值被固定了,这显然很没有人性化(但是有时候也是必须的),所以从中我们仅能选择第14和15模式。
AVR定时计数器0,1,2的相位可调PWM模式彻底应用

/***********AVR定时计数器0,1,2的相位可调PWM模式彻底应用***********************FileName : adjustablePWM.cAuthor : 沧海麒麟Date : 2011.05.28Version : 1.0Clock Frequency :8 MHZDescription : 适用于ATmega16(L)AVR的3个定时计数器相位频率PWM模式查询与中断的基本应用*/#include <iom16v.h> //常用头文件,如有需要可以查库文件include#include <avrdef.h>#include <macros.h>#include <string.h>#include <math.h>//#include "delay.c"//#include "LCM1602.c"#define uint unsigned int#define uchar unsigned char/*****************T/C0*********************************/void Timer0PCPWM_Init(uchar temp);void Timer0PCPWM_NquiryMode(uchar temp);//T/C0查询方式函数void Timer0PCPWM_InterruptMode(uchar temp);//T/C0中断方式函数/*****************T/C2*********************************/void Timer2PCPWM_Init(uchar temp);void Timer2PCPWM_NquiryMode(uchar temp);//T/C2查询方式函数void Timer2PCPWM_InterruptMode(uchar temp);//T/C2中断方式函数/*****************T/C1**********************************/void Timer1PCPWM_10_Init(uint top,uint temp);//T/C1波形产生模式:CTC4 void Timer1PCPWM_11_Init(uint top,uint temp);//T/C1波形产生模式:CTC12 void Timer1PCPWM_A_NquiryMode(uint temp);//T/C1比较匹配A查询方式函数void Timer1PCPWM_B_NquiryMode(uint temp);//T/C1比较匹配B查询方式函数void Timer1PCPWM_InterruptMode(uint temp);//T/C1中断方式函数void main(void){//占空比为1/5Timer0PCPWM_Init(51);//245HzTimer2PCPWM_Init(51);Timer1PCPWM_10_Init(1249,250);//50HZ//Timer1PWM_14_Init(1249,250);while (1);}/*******定时计数器的函数*******************//*与8位T/C0相关的寄存器1:T/C0计数寄存器TCNT0,输出比较寄存器OCR0,定时计数器中断屏蔽寄存器TIMSK 定时计数器中断标志寄存器TIFR,T/C0控制寄存器TCCR02:每计数一次需要的时间是(1/Xtal)*N us在此程序中Xtal=8,N定义为与分频系数N:1,8,64,256,10241 : TCCR0|=0x01;//0:无时钟,系统不工作8 : TCCR0|=0x02;64 : TCCR0|=0x03;256 : TCCR0|=0x04;1024: TCCR0|=0x05;//0x06:时钟由T0引脚输入,下降沿触发 0x07:时钟由T0引脚输入,上升沿触发*//***********************************************************/void Timer0PCPWM_Init(uchar temp){//Foc0pwm = Fclk/(510N)DDRB |= 0X08;TCNT0 = 0x00;TCCR0 = 0x40|0x20|0x03; //PWM设置|OC0触发方式的设置|预分频设置OCR0 = temp;//在此程序中Xtal=8,N定义为与分频系数N:1,8,64,256,1024//1 : TCCR0|=0x01;//0:无时钟,系统不工作//8 : TCCR0|=0x02;//64 : TCCR0|=0x03;//256 : TCCR0|=0x04;//1024: TCCR0|=0x05;}/********************************************************/void Timer0PCPWM_NquiryMode(uchar temp)//T/C0查询方式函数while(!(TIFR&0x02));TIFR=0x02;OCR0 = temp;//Focnpwm = Fclk/N(1+TOP)}/*********************************************************/void Timer0PCPWM_InterruptMode(uchar temp)//T/C0中断方式函数{CLI(); //disable all interruptsTCCR0 = 0x00; //stopTCNT0 = 0x00;TCCR0 = 0x40|0x20|0x03; //PWM设置|OC0触发方式的设置|预分频设置OCR0 = temp;MCUCR = 0x00;GICR = 0x00;TIMSK = 0x02; //timer interrupt sourcesSEI(); //re-enable interrupts //SREG|=BIT(7);//开启总中断}/*********************************************************/#pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP //20void timer0_comp_isr(void){//compare occured TCNT0=OCR0}/***********************************************************//*与8位T/C2相关的寄存器1:T/C2计数寄存器TCNT0,输出比较寄存器OCR2,定时计数器中断屏蔽寄存器TIMSK 定时计数器中断标志寄存器TIFR,T/C2控制寄存器TCCR22:每计数一次需要的时间是(1/Xtal)*N us在此程序中Xtal=8,N定义为与分频系数N:1,8,64,256,10241 : TCCR2|=0x01;//0:无时钟,系统不工作8 : TCCR2|=0x02;32 : TCCR2|=0x03;64 : TCCR2|=0x04;128 : TCCR2|=0x05;256 : TCCR2|=0x06;1024: TCCR2|=0x07;*//***********************************************************/void Timer2PCPWM_Init(uchar temp){//Foc0pwm = Fclk/(510N)DDRD |= 0X80;TCNT2 = 0x00;TCCR2 = 0x40|0x20|0x04; //PWM设置|OC2触发方式的设置|预分频设置OCR2 = temp; //Focnpwm = Fclk/N(1+TOP)}/***********************************************************/void Timer2PCPWM_NquiryMode(uchar temp)//T/C2查询方式函数{while(!(TIFR&0x80));TIFR=0x80;OCR2 = temp;}/***********************************************************/void Timer2PCPWM_InterruptMode(uchar temp)//T/C2中断方式函数{CLI(); //disable all interruptsTCCR2 = 0x00; //stopTCNT2 = 0x00; //set count//temp=6,N=64:2000us;计数250次TCCR2 = 0x40|0x20|0x04; //PWM设置|OC2触发方式的设置|预分频设置OCR2 = temp;MCUCR = 0x00;GICR = 0x00;TIMSK = 0x80; //timer interrupt sourcesSEI(); //re-enable interrupts //SREG|=BIT(7);//开启总中断}#pragma interrupt_handler timer2_comp_isr:iv_TIM2_COMP //4void timer2_comp_isr(void){//compare occured TCNT2=OCR2}/***********************************************************//*与16位T/C1相关的寄存器1:T/C1计数寄存器TCNT1H和TCNT1L,输出比较寄存器OCR1A(H/L)和OCR1B(H/L), 定时计数器中断屏蔽寄存器TIMSK,定时计数器中断标志寄存器TIFR,T/C1控制寄存器TCCR1A和TCCR1B2:每计数一次需要的时间是(1/Xtal)*N us在此程序中Xtal=8,N定义为与分频系数N:1,8,64,256,1024//1 : TCCR1B=0x01;//0:无时钟,系统不工作//8 : TCCR1B=0x02;//64 : TCCR1B=0x03;//256 : TCCR1B=0x04;//1024: TCCR1B=0x05;//0x06:时钟由T1引脚输入,下降沿驱动 0x07:时钟由T1引脚输入,上升沿驱动*//***********************************************************/void Timer1PCPWM_10_Init(uint top,uint temp){DDRD |= 0x30;TCNT1H = 0x00;TCNT1L = 0x00;TCCR1A = 0x80|0x20|(1 << WGM11)|(0 << WGM10); //OC1A&OC1B的触发方式设置|PWM 设置TCCR1B = (1 << WGM13)|(0 << WGM12)|0x03;//PWM设置|预分频设置ICR1 = top; //Focnpwm = Fclk/(2N*TOP)OCR1A = temp;OCR1B = temp;}/***********************************************************/void Timer1PCPWM_11_Init(uint top,uint temp){DDRD |= 0x30;TCNT1H = 0x00;TCNT1L = 0x00;TCCR1A = 0x80|0x20|(1 << WGM11)|(1 << WGM10); //OC1A&OC1B的触发方式设置TCCR1B = (1 << WGM13)|(0 << WGM12)|0x03;//PWM设置|预分频设置OCR1A = top; //Focnpwm = Fclk/(2N*TOP)OCR1B = temp;//说明还有8 9 10位相位修正PWM可用}/******************************************************************/void Timer1PCPWM_A_NquiryMode(uint temp)//T/C1比较匹配A查询方式函数{while(!(TIFR&0x10));TIFR = 0x10;OCR1A = temp; //Focnpwm = Fclk/(2N*TOP)}/*********************************************************/void Timer1PCPWM_B_NquiryMode(uint temp)//T/C1比较匹配B查询方式函数{while(!(TIFR&0x08));TIFR = 0x08;OCR1B = temp; //Focnpwm = Fclk/(2N*TOP)}/*******************中断方式函数视具体情况而定***************************/ void Timer1PCPWM_InterruptMode(uint temp)//T/C1中断方式函数{CLI(); //disable all interruptsDDRD |= 0x30;TCNT1H = 0x00;TCNT1L = 0x00;TCCR1A = 0xA0|(1 << WGM11)|(1 << WGM10); //OC1A&OC1B的触发方式设置|PWM设置 TCCR1B = (1 << WGM13)|(1 << WGM12)|0x03;//PWM设置|预分频设置OCR1A = temp;OCR1B = temp; //Focnpwm = Fclk/(2N*TOP)MCUCR = 0x00;GICR = 0x00;TIMSK = 0x18; //timer interrupt sourcesSEI(); //re-enable interrupts //SREG|=BIT(7);//开启总中断}/*********************************************************/#pragma interrupt_handler timer1_compa_isr:iv_TIM1_COMPA //7void timer1_compa_isr(void){//compare occured TCNT1=OCR1A}#pragma interrupt_handler timer1_compb_isr:iv_TIM1_COMPB //8void timer1_compb_isr(void){//compare occured TCNT1=OCR1B}。
AVR单片机定时器CTC输出PWM模式

AVR单片机定时器CTC输出PWM模式
第一篇:AVR单片机定时器CTC输出PWM模式
CTC:比较匹配时清零计数器模式。
当计数器TCNT0的数值等于比较寄存器OCR0时计数器TCNT0自动清零。
OCR0定义了计数器的最大(TOP)值,这个模式使得用户可以很容易地控制比较匹配输出的频率。
T/C0的比较输出脚为OC0(PB3),PB口的第三脚,在此模式下可以在OC0上输出PWM控制外部设备。
例如:在OC0脚上输出20HZ的方波信号,方波的周期时间为T=1/20HZ=0.05秒=50ms,半个周期为25ms,系统采用8MHZ晶振,1024分频,时钟计数频率为8000000/1024=7812.5HZ,每个时钟脉冲时间为1/7812.5=0.128ms,定时25ms的计数值为25ms/0.128ms=195,将195赋值为T/C0的比较寄存器OCR0,启动定时器后,TCNT0从0开始计数,当计数到195时,产生比较中断,在OC0脚上输出20HZ的占空比为50%的方波信号。
操作过程如下:
一、I/O管脚初始化:PB3(OC0)脚设为输出,DDRB|=(1<
二、使能全局中断:SREG=0X80;。
AVR单片机实现的直流电机PWM调速控制器

控制软件设计。设计了。可实现两个编码器信号的采集。 对INT1的中断次数计数来测量通道B的脉冲数,读取PC6 (即A相信号)的电平状态来判断电机
的转动方向。以上升沿触发为例,即当B路信号的上升沿 引起中断时,单片机判断PC6信号的电平高低。若PC6为 低电平,则电机为正转,计数器N的值加
动接口软件的程序如下:outocrlaH,temp19是控制输出 量,其再以PWM形式输出outocrlaL,tempi8为正传位反 转3,从实
验曲线可以看出,超调量小于10%,稳定时间为150ms左 右,稳态误差小于5%.系统具有较好的快速性和控制精度。 4结束语直流调速控制器采用AV
R单片机8535,实现了对直流电机的PWM调速控制。从实 际运用来看,它较好的实现了对直流电机的速度控制, 并具有精度高、快速响应性好、稳定性好
只承受单极性的电压;双极性工作方式是指在一个PWM 周期内电机电枢两端的电压呈正负变化。调速控制系统 采用的是单极性工作方式。单片机的EnB引脚
,它控制着电机转速大小;单片机的PD6或PD7经过一定 的逻辑电路接到L298的IN1~IN4输入引脚上,它控制电机 的转动方向。为了增强L29
8的驱动能力,本调速控制系统对L298的两路驱动进行了 并联使用,最大驱动能力可以达到3A.比较器LM393主要 起到了限制过流和保护L298的
Hale Waihona Puke 作用。LM393的同相端直接连到了一个可变电位计上,电 位计的电压是可调的。调节电位计的电压能调节L298的 限流电压。LM393的反相端接到L
298的SENSEA和SENSEB两检测端。当检测电阻两端的电压 大于限流电压时,比较器的反相端的电压大于同相端的 电压,输出端输出低电平,从而
第十四讲用AVR单片机定时器1产生PWM波形

第十四讲:用AVR单片机定时器1产生PWM波形实验目的AVR单片机的定时器功能非常强大,除了一般的定时、计数功能外(参见实验十三:用定时器做一个秒表),还具有PWM波形发生,捕获和比较等功能。
本实验演示AVR单片机的定时器产生PWM波形的方法。
我们用BASCOM-AVR的 BASIC 编程,配置定时器1(Timer1)工作在PWM波形产生模式。
BASIC中对定时器的配置非常简单,读者可以对照C语言和汇编语言的程序学习三者间的差别。
难度等级:初级硬件搭建取C型3位跳线将 10K模块接至 PC0 。
三号实验板的0、1引脚分别用B型2位跳线接单片机的PB1 和 PB2脚(即15,16脚,分别是OC1A 和OC1B),公共端接地。
程序代码源程序下载:Timer1_pwm.bas'----------------------------------------------------------------------------------------------------$regfile = "m48def.dat"$crystal = 8000000Config Adc = Single , Prescaler = Auto , Reference = AvccDim Lt As IntegerDim Rt As IntegerDim V As IntegerConfig Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down ,Compare B Pwm = Clear Up ,Prescale = 64Ddrb = &B00000110Start AdcStart Timer1DoV = Getadc(0)Lt = 1023 - VRt = 1023 - VPwm1a = LtPwm1b = RtLoopEnd ' 指定目标单片机为 ATmega48' 指定系统时钟8兆' 设置ADC为单次转换模式,采样频率系统设定,' 参考电压使用AVcc'''''配置定时器1位PWM波形输出模式'通道A的比较输出模式为降序计数'通到B的比较输出模式为升序计数'定时器时钟由系统时钟提供,分频数为64''配置PB1、PB2引脚输出'启动ADC转换'启动定时器1''取采样'''修改比较寄存器 Ocr1a'修改比较寄存器 Ocr1b程序讲解AVR单片机的定时器功能非常强大,除了最基本的定时和计数外,另一个重要作用是产生多种形式的PWM波形,例如快速PWM波形,相位修正PWM波形和相频修正PWM波形。
AVR事无巨细系列九,PWM演示

事无巨细,PWM 演示这几天总是很累,但是要坚持把这个系列写完。
今天讲讲PWM 。
PWM 对许多刚刚跨进电子设计的大门的朋友来说,估计是一个很陌生的名字。
当然我本人也只是是一知半解,即便如此,还是尽我所能把我知道的引导给大家。
★PWM ,英文全称为Pulse Width Modulation ,翻译过来就是脉冲宽度调制。
脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
★PWM 是一种对模拟信号电平进行数字编码的方法。
通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
★PWM 信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。
电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。
通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。
只要带宽足够,任何模拟值都可以使用PWM 进行编码。
许多微控制器内部都包含有PWM 控制器。
例如,Microchip 公司的PIC16C67内含两个PWM 控制器,每一个都可以选择接通时间和周期。
占空比是接通时间与周期之比;调制频率为周期的倒数。
★PWM 的一个优点是从处理器到被控系统信号都是数字形式的,无需进行数模转换。
对噪声抵抗能力的增强是PWM 相对于模拟控制的另外一个优点,让信号保持为数字形式可将噪声影响降到最小。
噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。
而且这也是在某些时候将PWM 用于通信的主要原因。
从模拟信号转向PWM 可以极大地延长通信距离。
在接收端,通过适当的RC 或LC 网络可以滤除调制高频方波并将信号还原为模拟形式。
总之,PWM 既经济、节约空间、抗噪性能强,是一种值得广大工程师在许多设计应用中使用的有效技术。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AVR单片机定时-计数器的PWM功能设计要点
2008-10-07 17:13:42 来源:互联网
一、定时/计数器PWM设计要点
根据PWM的特点,在使用ATmega128的定时/计数器设计输出PWM时应注意以下几点:
1.首先应根据实际的情况,确定需要输出的PWM频率范围,这个频率与控制的对象有关。
如输出PWM波用于控制灯的亮度,由于人眼不能分辨42Hz以上的频率,所以PWM的频率应高于42Hz,否则人眼会察觉到灯的闪烁。
2.然后根据需要PWM的频率范围确定ATmega128定时/计数器的PWM工作方式。
AVR定时/计数器的PWM模式可以分成快速PWM和频率(相位)调整PWM 两大类。
3.快速PWM可以的到比较高频率的PWM输出,但占空比的调节精度稍微差一些。
此时计数器仅工作在单程正向计数方式,计数器的上限值决定PWM的频率,而比较匹配寄存器的值决定了占空比的大小。
PWM频率的计算公式为:
PWM频率= 系统时钟频率/(分频系数*(1+计数器上限值))
4.快速PWM模式适合要求输出PWM频率较高,但频率固定,占空比调节精度要求不高的应用。
5.频率(相位)调整PWM模式的占空比调节精度高,但输出频率比较低,因为此时计数器仅工作在双向计数方式。
同样计数器的上限值决定了PWM的频率,比较匹配寄存器的值决定了占空比的大小。
PWM频率的计算公式为:
PWM频率= 系统时钟频率/(分频系数*2*计数器上限值))
6.相位调整PWM模式适合要求输出PWM频率较低,但频率固定,占空比调节精度要求高的应用。
当调整占空比时,PWM的相位也相应的跟着变化(Phase Correct)。
7.频率和相位调整PWM模式适合要求输出PWM频率较低,输出频率需要变化,占空比调节精度要求高的应用。
此时应注意:不仅调整占空比时,PWM的相位会相应的跟着变化;而一但改变计数器上限值,即改变PWM的输出频率时,会使PWM 的占空比和相位都相应的跟着变化(Phase
and Frequency Correct)。
8.在PWM方式中,计数器的上限值有固定的0xFF(8位T/C);0xFF、0x1FF、0x3FF(16位T/C)。
或由用户设定的0x0000-0xFFFF,设定值在16位T/C的ICP 或OCRA寄存器中。
而比较匹配寄存器的值与计数器上限值之比即为占空比。
二、PWM应用设计参考
下面给出一个设计示例,在示例中使用PWM方式来产生一个1KHz左右的正弦波,幅度为0-Vcc/2。
首先按照下面的公式建立一个正弦波样本表,样本表将一个正弦波周期分为128个点,每点按7位量化(127对应最高幅值Vcc/2):
f(x) = 64 + 63 * sin(2πx/180) x∈[0…127]
如果在一个正弦波周期中采用128个样点,那么对应1KHz的正弦波PWM的频率为128KHz。
实际上,按照采样频率至少为信号频率的2倍的取样定理来计算,PWM的频率的理论值为2KHz即可。
考虑尽量提高PWM的输出精度,实际设计使用PWM的频率为16KHz,即一个正弦波周期(1KHz)中输出16个正弦波样本值。
这意味着在128点的正弦波样本表中,每隔8点取出一点作为PWM的输出。
程序中使用ATmega128的8位T/C0,工作模式为相位调整PWM模式输出,系统时钟为8MHz,分频系数为1,其可以产生最高PWM频率为:8000000Hz / 510 =
15686Hz。
每16次输出构成一个周期正弦波,正弦波的频率为980.4Hz。
PWM
由OC0(PB4)引脚输出。
参考程序如下(ICCAVR)。
//ICC-AVR application builder : 2004-08
// Target : M128
// Crystal: 8.0000Mhz
#include <iom128v.h>
#include <macros.h>
#pragma data:code
// 128点正弦波样本表
const unsigned char auc_SinParam[128] = {
64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,109,111,113,115,117,118,120,1 21,
123,124,125,126,126,127,127,127,127,127,127,127,126,126,125,124,123,121,120,11 8,
117,115,113,111,109,106,104,102,99,96,94,91,88,85,82,79,76,73,70,67,64,60,57,54, 51,48,
45,42,39,36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,1,0,0,0,0,0,0,0,1,1,2,3,4,6 ,
7,9,10,12,14,16,18,21,23,25,28,31,33,36,39,42,45,48,51,54,57,60};
#pragma data:data
unsigned char x_SW = 8,X_LUT = 0;
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
X_LUT += x_SW; // 新样点指针
if (X_LUT > 127) X_LUT -= 128; // 样点指针调整
OCR0 = auc_SinParam[X_LUT]; // 取样点指针到比较匹配寄存器
}
void main(void)
{
DDRB |= 0x10; // PB4(OC0)输出
TCCR0 = 0x71; // 相位调整PWM模式,分频系数=1,正向控制OC0
TI MSK = 0x01; // T/C0溢出中断允许
SEI(); // 使能全局中断
while(1)
{……};
}
每次计数器溢出中断的服务中取出一个正弦波的样点值到比较匹配寄存器中,用于调整下一个PWM的脉冲宽度,这样在PB4引脚上输出了按正弦波调制的
PWM方波。
当PB4的输出通过一个低通滤波器后,便得到一个980.4Hz的正弦波了。
如要得到更精确的1KHz的正弦波,可使用定时/计数器T/C1,选择工作模式10,设置ICR1=250为计数器的上限值。
在ATMEL公司网站上,给出了使用一个定时/计数器实现双音频拨号的应用设计参考。