原创 利用T/C0定时器还可以同时实现定时中断和PWM功能

2008-5-23 16:38 3000 5 5 分类: 测试测量
利用T/C0定时器还可以同时实现定时中断和PWM功能

数码管的显示等同于OCR0,这只是一个原理性的实验,请大师们评点评点

/************************************************************
ICC-AVR application builder : 2008-4-17 16:11:30
Target : M16
Crystal: 4.0000Mhz
文件:timer_00
设计:raosibin
时间:2008-4-25
版本:ver1.0
功能说明:T/C0中断溢出实验,每4096US中断一次,刷新显示数据;
      动态扫描显示方式;每秒更新一次显示数据,
      T/C0快速PWM模式实验,每X秒更新OCR0的初值;改边PWM波型;
      通过PB3间接观察PWM的波型;      
硬件说明:PA0~PA3接数玛管的A,B,C,D;PD0~PD6接a,b,c,d,e,f,g;PB3接LED0;
**************************************************************/
#include <iom16v.h>
#include <macros.h>

const unsigned char seg7_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
                      0x6f}; //0,1......9 段码
const unsigned char position_data[]={0xf1,0xf2,0xf4,0xf8}; //0,1,2,3, 位选通
unsigned char   timer[4];             // 秒计数单元
unsigned char   posit;
volatile unsigned int   counter;
volatile unsigned char   flag_1s;
volatile unsigned char   flag_2ms;

void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0xFF;
}

void display(void)           // 4位LED数码管动态扫描函数
{
  PORTA = 0x00;  
  PORTD = seg7_data[timer[posit]];
  PORTA = position_data[posit];
  if (++posit >=4 ) posit = 0;
}

//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 2mSec
// actual value: 2.000mSec (0.0%),已修改了,不是2MS
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00; //set count
OCR0 = 0x00; //set compare
TCCR0 = 0x7B; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
//TCNT0 = 0x83; //reload counter value
flag_2ms=1;
if (++counter >=10) //改变10的值可以看到LED0变化的快慢
{
++OCR0;
counter=0;
flag_1s=1;
}
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();

MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}


void main(void)
{
timer[0]=0;
timer[1]=0;
timer[2]=0;
timer[3]=0;
init_devices();
/*计数数值调整,显示的范围为99.99S*/
while(1)
{
  if (flag_1s==1)
  {
  flag_1s=0;
  if (++timer[0]>=10)
  {
    timer[0]=0;
    if (++timer[1]>=10)
    {
      timer[1]=0;
      if (++timer[2]>=10)
      {
        timer[2]=0;
        if (++timer[3]>=10)
        {
          timer[3]=0;
        }
      }
    }
    }
  }
   
  if (flag_2ms==1)
  {
  flag_2ms=0;
  display();
  }
}
}


PS:已调试通过,T/C0还可以这样用
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条