实验思路时:使用定时器0输出PWM,而且通过按键改变PWM的占空比,以及使用定时器1让LED一秒钟翻转一次
定时器1使用的晶体频率位7.3728MHz,溢出中断设定为1s、1024分频。
代码:
/************************************************************
project:TIMER工程
IDE:AVR Studio 4+ Winavr20070525
author:jqq
date:2014-3-26
goal:熟悉运用 ATmega88 定时器
*************************************************************/
#include "main.h"
//#define KEY_STATUS PORTD3
//------------------------PWM设定值
const unsigned char VAL[7]={0x10,0x30,0x50,0x73,0xA0,0xC0,0xE0};
/*---------------------------------------------------------------
功能:延时函数
变量:cnt:延时函数
返回:无
---------------------------------------------------------------*/
void Delay(uchar cnt)
{
uint i;
for(;cnt>0;cnt--)
{
for(i=0;i<3000;i++) //延时一段时间
{
asm("nop"); //空操作
}
}
}
/*--------------------------------------------------------------
功能:定时器1溢出中断服务程序
变量:无
返回:无
-------------------------------------------------------------*/
//SIGNAL(SIG_OVERFLOW1)
void timer1_ovf_isr(void)
{
TCNT1 = 0xE3DF; //重装载计数值
//LED2_XOR(); //翻转I/O
PORTD&=~_BV(7);
//Delay(5);
PORTD|=_BV(7);
}
/*------------------------------------------------------------
功能:设备初始化
变量:无
返回:无
------------------------------------------------------------*/
void DEVICE_init(void)
{
cli(); //关闭全局中断
//------------------PB口
DDRB=0X00; //未使用也定义
PORTB=0X00;
//------------------PC口
DDRC=0X00; //未使用也定义
PORTC=0X00;
//------------------PD口
DDRD=0XE0; //PD3接按键,设置为输入,PD5.6.7设置为输出
PORTD=0X68;
//-------------------------------------------------------定时器0
TCCR0A=_BV(COM0B1)|_BV(WGM01)|_BV(WGM00);//快速PWM模式
TCCR0B=_BV(CS01); //8分频
OCR0B=VAL[0];
TCNT0=0x00;
//------------------------------------------------------定时器1
TIMSK1|=_BV(TOIE1); //开启溢出中断
TCNT1=0xE3DF; //设定1s
TCCR1B=_BV(CS12)|_BV(CS10); //1024分频
sei(); //开启全局中断
}
/*------------------------------------------------------------------
功能:主函数
变量:无
返回:无,此处定义返回int类型,为了兼容AS4
-------------------------------------------------------------------*/
int main(void)
{
uint cnt;
uchar key_cnt,flag;
key_cnt=0;
flag=0;
DEVICE_init(); //设备初始?
PORTD|=_BV(7);
//LED2_ON(); //点亮LED2
///------------------------主循环-------------
while(1)
{
//------------------检测按键是否有按下--------------------
while(!(PORTD&0X08))
{
cnt++;
if(cnt>100) //延迟超出一定值,执行
{
Delay(10);
flag=1;
}
}
//-----------------------------判断标志
if(flag==1)
{
cnt=0; //清除按键计数值
//LED1_XOR(); //翻转I/O
PORTD&=~_BV(6);
PORTD|=_BV(6);
flag=0; //清零标志,确保按一次键切换一次PWM
key_cnt++; //按键次数+1