hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 698|回复: 1

小型直流电机控制例子

[复制链接]

585

主题

769

帖子

2007

积分

大司空

Rank: 5Rank: 5

积分
2007
发表于 2023-11-21 09:03:33 | 显示全部楼层 |阅读模式
初学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自动生成代码结构清晰,很适合初学者,也可能有不妥的地方!
  1. // 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;             }             } }
复制代码
回复

使用道具 举报

0

主题

156

帖子

125

积分

关内侯

Rank: 2

积分
125
发表于 2023-11-21 09:04:00 | 显示全部楼层
要是有个电路图截图就更好了,小白很懒
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-11-1 09:26 , Processed in 0.056745 second(s), 22 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

快速回复 返回顶部 返回列表