Atmega8输出PWM波的仿真实验
- 格式:doc
- 大小:844.50 KB
- 文档页数:5
第五讲定时/计数器的学习提要:主要学习ATmega8的T/C0、T/C1和T/C2三个定时/计数器的应用。
前面我们学习了ATmega8的通用I/O口的应用和外部中断的应用,相信你一定会觉得自己进步很快吧。
好了接下来我们就进行定时/计数器的学习:5.1 ATmega8定时/计数器的特点:ATmega8共有3个定时/计数器:Timer/Counter0—8bit、Timer/Counter1—16bit 和Timer/Counter2—8bit。
这三个定时/计数器除了能够实现通常的定时和计数功能外,还具有捕捉、比较、脉宽调制(PWM)输出、实时时钟计数等功能。
5.2 8位定时/计数器0—T/C0介绍T/C0主要有一下特点:1. 8bit字长,最大可计数0xFF;2. 单通道计数器;3. 外部事件计数;4. 频率发生器;5. 带10位预定比例分频器。
学习应用T/C0之前我们首先要了解几个相关的寄存器:TCCR0、TCNT0、TIMSK和TIFR。
一.T/C0控制寄存器TCCR0的[2:0]位CS0[2:0]:时钟源选择。
CS02 CS01CS00 说明0 0 0 无时钟源,停止T/C00 0 1 系统时钟0 1 0 CLKio/8来自预分频器0 1 1 CLKio/64来自预分频器1 0 0 CLKio/256来自预分频器1 0 1 CLKio/1024来自预分频器1 1 0 外部T0脚,下降沿驱动1 1 1 外部T0脚,上升沿驱动对该寄存器的理解可以与INT0的MCUCR作类比,那里是选择外部中断的触发方式,这里是选择T/C0的时钟源。
另外这里作几点说明:A 当时钟源选择系统时钟时,系统内部时钟直接作为T/C0的时钟源,这是最高频率的时钟源。
B 选择预分频器作时钟源,预定分频器对系统时钟CLKio按四个不同的分频比例分频,输出4个不同周期的时钟信号CLKio/8、CLKio/64、CLKio/256、CLKio/1024。
一、设计内容该设计是利用A VR mega8L内部的定时/计数器可输出PWM波以及LED灯器件,设计一个按键可调LED灯亮度的电路。
设计的电路,通过两个按键,可以调节单片机输出PWM 波的占空比,从而调节LED灯的亮度。
二、基本原理PWM波是由mega8L的内部定时/计数器输出的。
Mega8的快速PWM模式可用来产生高频的PWM波,在TCNT1里设置TOP值,再设置TCR1A的值用之与TCNT1的值匹配产生PWM。
然后利用这个原理,改变TCR1A寄存器的值来调控PWM波的占空比,从而令一个周期内的高低电平产生变化,输出到LED灯上,LED灯的亮暗就会随着高低电平而变化。
三、系统硬件设计1)电源系统:此电源系统的功能是将AC220V经过整流,降压输出5V的DC供mega8的运行。
在稳压部分用四个电容滤波,两个470u电解电容用于滤去高频波,两个0.1u贴片电容用于滤去低频波。
2)Avr mega8单片机系统:此系统用于发生PWM波,按键1和2用于调节PWM的占空比。
LED1用于检测调节PWM波是否成功。
LED前选择330欧电阻用于限流,防止电流过大而容易引至LED灯烧坏。
LED2位置的是总电压4.9V,4.9/330=0.015A=15mA,符合LED工作电流小于20mA的要求。
四、系统软件程序的设计1)流程图:2)C语言程序:#include <iom8v.h>#include <macros.h>void port_init(void){PORTB = 0x02; //端口输出高电平DDRB = 0x02; //初始化PB1为输出口PORTC = 0x30; //内建上拉电阻打开DDRC = 0x00; //初始化PC4、PC5为输入口PORTD = 0x00;DDRD = 0x00;}void timer1_init(void){TCCR1B = 0x00; //stopTCNT1 = 0x00ff; //setup //设置TOP值为0x00ffTCCR1A = 0b10100001; //COM1A1、COM1B1、WGM10置位TCCR1B = 0b00001001; //WGM12、CS1置位//设置T1计数寄存器为8位快速PWM模式;无预分频}//call this routine to initialize all peripheralsvoid init_devices(void){//stop errant interrupts until set upCLI(); //disable all interruptsport_init();timer1_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x00; //timer interrupt sourcesSEI(); //re-enable interrupts//all peripherals are now initialized}void dalaynms(unsigned int j) //延时程序{unsigned char i;while(j>0) //当输入j=500,延时约500ms{for(i=0;i<187;i++){asm("nop"); //插入汇编空操作指令,目的是耗掉cpu的一个周期}j--;}}void main(){unsigned char l=64;init_devices();OCR1A = 64;while(1) //检测按键按下否{if((PINC&(1<<PC5))==0) //当键2按下,PWM波占空比减少{dalaynms(500); //延时程序,防抖动l-=6.4;OCR1A=l;if(l<=6.4){l=6.4; //当占空比等于十进制6.4之后,不再减少OCR1A=l;}}if((PINC&(1<<PC4))==0) //当键1按下,PWM波占空比增大{dalaynms(500);l+=6.4;OCR1A=l;if(l>=128) //当占空比等于十进制128后,不再增大{l=128;OCR1A=l;}}}}今次设计,将PWM波分20级,最大值为十进制的128,每一级为十进制数的6.4,因为占空比到50%时,LED灯已经足够亮,再继续增大高电平的比例LED灯的亮度已经无明显变化。
atmega8 例程:T1 定时器快速PWM
/** 函数库说明:ATMEGE8 T1 定时器快速PWM* 版本:v1.0
* 修改:庞辉* 修改日期:2011 年08 月11 日* *
说明:OC1A 20khz 50%占空比* OC1B 10khz 33%占空比* 且在溢出中断中频率不断改变*
* 版本更新:*
*注意:快速PWM 模式WGM1=5,6,7,14,15 * 单斜波计数,用于输出
高频率的PWM 信号(比双斜波的高一倍频率) * 都有TOV1 溢出中断,发
生于TOP 时* 比较匹配后可以产生OCF1x 比较匹配中断. * WGM1=5 时, 最大值为0x00FF,8 位分辨率* WGM1=6 时, 最大值为
0x01FF,9 位分辨率* WGM1=7 时, 最大值为0x03FF,10 位分辨率* WGM1=14 时,最大值由ICF1 设定,TOP 时产生ICF1 输入捕捉中断(单缓冲) * WGM1=15 时,最大值由OCR1A 设定,TOP 时产生OCF1A 比较匹配中断(双缓冲,但OC1A 将没有PWM 能力,最多只能输出方波) *
改变TOP 值时必须保证新的TOP 值不小于所有比较寄存器的数值* 注意,即使OCR1A/B 设为0x0000,也会输出一个定时器时钟周期的窄脉冲,而
不是一直为低电平* 计算公式:fPWM=fclk_IO/(N*(1+TOP))/#include
#include interrupt.h>int main(void){//PB1 PB2 设置为输出模式DDRB |= (1 tips: 感谢大家的阅读,本文由我司收集整编。
仅供参阅!。
基于ATmega8的无刷直流电机电调的设计摘要本文通过以ATmega8单片机为核心,分析了无刷直流电机的原理,从硬件和软件两个方面阐述了无刷直流电机的电调的设计,其中硬件包含了电流的检测、电机换相、电池电压检测、反电势过零检测,软件主要完成了系统程序、场效应管的自检程序、反电势检测程序、以及PPM解码程序。
经过测试该电调能够满足系统的设计需求。
【Key】ATmega8 无刷电机电调笔者在指导学生课外航模兴趣小组的过程中,发现无刷直流电机电调的使用比较频繁,而且很多成品电调不能满足设计需要,所以指导学生完成了此电调的设计,该电调可以直接与无线遥控器相连,通过测试性能稳定,以下是该电调设计中的原理和软硬件系统。
1 无刷直流电机的原理在点与磁的转换过程中主要有三个基本原理,左手定则、右手定则、安培定则。
左手定则用来判断在磁场中载流导体的受力方向,右手定则用来判断切割磁感线的导体产生的电流方向,安培定则用来判断磁感线的环绕方向,无刷电机相关参数的判断和程序的设计基础就是以上三个基本原理。
本系统电调的设计是基于外转子无刷直流电机设计的,该电机的KV值为1000,其采用的结构是12绕组14极(即7对极)。
电机换相的时机只取决于转子的位置,在该系统的设计中采用的是三相的感生电动势的方法来判断定子的位置,该方法的优点是不需要在系统中增加相应的器件,缺点是电机启动时可控性较差。
电机的调速是通过直流电压来控制,单片机通过用PWM方式来控制电机的输入电压,通过PWM占空比的变化来转换为不同大小的等效电压。
2 电调硬件电路的设计2.1 电流检测电路电流检测部分应用一段阻值大小为0.01欧姆的导线,经过MOSFET和电机的电流全都从它那里经过导线而流向GND,通过导线的电流和电阻的阻值相乘从而得到了产生的电压值大小,经过电阻和电容器进行一阶低通滤波,最后接入ATmega8的ADC6通道,通过对于电流值大小的判断实现了对于电流值检测功能。
万事开头难啊!本来说写一个简单的例子想着想着就复杂了,算了为了初学者学习,还是先从简单的说起吧!先来给大家说一下什么是脉冲宽度调制(PWM)。
脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写,简称脉宽调制。
它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量,通信,功率控制与变换等许多领域。
一种模拟控制方式,根据相应载荷的变化来调制晶体管栅极或基极的偏置,来实现开关稳压电源输出晶体管或晶体管导通时间的改变,这种方式能使电源的输出电压在工作条件变化时保持恒定。
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。
通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。
电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。
通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。
只要带宽足够,任何模拟值都可以使用PWM进行编码。
多数负载(无论是电感性负载还是电容性负载)需要的调制频率高于10Hz,通常调制频率为1kHz 到200kHz之间。
许多微控制器内部都包含有PWM控制器。
例如,Microchip公司的PIC16C67内含两个PWM控制器,每一个都可以选择接通时间和周期。
占空比是接通时间与周期之比;调制频率为周期的倒数。
执行PWM操作之前,这种微处理器要求在软件中完成以下工作:* 设置提供调制方波的片上定时器/计数器的周期* 在PWM控制寄存器中设置接通时间* 设置PWM输出的方向,这个输出是一个通用I/O管脚* 启动定时器* 使能PWM控制器PWM的一个优点是从处理器到被控系统信号都是数字形式的,无需进行数模转换。
让信号保持为数字形式可将噪声影响降到最小。
噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。
延时输出pwm实验报告1. 实验目的本实验旨在通过使用延时输出脉冲宽度调制(PWM)信号,控制LED灯的亮度,并进一步了解PWM的工作原理和应用。
2. 实验器材和材料- Arduino开发板- LED灯- 220Ω电阻- 面包板- 连接线3. 实验原理PWM是一种通过改变脉冲信号的占空比来控制电气设备的一种方法。
使用Arduino开发板上的PWM输出引脚可以调整输出脉冲的高和低电平时间,从而控制LED的亮度。
PWM信号的频率一般是固定的,高电平持续时间和低电平持续时间比例的变化来控制电器设备的工作状态。
在Arduino中,可用的PWM输出引脚有特殊标志,如“~3”、“~5”、“~6”、“~9”、“~10”和“~11”。
4. 实验步骤步骤1:硬件连接1. 将Arduino开发板连接到电脑上,并打开Arduino IDE软件。
2. 将LED的正极连接到Arduino的PWM输出引脚(例如,引脚9),将LED 的负极连接到电阻,然后将电阻的另一端连接到Arduino的地(GND)引脚。
步骤2:编写程序在Arduino IDE中编写以下程序:cppconst int ledPin = 9; PWM输出引脚void setup() {pinMode(ledPin, OUTPUT); 设置LED引脚为输出模式}void loop() {analogWrite(ledPin, 128); 设置PWM输出信号的占空比为50%delay(1000); 延时1秒analogWrite(ledPin, 0); 设置PWM输出信号的占空比为0%delay(1000); 延时1秒}步骤3:上传程序将开发板通过USB线缆与电脑相连,并点击Arduino IDE菜单中的“上传”按钮,将程序上传至开发板。
步骤4:观察实验结果LED灯应该开始闪烁,并且每隔1秒变亮一次。
5. 实验结果及分析经过实验,我们成功地使用延时输出PWM信号控制了LED灯的亮度。
前言学习单片机也有一段时间了,从模电、数电开始,一直到51、AVR回想起来真是一个漫长的过程啊。
我大学本是学的数学,开始就喜欢电脑这个东东,自然也就慢慢开始学习编程。
大学都被考试给耽误了,什么等级考试,程序员考试,从大二一直忙到大四,毕业了才发现自己除了比别人多了三四个证书外,别的就再没什么了。
编程除了学习谭老师的C和考二级时用TC 外,大二就开始接触VC了,但直到毕业也没把它玩转。
工作了,到公司才知道别人怎样用VC,后来在网上也认识了更多的高手,才发现自己的幼稚。
工作不到半年,就去了深圳,离开了内地,我才发现写程序要和单片机结合起来才更有前途,当然,也许我的认识到现在还是错误的。
因而回来之后我就找机会学习单片机,好在在大学考三级和高程时有一点硬件的理论,要不我想学起来就更难了。
也感谢现在网络资源丰富,我就BT了些资料,开是补充自己的硬件知识。
开始学习51时,朋友推荐了Protues,哇,第一次我就爱上她了,很快我找了些例子就把学到的理论给复习了一下;接下来我就进攻Atmega8了,因为我工作也用AVR的单片机,这样会方便些。
学习的过程是漫长的,但我并感觉不到辛苦,因为网上有那么多的朋友的例子,有那么多的资料供我去学习,还有我的女友的支持,我能感觉到的只是对知识的渴望。
为了更好的学习,我也买了块开发板,对学习的投资,我还是舍得的,呵呵。
但买回来发现,基本上那上面的功能,在Protues里都能实现,现在对ATmega8也基本了解了,我就想抽时间把自己学习的过程给整理一下,也给那些经济比较困难的学弟学妹们一点帮助。
同时也希望能有更多的朋友能奉献一点自己的热心,把自己的心得和经验贡献出来。
我希望自己总结的这份资料,可以在不用开发板的情况下去学习ATmega8,在您的电脑上装上Protues和icc Avr就可以了,我用的是Protues6.9和icc AVR6.3。
还没有回头整理,里面会有很多的错误,希望您发现了能发个email给我young45@。