📄 main.c
字号:
/***********************************************
**** AVR 利用T/C0定时中断控制舵机转动角度范例 ***
**** MCU: ATmega16 ***
**** 作者: maweili ***
**** 编译器:WINAVR ***
**** ***
**** 2009.3.2 ***
***********************************************/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> //中断函数头文件
#include "key.h" //包含按键定义头文件
volatile unsigned char Counter500us;
//计时变量,如果在中断中调用全局变量,必须加volatile来定义,否则变量不会变化
unsigned char jiaodu;
int main(void)
{
//没有用到的管脚全部设置为输入脚,使能内部上拉电阻
DDRB = 0x01;
PORTB = 0xfe;
DDRC = 0x00;
PORTC = 0xff;
DDRA = 0x00;
PORTA = 0xff;
//T/C0定时中断设置
TIMSK |= (1 << TOIE0); //T/C0溢出中断允许
TCCR0 |= (1 << CS02) | (1 << CS00); // T/C0工作于普通模式,1024分频
TCNT0 = 0xfa; //定时初值设置,定时时间 = (256-250)/12M*1024=500us
Counter500us = 0; // 500us计时变量清零
jiaodu = 1;
sei(); //使能全局中断
while(1)
{
//根据键值设置角度值
switch(KeyValue())
{
case 1:
jiaodu = 2;
break;
case 2:
jiaodu = 3;
break;
case 3:
jiaodu = 4;
break;
case 4:
jiaodu = 5;
break;
case 0:
//PORTB = 0x00;
break;
default:
break;
}
}
}
//T/C0定时中断服务程序
ISR(TIMER0_OVF_vect )
{
TCNT0 = 0xfa; //重装计数初值
if(Counter500us < jiaodu) //判断0.5ms的次数是否小于角度标识
{
PORTB = 0x01; //小于,则继续发送高电平
}
else
{
PORTB = 0x00; //大于,则输出低电平
}
Counter500us++; //0.5ms次数加1
Counter500us = Counter500us % 40; //0.5ms次数始终为40,既保持脉冲周期为20ms
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -