⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atmega8 timer.c

📁 基于ATmega8的电机驱动程序
💻 C
字号:
/****************************************************************************** 
程序名称:电机驱动程序 
运行平台:ATMaga8 4m晶振 
程序版本:2.0 
程序说明:通过按键 或A/D输入来调节pw波 
         pc0-pc4 对应 r3-r1(pc3 作为ad输入) 
       pwm 波通过pc5输出 
       当a/d输入有效时,键盘自动屏蔽 
        

键盘说明 
                   [rest]   [+]  [-] 
      [none] [none] [none ] 
        
作者:Gorgon Meducer 

最后修改:Gorgon Meducer 
修改时间:2004年12月29日 

******************************************************************************/ 

#include <iom8v.h> 
#include <macros.h> 

#pragma  interrupt_handler Timer1_ovf:9 
#pragma  interrupt_handler Adc_isr:15   // 
const char DispCode[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6, 
0xee,0x3e,0x9c,0x7a,0x9e,0x8e}; //数码管译码表 
const char DispBit[] = {0b11101111,0b11011111,0b10111111,0b01111111};//数码管初始位值 

unsigned char Mark_Line=0x80; 

//定时器延时 
unsigned int Timer_Count_End=0; 
unsigned int Timer_Count=0; 

//unsigned char PressKey_Per_n_Timer_Ovf=0;   //定义按键时间计数器 
unsigned char Press_Keys=0;    //按键代码 

/***************************************************************************/ 
 void Port_init(void); 
 void Timer0_init(void); 
 void Timer1_init(void); 
 void Timer1_ovf(void); 
 void Hardware_init(void); 
 void Delay_ms(unsigned int delay_time); 
 void Key_Press_Scan(void); 
 void adc_init(void); 
 void Display_Message(unsigned char Where,unsigned char Number,unsigned char delays); 
  
/***************************************************************************/ 

/*************************************************************************** 
                      端口初始化 
****************************************************************************/ 
void Port_init(void) 
{ 
 //定义c为输入 
 DDRC =0b11111111; 
 PORTC=0b11111111; 
 DDRC =0b00100000;   //PC5用来输出pw波 
  
 //定义B口为输出,用于显示数据 
 DDRB=0xff; 
 PORTB=0xff; 
  
 //定义D口为输出,用于显示数据 
 DDRD=0xff; 
 PORTD=0x00; 
  
} 

/*************************************************************************** 
                      定时器0初始化 
****************************************************************************/ 
//TIMER0 initialize - prescale:1 
// desired value: 20KHz 
// actual value: 20.000KHz (0.0%) 
//定时器0用来产生PW波 
void Timer0_init(void) 
{ 
 TCCR0 = 0x00; //stop 
 TCNT0 = 0x38; //set count 
 TCCR0 = 0x01; //start timer 
} 

/*************************************************************************** 
                      定时器1初始化 
****************************************************************************/ 
//定时器1主要用来做精确延时 
void Timer1_init(void)                      
{ 
 //定时器1部分 
     TCNT1H = 0xE0;  
     TCNT1L = 0xC0;  
    TCCR1B = 0x01;                       //1分频,定时1ms 
} 

/*************************************************************************** 
                      A/D初始化 
****************************************************************************/ 
void adc_init(void) 
{ 
 ADCSRA =0X00; //关闭AD 
 ADMUX = 0b00100011; //选择外部参考电源 ADC3 左对齐 
 ACSR = (1<<ACD); //关闭模拟比较器 
 ADCSRA = 0b10011110;//中断允许 64分频 
 } 
/*************************************************************************** 
                      A/D中断处理 
****************************************************************************/ 
void Adc_isr(void) 
{ 
 Mark_Line=ADCH; //读取高位数据(左对齐) 
 ADMUX = 0b00100011; //选择外部参考电源 ADC3 左对齐 
 ADCSRA |=(1<<ADSC);  //启动AD转换 
} 
/*************************************************************************** 
                      定时器1中断处理程序 
****************************************************************************/ 
void Timer1_ovf(void)                  //1ms中断程序,检测主程序标志 
{ 
       TCNT1H = 0xE0;  
       TCNT1L = 0xC0;                //复位1ms记数器 
      if (Timer_Count>0) 
           { 
         Timer_Count++; 
        } 
       
      
      if (Press_Keys==2) 
           { 
         Mark_Line++; 
         if (Mark_Line>0xff) 
           { 
          Mark_Line=0x00; 
          } 
        } 
      if (Press_Keys==3) 
         { 
         Mark_Line--; 
         if (Mark_Line<0x01) 
          { 
          Mark_Line=0xff; 
         } 
        } 
      if (Press_Keys==1) 
         { 
         Mark_Line=0x80;   //复位 
        } 
    
   if (TCNT0>Mark_Line) 
      { 
      //驱动电机 
        PORTC |= 0b00100000; 
      } 
     else 
      { 
      //停止驱动 
        PORTC &= 0b11011111; 
      } 
} 

/*************************************************************************** 
                      系统初始化 
****************************************************************************/ 
void Hardware_init(void) 
{ 
 CLI(); 
  
 Port_init(); 
 Timer1_init(); 
 Timer0_init(); 
 adc_init(); 
 TIMSK = 0x04; 
  
 SEI(); 
} 

/*************************************************************************** 
                      延时程序 
****************************************************************************/ 
/*void Delay_ms(unsigned int delay_time) 
{ 
 Timer_Count_End=delay_time; 
 Timer_Count=1;          //启动计数器 
re_delay: 
 if (Timer_Count<=Timer_Count_End) 
    { 
    if (TCNT0>Mark_Line) 
      { 
      //驱动电机 
        PORTC |= 0b00100000; 
      } 
     else 
      { 
      //停止驱动 
        PORTC &= 0b11011111; 
      } 
    goto re_delay; 
     
   } 
   else 
    { 
    Timer_Count_End=0; 
    Timer_Count=0; 
   } 
}*/ 
void Delay_ms(unsigned int m)  //1ms延时 
{ 
 int l,j; 
 for(l=0;l<m;l++) 
   for(j=0;j<500;j++) 
   { 
   if (TCNT0>Mark_Line) 
      { 
      //驱动电机 
        PORTC |= 0b00100000; 
      } 
     else 
      { 
      //停止驱动 
        PORTC &= 0b11011111; 
      } 
   } 
} 

/*************************************************************************** 
                      按键扫描程序 
****************************************************************************/ 
void Key_Press_Scan(void)  //判断键值 
{ //unsigned char temp=0; 
    //扫描第一列 
   Press_Keys=0; 
   PORTC = 0b00000111;  
    DDRC =  0b00110000; 
   //temp=PINC;      
    if ( (PINC&0b00000100) == 0)    
     { 
      Delay_ms(10); 
      if ((PINC&0b00000100) == 0) 
           { 
        Press_Keys=1; 
        } 
     } 
    else if ((PINC&0b00000010) ==0) 
     { 
      Delay_ms(10); 
      if ((PINC&0b00000010) ==0) 
           { 
        Press_Keys=2; 
         } 
     } 
    else if ((PINC&0b00000001) ==0)    
     { 
      Delay_ms(10); 
      if ((PINC&0b00000001) ==0) 
           { 
        Press_Keys=3; 
        } 
     }   

   /*  
   //扫描第二列 
   PORTC = 0b00010111;      
          
    DDRC =  0b00111000; 
   //temp=PINC; 
    if ( (PINC&0b00000100) == 0) 
      { 
         Delay_ms(10); 
       if ((PINC&0b00000100) == 0) 
           { 
        Press_Keys=4; 
        } 
      } 
    else if ((PINC&0b00000010) ==0) 
      { 
         Delay_ms(10); 
       if ((PINC&0b00000010) ==0) 
           { 
        Press_Keys=5; 
        } 
      }    
    else if ((PINC&0b00000001) ==0) 
      { 
         Delay_ms(10); 
       if ((PINC&0b00000001) ==0) 
           { 
        Press_Keys=6; 
        } 
      }*/ 
} 


/*************************************************************************** 
                      显示函数 
****************************************************************************/ 
void Display_Message(unsigned char Where,unsigned char Number,unsigned char delays) 
{ 
 //在指定的位置显示指定的数字 
 PORTD = DispBit[Where];   
 PORTB = DispCode[Number]; //调用数码管译码表 
 Delay_ms(delays); 
} 

/************************************************************************** 
                     主函数 
**************************************************************************/ 
void main(void) 
{ 
 Hardware_init(); 
 ADCSRA |=(1<<ADSC);  //启动AD转换 
 while(1) 
   { 
      if (TCNT0>Mark_Line) 
      { 
      //驱动电机 
        PORTC |= 0b00100000; 
      } 
     else 
      { 
      //停止驱动 
        PORTC &= 0b11011111; 
      } 
     Key_Press_Scan(); 
   Display_Message(0,((Mark_Line<<4)>>4),5); 
   Display_Message(1,(Mark_Line>>4),5); 
   } 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -