宝玛科技网
您的当前位置:首页智能小车的直流电机控制

智能小车的直流电机控制

来源:宝玛科技网
创作时间:贰零贰壹年柒月贰叁拾日

之南宫帮珍创作

创作时间:贰零贰壹年柒月贰叁拾日 智能小车的直流电机控制 【实验目的】

了解以单片机为核心的直流电机控制系统 掌握此系统中直流电机驱动与调速原理 熟悉ICCAVR 软件编译环境,会编写控制程序 【实验器材】

智能小车一部,下载线一根 【实验原理】

直流电机驱动控制系统示意图:

在本实验中所分析的是以单片机ATMEGA8515L 为核心的直流电机控制系统。

ATMEGA8515L 芯片的引脚图如下:

功放驱动电路采取基于双极性H-桥型脉宽调整方式PWM 的集成电路L293D。L293D是单

块集成电路,高电压,高电流,四通道驱动,设计用来接受DTL 或者TTL 逻辑电平,驱动感

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

性负载(比方 继电器,直流和步近马达),和开关电源晶体管。其引脚图如下:

ATMEGA8515L 利用I/O 口(PD5,PE2,PD4,PD6)向驱动电路输出控制电平,这些I/O

口作为单片机控制指令的输出,连接到驱动电路中L293D 的相应管脚上。 其真值表如下:

对于电机的转速调整,我们是采取脉宽调制(PWM)法子,控制电机的时候,电源并不是

连续地向电机供电,而是在一个特定的频率下以方波脉冲的形式提供电能。分歧占空比的方

波信号能对电机起到调速作用,这是因为电机实际上是一个大电感,它有阻碍输入电流和电

压突变的能力,因此脉冲输入信号被平均分配到作用时间上,这样,改变在始能端PE2 和

PD5 上输入方波的占空比就能改变加在电机两端的电压大小,从而改变了转速。

此实验中用微处理机来实现脉宽调制,通常的方法有两种: (1)用软件方式来实现,即通过执行软件延时循环程序交替改变端口某个二进制位输出逻

辑状态来发生脉宽调制信号,设置分歧的延时时间得到分歧的占

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

空比。

(2)硬件电路自动发生PWM 信号,不占用CPU 处理的时间。 这就要用到ATMEGA8515L 的在PWM 模式下的计数器1,具体内容可参考相关书籍。 【实验步调】

(1) 连接好电路,把数据线,下载线连接好,打开电源 (2) 进入ICCAVR 编译环境,调试程序直至没有错误,编译环境简介请拜见附录一

(3) 下载,烧录进单片机,观察实验结果 (4) 反复修改调试程序,逐渐增强其功能 (5) 写好实验陈述,实验心得体会 【程序示例】

1、小车前进一段——>左转一圈——>右转一圈——>前进一段——>后退一段——>停下

//ICC-AVR application builder : 2005-5-19 19:12:13 // Target : M8515 // Crystal: 4.0000Mhz #include #include unsigned int time; unsigned int yan; void port_init(void)

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

{

PORTA = 0x00; DDRA = 0xFF; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0xFF; PORTE = 0x00; DDRE = 0xFF; }

//call this routine to initialize all peripherals void init_devices(void) {

//stop errant interrupts until set up CLI(); //disable all interrupts port_init(); MCUCR = 0x00; EMCUCR =0x00; GICR = 0x00; TIMSK = 0x00;

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

SEI(); //re-enable interrupts

//all peripherals are now initialized }

void delay(unsigned int yan) {

while(yan>0) yan--; }

void runforth(void) {

while(time<1000) {

PORTE=0x04; PORTD=0x70; delay(2000); time++; } time=0; }

void zuozhuanwan(void) {while(time<1000) {

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

PORTE=0x00; PORTD=0X70; delay(2000); time++; } time=0; }

void youzhuanwan(void) {while(time<1000) {

PORTE=0x04; PORTD=0x50; delay(2000); time++; } time=0; }

void houtui(void) {while(time<1000) {

PORTE=0x04; PORTD=0x20;

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

delay(2000); time++; } time=0; }

void stop(void) {

PORTE=0x00; PORTD=0x00; }

void main(void) { init_devices(); time=0; runforth(); zuozhuanwan(); youzhuanwan(); runforth(); houtui(); stop(); }

2、调速程序

以下是用两定时器来控制加在两方向控制口的方波占空比,以此

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

来对电机进行调速,而

同学们可以利用对两始能端高低电平进行分歧延时来实现调速功能。

//ICC-AVR application builder : 2005-5-18 16:45:27 // Target : M8515 // Crystal: 4.0000Mhz #include #include unsigned char a; unsigned char p; unsigned char m; unsigned char n; void port_init(void) {

PORTA = 0x00; DDRA = 0x00; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0x70;

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

PORTE = 0x00; DDRE = 0x04; }

//TIMER0 initialize - prescale: // WGM: Normal // desired value: 40Hz // actual value: Out of range void timer0_init(void) {

TCCR0 = 0x00; //stop timer

TCNT0 = 0xfa /*INVALID SETTING*/; //set count value TCCR0 = 0x03; //start timer }

#pragma interrupt_handler timer0_ovf_isr:8 void timer0_ovf_isr(void) {

TCNT0 = 0xfa /*INVALID SETTING*/; //reload counter value if(m==a) {PORTD=0x70; TCCR1B=0x03; TCCR0=0x00; n=1;}

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

else{m++;} }

//TIMER1 initialize - prescale: // WGM: 0) Normal, TOP=0xFFFF // desired value: 40Hz

// actual value: 40.013Hz (0.0%) void timer1_init(void) {

TCCR1B = 0x00; //stop TCNT1H = 0xff; //setup TCNT1L = 0xfa; OCR1AH = 0x06; OCR1AL = 0x1A; OCR1BH = 0x06; OCR1BL = 0x1A; TCCR1A = 0x00; TCCR1B = 0x00; }

#pragma interrupt_handler timer1_ovf_isr:7 void timer1_ovf_isr(void) {

TCNT1H = 0xff; //reload counter high value

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

TCNT1L = 0xfa; //reload counter low value if(n==250-a) {PORTD=0x20; TCCR0=0x03; TCCR1B=0x00; m=1;

if(p==0){if(a==125){p=1;} else{a++;}}

else{{if(a==1){p=0;} else{a--;}}}} else{n++;} }

//call this routine to initialize all peripherals void init_devices(void) {

//stop errant interrupts until set up CLI(); //disable all interrupts port_init(); timer0_init(); timer1_init(); MCUCR = 0x00; EMCUCR = 0x00;

创作时间:贰零贰壹年柒月贰叁拾日

创作时间:贰零贰壹年柒月贰叁拾日

GICR = 0x00; TIMSK = 0x82;

SEI(); //re-enable interrupts

//all peripherals are now initialized }

void main(void) {a=0; p=0; m=1; n=1;

init_devices(); while(1) {PORTE=0x04;} }

创作时间:贰零贰壹年柒月贰叁拾日 创作时间:贰零贰壹年柒月贰叁拾日

因篇幅问题不能全部显示,请点此查看更多更全内容