操作步骤:
一、捕获输入端口初始化:捕获输入端ICP1(PD6)设为输入,DDRD&=(0<<PD6);
并使能PD6口的内部上拉电阻,PORTD|=(1<<PD6);
二、设置定时器的工作模式:TCCR1A=0X00 //普通模式,计数最大值为65535
三、设置分频系数: 1024分频,TCCR1B|=(1<<CS12)|(0<<CS11)|(1<<CS10);
四、开启捕捉噪声抑制器:TCCR1B|=(1<<INCN1);
五、 设置捕捉触发方式: TCCR1B|=(0<<ICES1) ; //下降沿触发
六、输入捕捉使能: TIMSK|=(1<<TICIE1);
七、计数器初始化: TCNT1=0;
八、中断总使能: SREG=0x80;
//函数功能:检测ICP1(PD6)脚上的电平变化,(代码来自轻松玩转avr单片机c语言cd)
#include <iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#define beep_0 (PORTD=PORTD&0x7f) //PD7上的蜂鸣器发声
#define beep_1 (PORTD=PORTD|0x80) //PD7上的蜂鸣器不发声
uint count;
/********以下是延时函数********/
void Delay_ms(uint xms)
{
int i,j;
for(i=0;i<xms;i++)
{ for(j=0;j<1140;j++) ; }
}
/********以下是端口初始化函数********/
void port_init()
{
DDRA = 0Xff; //PA口设为输出
PORTA = 0Xff; //PA口输出高电平
DDRD &=(0<<PD6); //PD6(ICP1)口为输入捕捉口
PORTD |=(1<<PD6); //使能PD6的内部上拉电阻,平时该口为高电平
DDRD |=(1<<PD7); //PD7(蜂鸣器)为输出口
PORTD |=(1<<PD7); //PD7输出高电平
}
/********以下是定时器1初始化函数********/
void timer1_init()
{
TCCR1A=0X00; //设置为普通模式
TCCR1B |= (1<<ICNC1)|(1<<CS10)|(1<<CS12); //开启输入捕捉口的噪声抑制器,时钟1024分频,下降沿捕捉
TIMSK |= (1 << TICIE1); //输入捕捉使能
TIMSK |= (1 << TOIE1); //溢出中断使能
TCNT1=0; //计数初值
SREG=0x80; //使能全局中断
}
/*********以下是主函数*********/
int main(void)
{
port_init();
timer1_init();
while(1);
}
/********定时/计数器1的输入捕捉中断服务程序********/
#pragma interrupt_handler timer1_CAPT:6
void timer1_CAPT(void) //输入捕捉端口有下降沿电平,则触发中断
{
TCNT1 = 0; // 清零计数寄存器,下一次仍从0开始计数
if(ICR1>23438) //判断两次按键之间的间隔是否大于3s
{
ICR1 = 0; //清零输入捕捉寄存器
PORTA =~PORTA; //LED状态翻转
}
}
/********定时/计数器1的溢出中断服务程序********/
#pragma interrupt_handler timer1_OVR:10
void timer1_OVR(void)
{
beep_0;
Delay_ms(100);
beep_1;
Delay_ms(100);
}