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

📄 avrdcmotorcontrolsystem.txt

📁 初学AVR
💻 TXT
字号:
初学AVR,手头没有什么具体实践的课题,拆了几个小马达,玩玩中,也学到不少东西。希望可以给初学者一点帮助。 
这个小型的直流电机控制系统很容易就可以实现,采用PWM调速方式,驱动电路,可以用分立元件搭,(网上这种电路很多),也可以采用集成IC器件,我采用的就是L293。电路很简单,就不画图了。 
接线描述如下: 
   PORTC7,PORTC6分别接L293 IN1,IN2,察看L293资料可知,ENA=H,IN1=H,IN2=L正转 
                                                        ENA=H,IN1=L,IN2=H反转 
                                             ENA=H,同IN2(IN4),同IN1(IN3)  快速停止 
                                             ENA=L,                            停止 
   OCR2接L293 ENA 
   测速反馈信号接T0 
代码描述如下: 
   本系统可以同过串口接收上位机控制命令,可以实现开启,停机,调速,及时速度反馈。串口采用接收中断方式,命令协议如下:命令采用M**C模式,所有命令字符串以M开头,C结尾。中间两个字符定义:s表示调速,以第三个命令字符和0xff的比值作为PWM的占空比进行调速。 
    d表示向上位机发送当前转速。 
    t表示停机 
    r表示开启 
    o表示方向翻转 
测速采用测速脉冲信号(霍尔速度传感器)作为T2的外部计数脉冲,T1 CTC模式,实现1s定时,比较匹配中断允许,中断服务程序读TCNT2的值,即为转速,读后重新初始化Timer2。 
对初学者来说,测速可以使用cpu风扇来作试验,cpu风扇自带一个速度输出线,内部采用的是霍尔传感器,注意,霍尔传感器输出端是oc门开路,需要接上拉电阻。可以得到很标准的方波!另:注意将风扇接地和你的开发板接地连在一起。 
原代码如下: 
  程序采用的是ICC自动生成代码,再移植到codevision中,本人觉得ICC自动生成代码结构清晰,很适合初学者,也可能有不妥的地方! 
 // Target : M16 
// Crystal: 4.0000Mhz 

#include <mega16.h> 
#include <delay.h> 
#include <stdio.h> 
unsigned char rx_data[5];//数据缓冲区 
volatile unsigned char rx_counter=0; 

volatile unsigned char crut_sped;//当前转速 
//const unsigned char seg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 
//0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  
void port_init(void) 
{ 
 PORTA = 0x00; 
 DDRA  = 0x00; 
 PORTB = 0x00; 
 DDRB  = 0x00; 
 PORTC = 0b01000000; //m103 output only 
 DDRC  = 0xFF; 
 PORTD = 0xFF; 
 DDRD  = 0xFF; 
} 
//外部事件计数 
void timer0_init(void) 
{ 
TCCR0 = 0x00; //stop 
TCNT0 = 0x00;  
OCR0  = 0x00 ;    
TCCR0 = 0x07; //start 
}   
//TIMER1 initialize - prescale:64 
// WGM: 4) CTC, TOP=OCRnA 
// desired value: 1Sec 
// actual value:  1.000Sec (0.0%) 
void timer1_init(void) 
{ 
 TCCR1B = 0x00; //stop 
 TCNT1H = 0x0B; //setup 
 TCNT1L = 0xDD; 
 OCR1AH = 0xF4; 
 OCR1AL = 0x23; 
 OCR1BH = 0xF4; 
 OCR1BL = 0x23; 
 ICR1H  = 0xF4; 
 ICR1L  = 0x23; 
 TCCR1A = 0b00000000; 
 TCCR1B = 0b00001011; //start Timer 
}  
//TIMER2 initialize - prescale:64 
// WGM: PWM Phase correct 
// desired value: 122Hz 
// actual value: 122.549Hz (0.4%) 
void timer2_init(void) 
{ 
 TCCR2 = 0x00; //stop 
 TCNT2 = 0x01; //set count 
 OCR2  = 0x3f;  //set compare 
 TCCR2 = 0b01100011; //start timer 
} 

 interrupt [TIM1_COMPA] void timer1_compa_isr(void) 
{ 
 //compare occured TCNT3=OCR3A 
 crut_sped=TCNT0; 
 timer0_init();  
}   
//UART0 initialize 
// desired baud rate: 19200 
// actual: baud rate:19231 (0.2%) 
// char size: 8 bit 
// parity: Disabled 
void uart_init(void) 
{ 
 UCSRB = 0x00; //disable while setting baud rate 
 UCSRA = 0x00; 
 UCSRC = 0x06; 
 UBRRL = 0x0C; //set baud rate lo 
 UBRRH = 0x00; //set baud rate hi 
 UCSRB = 0x98; 
} 


interrupt[USART_RXC] void uart_rx_isr(void) 
{ 
  /*if (rx_counter >= 4)  
       { 
               rx_counter = 0; 
                if ((!(rx_data[0] == 'M'))||(!(rx_data[3] == 'C'))) 
                  { 
                    rx_data[0]=0; 
             rx_data[1]=0; 
             rx_data[2]=0; 
             rx_data[3]=0; 
                  }   
       }   */ 
    rx_data[rx_counter] = UDR; 
      
     if (rx_data[rx_counter]=='M') 
       { 
                 rx_data[0]=rx_data[rx_counter]; 
                 rx_counter=0; 
       } 
     rx_counter++;  
   
        
}     

void init_devices(void) 
{ 
 //stop errant interrupts until set up 
#asm("cli"); //disable all interrupts 
 port_init(); 
 timer0_init(); 
 timer1_init(); 
 timer2_init(); 
 uart_init(); 
 MCUCR = 0x00; 
 GICR  = 0x00; 
 TIMSK = 0b00010000; //输出比较匹配A中断使能 
 #asm("sei");//re-enable interrupts 
 //all peripherals are now initialized 
} 
void timer2_reset(unsigned char i) 
{ 
 if((i>0x00)&&(i<0xff)) 
 { 
 TCCR2 = 0x00; //stop 
 TCNT2 = 0x01; //set count 
 OCR2  = i;  //set compare 
 TCCR2 = 0b01100011; //start timer 
 } 
  
}  
 void speed_direction(void) 
 { 
  PORTC^=0x80; 
  PORTC^=0x40;   
 } 

void main(void) 
{  
 init_devices(); 
  while(1) 
  {  
    if (rx_counter==4) 
       { 
          rx_counter=0; 
          if ((rx_data[0] == 'M')&&(rx_data[3] == 'C')) 
          { 
            if(rx_data[1]=='s')//设定速度 
            { 
             timer2_reset(rx_data[2]); 
            } 
             else if(rx_data[1]=='d') 
               { 
              putchar(crut_sped); 
               }   
             else if(rx_data[1]=='t') 
               { 
              PORTC=0x00; 
               }  
             else if(rx_data[1]=='r') 
             { 
             PORTC=0x80; 
             }  
             else if(rx_data[1]=='o') 
             { 
             speed_direction(); 
             } 
            }   
           else   
             
           {   
          printf("your command is wrong 
"); 
             } 
              rx_data[0]=0; 
              rx_data[1]=0; 
              rx_data[2]=0; 
              rx_data[3]=0; 
            }   
        
  } 
} 

⌨️ 快捷键说明

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