[求助] 关于ATtiny13A的一段程序

whwshiyuan1984   2011-12-16 11:01 楼主

可调光手电筒电路及程序如下:

ourdev_427556[1].jpg

 

#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+是什么东西?

请高手帮小弟解释解释,再拜,万分感谢!

 

 

 

回复评论 (2)

回复 楼主 whwshiyuan1984 的帖子

大师们,亮剑吧,灰常感谢了
点赞  2011-12-16 16:12

回复 楼主 whwshiyuan1984 的帖子

三请大师出山,谢谢了。再拜,谢谢!
点赞  2011-12-17 10:20
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复