Atmega16-定时器2的使用 step by step。
编译环境:AVR Studio 4.19 +avr-toolchain-installer-3.4.1.1195-win32.win32.x86
芯片型号:ATmega16
芯片主频:8MHz
测试说明:
1、OC2引脚输出比较匹配的波形
2、PA0在TOV2中断时取反
3、PA1在OCF2中断时取反
-------------------------------------------------------------------------------------------------------------------------------------
第零步: 阅读手册
-------------------------------------------------------------------------------------------------------------------------------------
第一步: 普通模式
1、这一步使用普通模式输出脉冲,顺便测量一下自己设置的溢出时间是否OK。
测试代码:
Drv_Timer.h
// 定时器中断模式
typedef enum
{
INT_MODE_TOV = 0,
INT_MODE_OCF = 1,
INT_MODE_ICF = 2
} TIMER_INT_MODE;
// 定时器2
typedef enum
{
T2_WGM_NOMAL = 0, // 普通模式
T2_WGM_PHASE_PWM = 1,
T2_WGM_CTC = 2,
T2_WGM_FAST_PWM = 3,
T2_COM_MODE_NONE = 0,
T2_COM_MODE_TOGGLE = 1,
T2_COM_MODE_CLEAR = 2,
T2_COM_MODE_SET = 3,
T2_CLK_SOURCE_NONE = 0,
T2_CLK_SOURCE_CLK_1 = 1,
T2_CLK_SOURCE_CLK_8 = 2,
T2_CLK_SOURCE_CLK_32 = 3,
T2_CLK_SOURCE_CLK_64 = 4,
T2_CLK_SOURCE_CLK_128 = 5,
T2_CLK_SOURCE_CLK_256 = 6,
T2_CLK_SOURCE_CLK_1024 = 7
} TIMER2_MODE;
Drv_Timer.c
// ==========================================================================================================
// 定时器0/1/2 驱动模块
// ==========================================================================================================
#include "Drv_Timer.h"
#include <avr/interrupt.h>
// ==========================================================================================================
// TIMER2 初始化
//
// 参数:wave_mode 工作模式/波形产生模式选择
// OC_mode 比较匹配/PWM输出模式选择
// clk_source 时钟源和预分频选择
//
// 写TCCR2时需要清除bit7=FOC2
//
// 定时器溢出周期 T = ((1.0 / 8000000) * 1000000) * clk_source * 256 ( @ 8MHz )
// ==========================================================================================================
void Drv_Timer2_init(const uint8_t wave_mode, const uint8_t com_mode, const uint8_t clk_source)
{
uint8_t wgm20,wgm21;
wgm20 = wave_mode & 0x01;
wgm21 = (wave_mode & 0x02) >> 1;
// 写TCCR2时需要将bit7=FOC2清0
TCCR2 = (wgm20 << 6)| // 工作模式/波形产生模式选择
(wgm21 << 3)|
((com_mode & 0x03) << 4)| // 比较匹配/PWM输出模式选择
((clk_source & 0x07) << 0); // 时钟源和预分频选择
}
// ==========================================================================================================
// TIMER2 中断使能
//
// 参数:mode = INT_MODE_TOV 或 INT_MODE_OCF 或 INT_MODE_ICF
// enable = ENABLE 或 DISABLE
//
// 可以单独使能/禁止一种模式的中断
//
// ==========================================================================================================
void Drv_Timer2_INT_Enable(const uint8_t mode, const uint8_t enable)
{
if(INT_MODE_TOV == mode)
{
if(DISABLE == enable)
{
TIMSK &= ~(1 << TOIE2);
}
else
{
TIMSK |= (1 << TOIE2);
}
TIFR |= (1 << TOV2);
}
if(INT_MODE_OCF == mode)
{
if(DISABLE == enable)
{
TIMSK &= ~(1 << OCIE2);
}
else
{
TIMSK |= (1 << OCIE2);
}
TIFR |= (1 << OCF2);
}
}
// ==========================================================================================================
// TIMER2 溢出中断服务程序
// ==========================================================================================================
ISR(TIMER2_OVF_vect)
{
PORTA ^= (1 << PA0);
}
main.c
// ==========================================================================================================
// 主函数
// ==========================================================================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include "Drv_Timer.h"
#include "config.h"
// ==========================================================================================================
// main函数
// ================================================================================&