可调光手电筒电路及程序如下:
#include <tiny13.h>
#include <delay.h>
//IO--寄存器定义
#define PB0 0 //tiny13第5脚
#define PB1 1 //tiny13第6脚
#define PB2 2 //tiny13第7脚
#define PB3 3 //tiny13第2脚
#define PB4 4 //tiny13第3脚
#define PB5 5 //tiny13第1脚
#define SM0 3
#define SM1 4
#define SE 5
//控制寄存器EECR位名设置
#define EERE 0 //读使能
#define EEPE 1 //编程使能
#define EEMPE 2 //准备好中断使能
#define EERIE 3 //主机编程使能
#define EEPM0 4 //EEPROM编程模式位
#define EEPM1 5 //
//LED亮度基数设置
#define lum3 0xff //亮度1--最亮
#define lum2 0x50 //亮度2
#define lum1 0x10 //亮度3
#define lum0 0x00 //亮度4--关
#define led_dis() (PORTB&=~(1<<PB1)) //LED低电平有效
#define led_en() (PORTB|=(1<<PB1)) //LED高电平有效
#define pwm_en() (PORTB&=~(1<<PB3)) //PWM开
#define pwm_dis() (PORTB|=(1<<PB3)) //PWM关
unsigned char lum; //亮度
unsigned char count;
unsigned char count1;
bit flag;
bit time_flag;
//=======================================================================
//eeprom写一个字节数据
//变量:address--地址 data--数据
//
//=======================================================================
void eep_write(unsigned char address,unsigned char data)
{
//等待上一次写操作结束
while(EECR&(1<<EEPE));
//设置编程模式
EECR=(0<<EEPM1)|(0>>EEPM0);
//设置地址和数据寄存器
EEAR = address;
EEDR = data;
//置位EEMPE
EECR |= (1<<EEMPE);
//置位EEWE,启动写操作
EECR |= (1<<EEPE);
}
//=======================================================================
//eeprom读一个字节数据
//变量:address--地址
//
//=======================================================================
unsigned char eep_read(unsigned char address)
{
//等待上一次写操作结束
while(EECR&(1<<EEPE));
//设置地址寄存器
EEAR=address;
//设置EERE以启动读操作
EECR |= (1<<EERE);
//自数据寄存器返回数据
return(EEDR);
}
//=======================================================================
//定时器T0溢出中断
//
//
//=======================================================================
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
count++;
if(count>=200)
{
count=0;
flag=~flag;
if(flag) led_en();
else led_dis();
}
}
//=======================================================================
//设备初始化
//
//
//=======================================================================
void init_devices(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
//IO口初始化
PORTB = 0xff;
DDRB = 0x02;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 9600.000 kHz
// Mode: Fast PWM top=FFh
// OC0A output: Inverted PWM
// OC0B output: Inverted PWM
TCCR0A=0x21;
TCCR0B=0x0a;
TCNT0=0x00;
OCR0A=0xff;
OCR0B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
MCUCR=0x00;
GIMSK=0x00;
PCMSK=0x00;
GIFR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
#asm("sei") //打开全部中断
//MCUCR|=(1<<SM1)|(0<<SM0); //掉电模式
//MCUCR|=(1<<SE); //休眠使能
//#asm ("sleep"); //开机后进入中断
}
//=======================================================================
// 主程序
//
//
//=======================================================================
void main(void)
{
init_devices();
delay_ms(10);
lum=eep_read(0x01); //读取eeprom里的数据
lum++;
if(lum>=4) lum=0;
eep_write(0x01,lum); //写eeprom里的数据
led_dis();
TIMSK0=0x00;
TCCR0A=0x00;
TCCR0A=0x21;
switch(lum)
{
case 0: OCR0B=lum1;
break;
case 1: OCR0B=lum2;
break;
case 2: OCR0B=lum3;
break;
case 3: OCR0B=lum3; //闪
TCCR0A=0x01;
TIMSK0=0x02;
default: OCR0B=lum1;
break;
}
while (1)
{
}
}
我是用EEPROM做记录的,只有一个电源开关/
这是本人在网上找的一个手电筒电路和程序,PWM调光,ATtiny13中文资料如附件,因为初次接触AVR单片机,上面程序一些红色的代码是我不懂得地方(我现在只看到红色代码的地方,下面的还没看,可能下面还会有不懂的),请大侠们帮小弟讲解一番。首先是EEPROM读写子程序,资料上也是这个例程,但是就是不太懂,<<符合应该是左移吧?其次,定时/计算器0的溢出中断子程序函数名前面加interrupt [TIM0_OVF] 是不是就是一种固定格式,表明此函数就是定时器0的溢出中断处理程序?再次,这几句
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
是啥意思,pragma我查了下,还是不理解,optsize-和optsize+是什么东西?
请高手帮小弟解释解释,再拜,万分感谢!