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