Atmega16
于定時(shí)器0相關(guān)的寄存器有 SREG 全局中斷 bit7 I
TIMSK中斷屏蔽寄存器 bit 0:1 TOIE0 OCIE0
OCIE0輸出比較允許標(biāo)志位
TCCR0 timer0控制寄存器 bit0:7
WGM00:WGM01 模式控制位;
COM01:COM00 各PWM模式中 具體設(shè)置位:
CS00 CS01 CS02 時(shí)鐘選擇位 于定時(shí)器2公用
TCNT0 定時(shí)器0寄存器八位放置定時(shí)器初值
OCR0 定時(shí)器0比較匹配寄存器與TCNT0值比較
TIFR 中斷標(biāo)志寄存器
OCF0 比較匹配中斷標(biāo)志位
下邊我們編程先從簡(jiǎn)單的定時(shí)器計(jì)數(shù)開始
程序部分
#include<iom16v.h>
#include"dis.h" //595驅(qū)動(dòng)顯示頭文件
unsigned char i,temp;
void inittimer0(void)//定時(shí)器0初始化函數(shù)
{
TCCR0|=(1<<CS00)|(1<<CS02);//普通計(jì)數(shù)模式,1024分頻
TCNT0=0X00; //賦值
SREG=0X80; //全局中斷打開
TIMSK|=(1<<TOIE0); //定時(shí)器0溢出中斷使能
}
void main(void)
{
DDRC|=0X07; //595控制端口初始化
inittimer0(); //定時(shí)器初始化
dis(0); //顯示函數(shù)
while(1){ }
}
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf(void)///定時(shí)器中斷
{
i++;
if(i>=4)
{
i=0;
temp++;dis(temp);//數(shù)值自加,顯示;
}
} 仿真部分
下邊源碼中更改TCCR0的配置可決定那種跳變沿觸發(fā)
下降沿觸發(fā) TCCT0|=(1<<CS02)|(1<<CS01);
上升沿觸發(fā) TCCT0|=(1<<CS02)|(1<<CS01)|(1<<CS00);
注意這里的上升沿是T0口處于低電平狀態(tài),發(fā)生了高電平的跳變,配置不需要改變,上升沿下降沿端口配置是一樣的
//通過T0引腳觸發(fā)中斷
#include<iom16v.h>
void initTimer0(void)
{
TCCR0|=(1<<CS02)|(1<<CS01); //下降沿觸發(fā),(1<<CS00)上升沿觸發(fā)
TCNT0=0XFE; //賦值通過按鍵將寄存器值填滿產(chǎn)生中斷
TIMSK|=(1<<TOV0); //定時(shí)器0溢出中斷
SREG|=0X80; //全局中斷
PORTD|=(1<<PD0); //初始化T0引腳
DDRC=0XFF; //中斷產(chǎn)生動(dòng)作端口初始化
}
void main(void)
{
initTimer0();
while(1);
}
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf(void)
{
TCNT0=0XFE; //寄存器重裝
PORTC=~PORTC; //動(dòng)作
}
下邊介紹定時(shí)器0 的PWM功能,通過上邊對(duì)定時(shí)器的了解下邊也會(huì)很簡(jiǎn)單的掌握。選擇相位修正模式,WGM00=1;WGM01=0;無分頻,CS02=0;CS01=0;CS00=1;
比較匹配選擇在升序計(jì)數(shù)發(fā)生比較匹配將清零OC0,降序計(jì)數(shù)發(fā)生時(shí)比較匹配將OC0置位.相應(yīng)控制位COM00=0,COM01=1;TCCR0|=(1<<WGM00)|(1<<COM01)|(1<<CS00);
比較匹配寄存器賦值,比較匹配中斷向量為:20
#include<iom16v.h>
void initpwmt0(void) //編寫人張小強(qiáng)日期13,09,17
{
TCCR0|=(1<<WGM00)|(1<<COM01)|(1<<CS00);//相位修正PWM
TIMSK|=(1<<OCIE0); //輸出匹配使能
SREG|=0X80; //全局中斷使能
TCNT0=0X00; //定時(shí)器寄存器
OCR0=0X80; //比較匹配寄存器
DDRB|=(1<<DDB3); //比較匹配輸出引腳初始化
}
void delaymsPWM(unsigned int z)
{
unsigned int x,y;
for(x=1000;x>0;x--)
for(y=z;y>0;y--);
}
void main()
{
initpwmt0();
while(1)
{
OCR0++;delaymsPWM(10); //定時(shí)自加
}
} //比較匹配中斷
#pragma interrupt_handler timer0_comp:20
void timer0_comp(void)
{}