6. avr定时器/计数器1 --TC1 --输入捕捉模式 (捕获外部事件模式)

 T/C 的输入捕捉单元可用来捕获外部事件,并为其赋予时间标记以说明此时间的发生时刻。外部事件发生的触发信号由引脚ICP1 (PD6)输入,也可通过模拟比较器单元来实现。时间标记可用来计算频率、占空比及信号的其它特征,以及为事件创建日志。当引脚ICP1 上的逻辑电平( 事件) 发生了变化,或模拟比较器输出ACO 电平发生了变化,并且这个电平变化为边沿检测器所证实,输入捕捉即被激发:16 位的TCNT1 数据被拷贝到输入捕捉寄存器ICR1,同时输入捕捉标志位ICF1 置位。如果此时ICIE1 = 1,输入捕捉标志将产生输入捕捉中断。中断执行时ICF1 自动清零,或者也可通过软件在其对应的I/O 位置写入逻辑"1” 清零。读取ICR1 时要先读低字节ICR1L,然后再读高字节ICR1H。读低字节时,高字节被复制到高字节临时寄存器TEMP。CPU 读取ICR1H 时将访问TEMP 寄存器。

操作步骤:

一、捕获输入端口初始化:捕获输入端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);
}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
定时器/计数器是嵌入式系统中常用的模块,可以用来实现计时、延时、PWM输出等功能。下面介绍一些常见的定时器/计数器的定时实验。 1. 延时实验 使用定时器/计数器实现延时功能,一般是通过设置定时器/计数器的初值和计数模式来实现的。以 8051 单片机定时器为例,可以使用以下代码实现延时 1 秒: ```c #include <reg51.h> void delay() { TMOD = 0x01; // 设置定时器0为模式1,使用定时器模式 TH0 = 0x3C; // 设置定时器初值,定时1s TL0 = 0xAF; TR0 = 1; // 启动定时器 while(TF0 == 0); // 等待定时器溢出 TR0 = 0; // 停止定时器 TF0 = 0; // 清除溢出标志 } void main() { while(1) { P1 = 0x55; // P1口输出0x55 delay(); // 延时1s P1 = 0xAA; // P1口输出0xAA delay(); // 延时1s } } ``` 2. 计时实验 使用定时器/计数器实现计时功能,一般是通过设置定时器/计数器的时钟源和计数模式来实现的。以 AVR 单片机定时器为例,可以使用以下代码实现计时 1 秒: ```c #include <avr/io.h> #include <avr/interrupt.h> volatile uint32_t timer_count = 0; // 计时器计数值 ISR(TIMER1_COMPA_vect) // 定时器1比较匹配中断服务程序 { timer_count++; // 计数器加1 } int main() { DDRB = 0xFF; // PB口设置为输出 TCCR1A = 0x00; // 定时器1模式设置为普通计数模式 TCCR1B = 0x0D; // 定时器1时钟源设置为外部时钟,分频系数为1024 OCR1A = 15624; // 定时器1比较值,计数1s TIMSK1 = (1 << OCIE1A); // 允许定时器1比较匹配中断 sei(); // 开启全局中断 while(1) { if(timer_count >= 1000) // 如果计时器计数值达到1s { PORTB = ~PORTB; // PB口翻转 timer_count = 0; // 计数器清零 } } return 0; } ``` 3. PWM输出实验 使用定时器/计数器实现 PWM 输出功能,可以通过设置定时器/计数器的时钟源、计数模式和比较匹配值来实现。以 STM32 单片机定时器为例,可以使用以下代码实现 PWM 输出: ```c #include "stm32f10x.h" int main() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 定时器分频系数为72 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 定时器计数值为1000 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500 - 1; // 比较匹配值为500 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); while(1); return 0; } ``` 以上是一些常见的定时器/计数器的定时实验,可以根据自己的需要进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值