找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

小型直流电机控制例子

[复制链接]
慧龙 发表于 2010-5-26 00:04:05 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
初学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
  2. // Crystal: 4.0000Mhz

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

  8. volatile unsigned char crut_sped;//当前转速
  9. //const unsigned char seg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
  10. //0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  
  11. void port_init(void)
  12. {
  13. PORTA = 0x00;
  14. DDRA  = 0x00;
  15. PORTB = 0x00;
  16. DDRB  = 0x00;
  17. PORTC = 0b01000000; //m103 output only
  18. DDRC  = 0xFF;
  19. PORTD = 0xFF;
  20. DDRD  = 0xFF;
  21. }
  22. //外部事件计数
  23. void timer0_init(void)
  24. {
  25. TCCR0 = 0x00; //stop
  26. TCNT0 = 0x00;  
  27. OCR0  = 0x00 ;   
  28. TCCR0 = 0x07; //start
  29. }   
  30. //TIMER1 initialize - prescale:64
  31. // WGM: 4) CTC, TOP=OCRnA
  32. // desired value: 1Sec
  33. // actual value:  1.000Sec (0.0%)
  34. void timer1_init(void)
  35. {
  36. TCCR1B = 0x00; //stop
  37. TCNT1H = 0x0B; //setup
  38. TCNT1L = 0xDD;
  39. OCR1AH = 0xF4;
  40. OCR1AL = 0x23;
  41. OCR1BH = 0xF4;
  42. OCR1BL = 0x23;
  43. ICR1H  = 0xF4;
  44. ICR1L  = 0x23;
  45. TCCR1A = 0b00000000;
  46. TCCR1B = 0b00001011; //start Timer
  47. }  
  48. //TIMER2 initialize - prescale:64
  49. // WGM: PWM Phase correct
  50. // desired value: 122Hz
  51. // actual value: 122.549Hz (0.4%)
  52. void timer2_init(void)
  53. {
  54. TCCR2 = 0x00; //stop
  55. TCNT2 = 0x01; //set count
  56. OCR2  = 0x3f;  //set compare
  57. TCCR2 = 0b01100011; //start timer
  58. }

  59. interrupt [TIM1_COMPA] void timer1_compa_isr(void)
  60. {
  61. //compare occured TCNT3=OCR3A
  62. crut_sped=TCNT0;
  63. timer0_init();  
  64. }   
  65. //UART0 initialize
  66. // desired baud rate: 19200
  67. // actual: baud rate:19231 (0.2%)
  68. // char size: 8 bit
  69. // parity: Disabled
  70. void uart_init(void)
  71. {
  72. UCSRB = 0x00; //disable while setting baud rate
  73. UCSRA = 0x00;
  74. UCSRC = 0x06;
  75. UBRRL = 0x0C; //set baud rate lo
  76. UBRRH = 0x00; //set baud rate hi
  77. UCSRB = 0x98;
  78. }


  79. interrupt[USART_RXC] void uart_rx_isr(void)
  80. {
  81.   /*if (rx_counter >= 4)  
  82.        {
  83.         rx_counter = 0;
  84.          if ((!(rx_data[0] == 'M'))||(!(rx_data[3] == 'C')))
  85.            {
  86.              rx_data[0]=0;
  87.              rx_data[1]=0;
  88.              rx_data[2]=0;
  89.              rx_data[3]=0;
  90.            }   
  91.        }   */
  92.     rx_data[rx_counter] = UDR;
  93.       
  94.      if (rx_data[rx_counter]=='M')
  95.        {
  96.           rx_data[0]=rx_data[rx_counter];
  97.           rx_counter=0;
  98.        }
  99.      rx_counter++;  
  100.    
  101.         
  102. }     

  103. void init_devices(void)
  104. {
  105. //stop errant interrupts until set up
  106. #asm("cli"); //disable all interrupts
  107. port_init();
  108. timer0_init();
  109. timer1_init();
  110. timer2_init();
  111. uart_init();
  112. MCUCR = 0x00;
  113. GICR  = 0x00;
  114. TIMSK = 0b00010000; //输出比较匹配A中断使能
  115. #asm("sei");//re-enable interrupts
  116. //all peripherals are now initialized
  117. }
  118. void timer2_reset(unsigned char i)
  119. {
  120. if((i>0x00)&&(i<0xff))
  121. {
  122. TCCR2 = 0x00; //stop
  123. TCNT2 = 0x01; //set count
  124. OCR2  = i;  //set compare
  125. TCCR2 = 0b01100011; //start timer
  126. }
  127.   
  128. }  
  129. void speed_direction(void)
  130. {
  131.   PORTC^=0x80;
  132.   PORTC^=0x40;   
  133. }

  134. void main(void)
  135. {  
  136. init_devices();
  137.   while(1)
  138.   {  
  139.     if (rx_counter==4)
  140.        {
  141.           rx_counter=0;
  142.           if ((rx_data[0] == 'M')&&(rx_data[3] == 'C'))
  143.           {
  144.             if(rx_data[1]=='s')//设定速度
  145.             {
  146.              timer2_reset(rx_data[2]);
  147.             }
  148.              else if(rx_data[1]=='d')
  149.                {
  150.               putchar(crut_sped);
  151.                }   
  152.              else if(rx_data[1]=='t')
  153.                {
  154.               PORTC=0x00;
  155.                }  
  156.              else if(rx_data[1]=='r')
  157.              {
  158.              PORTC=0x80;
  159.              }  
  160.              else if(rx_data[1]=='o')
  161.              {
  162.              speed_direction();
  163.              }
  164.             }   
  165.            else   
  166.             
  167.            {   
  168.           printf("your command is wrong
  169. ");
  170.              }
  171.               rx_data[0]=0;
  172.               rx_data[1]=0;
  173.               rx_data[2]=0;
  174.               rx_data[3]=0;
  175.             }   
  176.         
  177.   }
  178. }

复制代码
jiuhanfeng 发表于 2016-5-12 16:44:06 | 显示全部楼层
要是有个电路图截图就更好了,小白很懒
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-23 01:41 , Processed in 0.065504 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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