AVR单片机_实验3:定时器实验

曾巧文 发布于:2012-4-29 16:59 分类:AVR单片机 标签: 实验 单片机 AVR

1 实验目的

通过实验,掌握定时器的使用方法。着重掌握定时中断的使用!

2 实验内容

  1. 使用Mega16单片机的timer0产生1ms间隔的定时中断(建议采用application builder,既可以用Normal工作模式也可以使用CTC模式),(1)在定时中断中实现4位数码管的动态刷新。(2)在1ms的定时中断中设计100mS的时间标志位,在主程序中查询时间标志位,实现LED闪烁。

    2、 重新配置TImer0工作在PWM模式,用按键改变PWM的占空比,调节电机转速;

    3 实验预习要求

    仔细阅读教材中定时中断的范例;

    1. 实验步骤

    1、启动ICCAVR,创建一个工程文件,配置timer0,实现10ms的定时中断,采用Application Builder来生成初始化代码。注意:本次实验使用的IO口也要初始化,包括数码管驱动所使用的IO,按键等

    2、在定时中断中实现四位数码管的定时刷新(注:要使用上次实验课的HC595的驱动),并在定时中断中实现100ms的时间标志(时标),在主程序中查询时标,实现led(PORTC口任何一个LED都可)闪烁;

    3、重新配置TImer0工作在PWM模式,初始占空比设置为10%,然后使用按键INT1(在原理图中为SW8,连接到了单片机的PD3引脚上』来改变占空比,例如每按一次按键,占空比增加10%。

    注:实验中要使用的管脚有:PD4、PD5、PD6、PD7、PB0、PB1、PA0,PD3,各管脚连接请参照原理图。

    AVR单片机_实验3:定时器实验


    1 实验目的

    通过实验,掌握定时器的使用方法。着重掌握定时中断的使用!

    2 实验内容

    1、使用Mega16单片机的timer0产生1ms间隔的定时中断(建议采用application builder,既可以用Normal工作模式也可以使用CTC模式),(1)在定时中断中实现4位数码管的动态刷新。(2)在1ms的定时中断中设计100mS的时间标志位,在主程序中查询时间标志位,实现LED闪烁。

    2、重新配置TImer0工作在PWM模式,用按键改变PWM的占空比,调节电机转速;

    3 使用Mega16单片机的timer0产生1ms间隔的定时中断(建议采用application builder,既可以用Normal工作模式也可以使用CTC模式),写出采用的工作模式,以及定时器各个寄存器的值。

       

    //ICC-AVR application builder : 2012-1-1 17:03:52
    // Target : M16
    // Crystal: 1.0000Mhz
    
    #include <iom16v.h>
    #include <macros.h>
    
    //定义字符表 		   														
    unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    		 	  			 0x80,0x90,0xff,0x7f,0xc6,0x00};
    						 
    unsigned char Disp_data[4]={0x01,0x02,0x03,0x04};
    						 
    #define CLR_SHCLK()  		PORTB&=~(1<<1)		  //移位时钟 SCLK
    #define SET_SHCLK()  		PORTB|=(1<<1)		  //移位时钟 SCLK,上升沿
    
    #define CLR_STCLK()  		PORTB&=~(1<<0)		  //锁存时钟 RCLK
    #define SET_STCLK()  		PORTB|=(1<<0)		  //拉高锁存时钟,上升沿
    
    #define CLR_DS()			PORTA&=~(1<<0)		  //清零
    #define SET_DS()			PORTA|=(1<<0)		  //置位
    
    
    
    void HC595_send_byte(unsigned char SndData)
    {
        char i;
        for(i=0;i<8;i++)
        {  
            if(SndData&(1<<(7-i)))
            {
                SET_DS();
            }
            else
            {
                CLR_DS();
            }
    		CLR_SHCLK();		  //移位时钟 SCLK
            SET_SHCLK();		  //移位时钟 SCLK,上升沿
        }
    	CLR_STCLK();			  
    	SET_STCLK();			  //拉高锁存时钟,上升沿
    }
    
    void port_init(void)
    {
     PORTA = 0xff;
     DDRA  = 0x01;
     PORTB = 0x00;
     DDRB  = 0x03;
     PORTC = 0x00; //m103 output only
     DDRC  = 0x00;
     PORTD = 0x00;
     DDRD  = 0xf0;//控制PORTD状态为输出状态,1为输出状态
    }
    
    //TIMER0 initialize - prescale:64
    // WGM: CTC
    // desired value: 1KHz
    // actual value:  0.977KHz (-2.4%)
    void timer0_init(void)
    {
     TCCR0 = 0x00; //stop
     TCNT0 = 0xF1; //set count
     OCR0  = 0x0F;  //set compare
     TCCR0 = 0x0B; //start timer
    }
    
    #pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP
    
    int j = 4;
    void timer0_comp_isr(void)
    {
      PORTD = 0xff;//输出1,全部灭灯
      HC595_send_byte(led_7[j]);
      PORTD &= ~(1 << j);//第j位置1 后取反,则为0; 任何数&(与) x & 0 =0
      if(++j > 7)
      {
         j = 4;
      }
     //compare occured TCNT0=OCR0
    }
    
    //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 = 0x02; //timer interrupt sources
     SEI(); //re-enable interrupts
     //all peripherals are now initialized
    }
    
    int main()
    {
       init_devices();
       while(1);
    }

     

     

    4 在定时中断中实现4位数码管的动态刷新。(只写出定时中断相关的代码,本部分要借用上次实验课实现的HC595的驱动函数

     

        

    //ICC-AVR application builder : 2012-1-1 18:11:21
    // Target : M16
    // Crystal: 1.0000Mhz
    
    #include <iom16v.h>
    #include <macros.h>
    
    //定义字符表 		   														
    unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    		 	  			 0x80,0x90,0xff,0x7f,0xc6,0x00};
    						 
    unsigned char Disp_data[4]={0x01,0x02,0x03,0x04};
    						 
    #define CLR_SHCLK()  		PORTB&=~(1<<1)		  //移位时钟 SCLK
    #define SET_SHCLK()  		PORTB|=(1<<1)		  //移位时钟 SCLK,上升沿
    
    #define CLR_STCLK()  		PORTB&=~(1<<0)		  //锁存时钟 RCLK
    #define SET_STCLK()  		PORTB|=(1<<0)		  //拉高锁存时钟,上升沿
    
    #define CLR_DS()			PORTA&=~(1<<0)		  //清零
    #define SET_DS()			PORTA|=(1<<0)		  //置位
    
    
    void HC595_send_byte(unsigned char SndData)
    {
        char i;
        for(i=0;i<8;i++)
        {  
            if(SndData&(1<<(7-i)))
            {
                SET_DS();
            }
            else
            {
                CLR_DS();
            }
    		CLR_SHCLK();		  //移位时钟 SCLK
            SET_SHCLK();		  //移位时钟 SCLK,上升沿
        }
    	CLR_STCLK();			  
    	SET_STCLK();			  //拉高锁存时钟,上升沿
    }
    
    void port_init(void)
    {
     PORTA = 0x01;
     DDRA  = 0xFF;
     PORTB = 0x03;
     DDRB  = 0x03;
     PORTC = 0x00; //m103 output only
     DDRC  = 0x00;
     PORTD = 0xF0;
     DDRD  = 0xF0;
    }
    
    //TIMER0 initialize - prescale:64
    // WGM: CTC
    // desired value: 1KHz
    // actual value:  0.977KHz (-2.4%)
    void timer0_init(void)
    {
     TCCR0 = 0x00; //stop
     TCNT0 = 0xF1; //set count
     OCR0  = 0x0F;  //set compare
     TCCR0 = 0x0B; //start timer
    }
    
    #pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP
    char j;
    void timer0_comp_isr(void)
    {
      if(j < 4) 
      {
       j = 7;
      }
      PORTD = 0xff;
      HC595_send_byte(led_7[j - 4]);
      PORTD &= ~(1 << j);
      j--; 
     //compare occured TCNT0=OCR0
    }
    
    //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 = 0x02; //timer interrupt sources
     SEI(); //re-enable interrupts
     //all peripherals are now initialized
    }
    int main()
    {
      init_devices();
      while(1);   
      
    }

     

    5、在1ms的定时中断中设计100mS的时间标志位,在主程序中查询时间标志位,实现LED闪烁。(只写定时中断服务程序和实现LED闪烁的功能代码)

     

    //ICC-AVR application builder : 2012-2-17 20:17:14
    // Target : M16
    // Crystal: 1.0000Mhz
    
    #include <iom16v.h>
    #include <macros.h>
    char time_is_ok;
    unsigned int timer=0; 
    void port_init(void)
    {
     PORTA = 0x00;
     DDRA  = 0x00;
     PORTB = 0x00;
     DDRB  = 0x00;
     PORTC = 0xff; //m103 output only
     DDRC  = 0xff;
     PORTD = 0x00;
     DDRD  = 0x00;
    }
    
    //TIMER0 initialize - prescale:8
    // WGM: CTC
    // desired value: 1KHz
    // actual value:  0.992KHz (-0.8%)
    void timer0_init(void)
    {
     TCCR0 = 0x00; //stop
     TCNT0 = 0x83; //set count
     OCR0  = 0x7D;  //set compare
     TCCR0 = 0x0A; //start timer
    }
    
    #pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP
    void timer0_comp_isr(void)
    {
     //compare occured TCNT0=OCR0
     if(++timer > 200)
     {
       timer = 0;
       time_is_ok = 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 = 0x02; //timer interrupt sources
     SEI(); //re-enable interrupts
     //all peripherals are now initialized
    }
    
    void main()
    {
      init_devices();
      while(1)
      {
        if(time_is_ok)
    	{
    	  time_is_ok = 0;
    	  PORTC ^= 1;
    	}
      }
    }

     






版权所有:《曾巧文博客-关注互联网IT技术,记录生活点滴》 => 《AVR单片机_实验3:定时器实验
本文地址://qiaowen.net/post-1185.html
除非注明,文章均为 《曾巧文博客-关注互联网IT技术,记录生活点滴》 原创,欢迎转载!转载请注明本文地址,谢谢。

有 4808 人浏览,获得评论 0 条

发表评论:

Powered by emlog 粤ICP备12040901号

>>本作品采用-知识共享署名-非商业-禁止演绎-协议-进行许可 |站点地图 | | | | 开放分类目录 |