1 / 59

实验三:直流电机的驱动 与编码器脉冲的采集

实验三:直流电机的驱动 与编码器脉冲的采集. 内容概要. 学习 1 种 ATmega64 资源 —— 定时、计数器 3 演示 2 个实验: ( 1 )直流电机的驱动、调速 ( 2 )上述实验的软件仿真 自行做 3 个实验: ( 1 )直流电机的驱动 ( 2 )直流电机的 PWM 调速 ( 3 )光电编码器脉冲信号的读取. 控制什么?. 控制什么?. 用到哪些单片机资源?. 单片机模块 —— 电机控制. 通信模块 —— 和 PC 通信. 电机 驱动 模块 —— 驾驭电机. 电源模块 —— 提供动力.

niesha
Download Presentation

实验三:直流电机的驱动 与编码器脉冲的采集

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 实验三:直流电机的驱动 与编码器脉冲的采集

  2. 内容概要 • 学习1种ATmega64资源 ——定时、计数器3 • 演示2个实验: • (1)直流电机的驱动、调速 • (2)上述实验的软件仿真 • 自行做3个实验: • (1)直流电机的驱动 • (2)直流电机的PWM调速 • (3)光电编码器脉冲信号的读取

  3. 控制什么?

  4. 控制什么?

  5. 用到哪些单片机资源? 单片机模块—— 电机控制 通信模块——和PC通信 电机 驱动 模块——驾驭电机 电源模块——提供动力 输入输出模块——按键控制和状态指示

  6. 让直流电机动起来! • M+和M-分别接电源和地,电机就可以转动 • 交换M+和M-,电机就反向转动

  7. 用L298驱动直流电机

  8. 用L298驱动直流电机

  9. 自己动手之一——驱动直流电机 • 指令的输入:通过按键 • 按钮Stop、F.W.、B.W.作为控制按钮 • Stop(PC3,可触发外部中断INT5):启动、停止 • F.W.、B.W.( PC0、PC1,可触发外部中断4):正、反转

  10. 调试灯 • 调试用LED灯,可表示正、反转状态,运行状态等,也可以自定义。

  11. 电机控制I/O • PB4、PB5与L298的输入引脚相连 • 注意:小心滑块撞到支架!

  12. 操作说明 • 进行电机实验前,确保各接口连接好后,再打开电源。 • 在使用电机模块时,先打开电源开关,再打开L298使能开关;关闭时,先关闭L298使能开关,再关闭电源开关。 电源开关 L298使能开关

  13. 中断方式的设定

  14. 标志位的设定 • #define RUN 1 • #define STOP 0 • #define FORWARD 0 • #define BACKWARD 1 • unsigned char DC_State = STOP; // 电机状态,STOP或RUN • unsigned char dir_flag = FORWARD; // 方向标志,FORWARD或BACKWARD

  15. 宏定义 • #define isButtonFWDown() ((PINC&0B00000001)==0) • #define isButtonBWDown() ((PINC&0B00000010)==0) • #define isButtonZERODown() ((PINC&0B00000100)==0) • #define isButtonSTOPDown() ((PINC&0B00001000)==0) • #define LedFWOn() (PORTA &= 0B11111110) • #define LedBWOn() (PORTA &= 0B11111101) • #define LedZeroOn() (PORTA &= 0B11111011) • #define LedRunOn() (PORTA &= 0B11110111) • #define LedFWOff() (PORTA |= 0B00000001) • #define LedBWOff() (PORTA |= 0B00000010) • #define LedZeroOff() (PORTA |= 0B00000100) • #define LedRunOff() (PORTA |= 0B00001000)

  16. 自定义函数 • void DC_Forward() • { • PORTB |= 0B00010000; • PORTB &= 0B11011111; • } • void DC_Backward() • { • PORTB |= 0B00100000; • PORTB &= 0B11101111; • } • void DC_Stop() • { • PORTB &= 0B11001111; • } • 使用宏定义与自定义函数,可以提高程序的可读性与可维护性。 • 而宏定义与自定义函数相比,程序的执行效率更高。

  17. 外部中断4的处理程序举例 • #pragma interrupt_handler int4_isr:6 • void int4_isr() • { • //external interupt on INT4 • delay_ms(50); // 软件防抖 • if ( DC_State == RUN ) { • if ( isButtonFWDown() ) • { • dir_flag = FORWARD; • LedFWOn(); • LedBWOff(); • } • else if ( isButtonBWDown() ) • { • dir_flag = BACKWARD; • LedBWOn(); • LedFWOff(); • } • } • }

  18. 外部中断5的处理程序举例 • #pragma interrupt_handler int5_isr:7 • void int5_isr() • { • //external interupt on INT5 • delay_ms(50); • if ( isButtonSTOPDown() ) { • if ( DC_State == RUN ) • { • DC_State = STOP; • LedRunOff(); • DC_Stop(); • } • else if ( DC_State == STOP ) • { • DC_State = RUN; • LedRunOn(); • } • } • else if ( isButtonZERODown() ) • { • } • }

  19. 主函数 • while(1) • { • if (DC_State == RUN ) • { • if ( dir_flag == FORWARD ) • DC_Forward(); • else if ( dir_flag == BACKWARD ) • DC_Backward(); • } • }

  20. 如何改变电机的转速? • 对L298的控制有单极性、双极性2种方式。 • 单极性工作方式指的是在一个PWM周期内电机的电枢只承受单极性的电压; • 双极性工作方式是指在一个PWM周期内电机电枢两端的电压呈正负交替变化。

  21. PWM波 H M+ L 转动时间 停止时间 电机正转 电机调速(单极性) • 以电机正转为例,在M+端产生PWM波,M-接低电平。则M+为高电平时,电机正转;为低电平时,电机停转。 • 改变PWM波的占空比即可改变电机的转速,占空比越大,电机转速越快。 • 脉冲宽度(简称脉宽),就是高电平的时间。 PWM(Pulse Width Modulation):脉冲宽度调制

  22. 如何产生PWM波?(T/C1) • 16位的T/C 可以实现精确的程序定时(事件管理)、波形产生和信号测量。其主要功能如下: • 用作定时器:可以用作频率发生器等; • 用作计数器:可用来对外部引脚的脉冲信号进行计数; • 输入捕获功能:可用来测定外部信号的脉宽; • 输出比较匹配功能:可用来产生脉宽调制信号(PWM波)。

  23. 相关引脚 • T1(PD6) • OC1A(PB5) • OC1B(PB6) • OC1C(PB7) • ICP1(PD4)

  24. 波形产生模式

  25. 有关定时/计数器的几个变量

  26. M+ 转动时间 停止时间 电机正转 电机调速(单极性,快速PWM模式) TOP OCR1A TCNT1 溢出时置位,并进行 电机转向控制 BOTTOM TOP(ICR1) OCR1A 比较匹配时清零

  27. 软件设计 • PWM波形产生方法: 我们采用大致20KHz以上的PWM波进行电机的调速,采用Timer1的模式14,快速PWM模式,分频为1。使能overflow interrupt 和compare A interrupt中断,选择OC1A output mode为disconnected普通模式,在匹配中断中清零PB4、PB5,溢出中断中根据方向标志置位PB4或PB5。 这样就用单极性方式产生了方向可变的PWM波形。

  28. 快速PWM模式 • TOP:用来定义通过波形发生器产生的波形的周期(频率)。我们要求在20kHz,采用快速PWM模式(模式14),TOP值由ICR1寄存器给定。 • OCR1A:输出比较寄存器,记录输出比较的脉冲数,即调节占空比。这样,如果可以随时改变OCR1A的值,就可以产生可调占空比的PWM波。在模式14中,OCR1A的更新在TCNT1达到TOP时刻。

  29. 输出比较中断 OCR1A =? TCNT1←TCNT1+1 比较匹配的标志位 OCF1A置位 (TIFR) 产生PWM 波形可从引脚 OC1A输出 总开关I打开? (SREG) 分开关OCIE1A 打开?(TIMSK) 输出比较 中断服务 清空 OCF1A

  30. 输出比较单元 • 双缓冲输出比较寄存器OCR1A一直与TCNT1 的值做比较。 • 波形发生器用比较结果产生PWM或在输出比较引脚OC1A输出可变频率的信号。 • 比较匹配结果还可置位比较匹配标志OCF1A,用来产生输出比较中断请求。

  31. 相关寄存器 • SREG(状态寄存器) • Bit 7 – I: 全局中断使能(总开关) • I 置位时使能全局中断。单独的中断使能由其他独立的控制寄存器控制。如果I 清零,则不论单独中断标志置位与否,都不会产生中断。

  32. 相关寄存器 • TIMSK(定时器中断屏蔽寄存器)(分开关) • Bit 5 – TICIE1: T/C1 输入捕捉中断使能 • Bit 4 – OCIE1A:T/C1 输出比较 A 匹配中断使能 • Bit 3 – OCIE1B:T/C1 输出比较 B 匹配中断使能 • Bit 2 – TOIE1:T/C1 溢出中断使能

  33. 相关寄存器 • TIFR(定时器中断标志寄存器) • Bit 5 – ICF1: T/C1 输入捕捉标志 • Bit 4 – OCF1A: T/C1 输出比较 A 匹配标志 当TCNT1 与OCR1A 匹配成功时,该位被设为"1”。 • Bit 3 – OCF1B: T/C1 输出比较 B 匹配标志 • Bit 2 – TOV1: T/C1 溢出标志

  34. 相关寄存器 • TCCR1A(T/C1控制寄存器A) • TCCR1B(T/C1控制寄存器B) • TCCR1C(T/C1控制寄存器C)

  35. TCCR1A(T/C1控制寄存器A)

  36. TCCR1B(T/C1控制寄存器B)

  37. TCCR1C(T/C1控制寄存器C) • • Bit 7 – FOCnA: 强制输出比较通道A • • Bit 6 – FOCnB: 强制输出比较通道B • • Bit 5 – FOCnC: 强制输出比较通道C

  38. 相关寄存器(5个16位) • TCNT1(TCNT1H、TCNT1L) (16位的T/C1定时数据寄存器) • OCR1A(OCR1AH、OCR1AL) (16位的T/C1双缓冲输出比较寄存器A) • OCR1B(OCR1BH、OCR1BL) (16位的T/C1双缓冲输出比较寄存器B) • OCR1C(OCR1CH、OCR1CL) (16位的T/C1双缓冲输出比较寄存器C) • ICR1(ICR1H、ICR1L)(16位的T/C1输入捕获寄存器)

  39. 自己动手之二——改变电机转速 • Q:如何改变转速? • A:通过串口改变OCR1A的值,从而改变PWM占空比。 • 通过串口由PC机改变OCR1A的值,从而改变直流电机的转速!

  40. 单极性方式 • 输入端In1为PWM信号,输入端In2为低电平,电动机正转;输入端In2为PWM信号,输入端In1为低电平,电动机反转。 • 占空比为0%时制动,为100%时达到最高速; • 当EnA为低电平时,驱动桥路上的4个晶体管全部截止,使正在运行的电动机电枢电流反向,电动机自由停止。 • 但是,控制板的使能端通过按键开关接电源——用急停方式

  41. ICCAVR中如何设置T/C1 采用普通方式。 电机采用单极性方式驱动

  42. 定时/计数器1的初始化举例 • void timer1_init(void) • { • TCCR1B = 0x00; //stop • TCNT1H = 0x00; //setup • TCNT1L = 0x00; • OCR1AH = 0x02; • OCR1AL = 0x27; • OCR1BH = 0x02; • OCR1BL = 0x27; • OCR1CH = 0x02; • OCR1CL = 0x27; • ICR1H = 0x02; // 20kHz • ICR1L = 0x27; • TCCR1A = 0x02; // OCR1A未连接,做普通端口操作 • TCCR1B = 0x19; // start Timer • } ( 0227 )H=( 551 )D

  43. 定时/计数器1的比较匹配中断 • #pragma interrupt_handler timer1_compa_isr:iv_TIM1_COMPA • void timer1_compa_isr(void) • { • //compare occured TCNT1=OCR1A • DC_Stop(); • }

  44. 定时/计数器1的溢出中断处理 • #pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF • void timer1_ovf_isr(void) • { • //TIMER1 has overflowed • TCNT1H = 0x00; //reload counter high value • TCNT1L = 0x00; //reload counter low value • if (DC_State == RUN ) • { • if ( dir_flag == FORWARD ) • DC_Forward(); • else if ( dir_flag == BACKWARD ) • DC_Backward(); • } • else DC_Stop(); • }

  45. 通信协议 • 每帧包含3字节数据: • 字节0:0xaa (帧开始标志) • 字节1:速度高4位(bit3~bit0) • 字节2:速度低8位 • 速度范围(0x0001~0x0227),参见TIMER1初始化中ICR1取值

  46. ICCAVR中如何设置USART1

  47. 串口通信程序举例 • unsigned char ReceivedData[3]; // 接收缓存 • unsigned char receive_flag=0; // 接收完成标志,1表示接收一帧结束 • #pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC • void uart1_rx_isr(void) • { • static unsigned char rece_num=0; • unsigned char data; • data=UDR1; • if(( 0xAA == data )&&( 0 == rece_num ) || rece_num > 0 ) • { ReceivedData[ rece_num ] = data; • rece_num++; } • if ( 3 == rece_num ) • { rece_num = 0; • receive_flag = 1; } • }

  48. 主函数中修改脉冲宽度 • while(1) • { • if (receive_flag == 1) • { • OCR1AH = ReceivedData[ 1 ]; • OCR1AL = ReceivedData[ 2 ]; • DC_State = RUN; • receive_flag = 0; • } • }

  49. PROTEUS仿真效果

  50. 如何知道电机转多快?

More Related