Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
et:examples:motor:dc:speed [2011/12/09 13:20] – tekitatud raivo.sellet:examples:motor:dc:speed [2020/07/20 12:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== Mootori kiiruse juhtimine ======
  
 +Näide, mis võimaldab nuppudest mootori 0 kiirust suurendada ja vähendada ja pöörlemissuunda muuta. Lisaks on main.c failis ka funktsioon, mis võimaldab kõigi DC nootorite kiiruseid muuta ja suunda vahetada:
 +
 +
 +<code c>
 +void dcmotor_drive(unsigned char index, signed char direction, unsigned char speed)
 +</code>
 +
 +
 +Hetkel see ei ole mõeldud teegi mootorite osaga kasutamiseks, kuna funktsiooni nimi kattub. 
 +
 +Kõige üldisemalt saab viikude PWM-i juhtida compbuff[CHMAX] muutuja kaudu. Nii võite endale ise funktsioonid jne koostada. Siis saab kõiki  SoftPWM.h failis olevaid kanaleid eraldi juhtida.
 +
 +Kui kanalite arvu muudate, siis vaadake ka SoftPWM.c fail üle, kus tuleb üleliigsete kanalite haldamine kinni keerata: faili lõpus compare funktsioonid.
 +
 +On oht, et selle SoftPWMi taimer0 kattub hw_delay funktsioonis kasutatuga. Lihtsalt teadmiseks.
 +Kui mujal projektis soovite kasutada, siis kindlasti peab failis, kus on dcmotor_drive funktsioon olema ka volatile unsigned char compbuff[CHMAX];. Vastasel juhul kood ei kompileeru.
 +
 +Kõik failid allalaadimiseks siin:
 +  * {{:software:codes:softpwm:main.c|}}
 +  * {{:software:codes:softpwm:main.h|}}
 +  * {{:software:codes:softpwm:softpwm.c|}}
 +  * {{:software:codes:softpwm:softpwm.h|}}
 +
 +
 +
 +<code c>
 +/**************************************************************************
 +*
 +*
 +* - File              : main.c
 +*
 +*
 +* - Supported devices : Atmega2561.
 +*
 +*
 +*****************************************************************************/
 +
 +#include <ctype.h>
 +#include "main.h"
 +#include <avr/io.h>
 +#include <homelab/delay.h>
 +#include <homelab/pin.h>
 +#include <homelab/module/lcd_gfx.h>
 +
 +
 +// Global buffer. Defined SoftPWM.c
 +volatile unsigned char compbuff[CHMAX];
 +
 +pin led_red    = PIN(C, 5);
 +pin led_yellow = PIN(C, 4);
 +pin led_green  = PIN(C, 3);
 + 
 +pin button1 = PIN(C, 0);
 +pin button2 = PIN(C, 1);
 +pin button3 = PIN(C, 2);
 +
 +
 +//
 +// The program entry point.
 +//
 +int main(void)
 +{
 +  unsigned char rxdata = 0;
 +  signed char direction = -1;
 +
 +
 +    // Seab LEDid töökorda
 + pin_setup_output(led_red);
 + pin_setup_output(led_yellow);
 + pin_setup_output(led_green);
 + 
 + // Seab nupud töökorda
 + pin_setup_input_with_pullup(button1);
 + pin_setup_input_with_pullup(button2);
 + pin_setup_input_with_pullup(button3);
 + 
 + // Lülitab LEDid välja
 + pin_set(led_green);
 + pin_set(led_yellow);
 + pin_set(led_red);
 +
 + // Ekraani seadistamine
 + lcd_gfx_init();
 + 
 + // LCD ekraani puhastamine
 + lcd_gfx_clear();
 +
 + lcd_gfx_backlight(true); 
 + 
 + // Kursori (nähtamatu) ekraani keskele viimine
 + lcd_gfx_goto_char_xy(3, 2);
 + 
 + // Teksti kuvamine
 + lcd_gfx_write_string("SoftPWM");
 +
 +    
 +  InitSoftPWM();
 + 
 +
 +  while(1)
 +  {
 +      
 + 
 + // Nupp S1 alla vajutatud
 + if(!pin_get_debounced_value(button1))
 + {
 + // Kiiruse suurendamine
 + if(rxdata < 0xFF)
 + {
 + rxdata++;
 + }
 + pin_clear(led_green);
 +
 + }
 + 
 + // Nupp S2 alla vajutatud
 +     if(!pin_get_debounced_value(button2))
 + {
 + // Kiiruse vähendamine
 + if(rxdata > 0x00)
 + {
 + rxdata--;
 + }
 + pin_clear(led_yellow);
 +
 + }
 + 
 + // Nupp S3 alla vajutatud
 + if(!pin_get_debounced_value(button3))
 + {
 + //Pöörlemissuuna muutmine
 + if(direction == 1)
 + {
 + direction = -1;
 + }
 + else
 + {
 + direction = 1;
 + }
 +
 + }
 +
 + pin_set(led_green);
 + pin_set(led_yellow);
 +
 + //Mootori juhtimine
 + dcmotor_drive(0, direction, rxdata);
 + sw_delay_ms(5);
 +
 + /*
 + dcmotor_drive(0, 1, 0xFF);
 + sw_delay_ms(500);
 + dcmotor_drive(0, -1, 0xFF);
 + sw_delay_ms(500);
 + */
 +       
 +  }
 +}
 +
 +//
 +// Funktsioon mootori juhtimiseks.
 +//
 +void dcmotor_drive(unsigned char index, signed char direction, unsigned char speed) 
 +{
 + switch (index)
 + {
 + case 0:
 + if(direction == 1)
 + {
 + compbuff[6] = 0x00;
 + compbuff[7] = speed;
 + }
 + if(direction == -1)
 + {
 + compbuff[7] = 0x00;
 + compbuff[6] = speed;
 + }
 +
 + break;
 + 
 +
 + case 1:  //OK
 +
 + if(direction == 1)
 + {
 + compbuff[0] = 0x00;
 + compbuff[1] = speed;
 + }
 + if(direction == -1)
 + {
 + compbuff[0] = speed;
 + compbuff[1] = 0x00;
 + }
 +
 + break;
 +
 + case 2: //OK
 +
 + if(direction == 1)
 + {
 + compbuff[4] = 0x00;
 + compbuff[5] = speed;
 + }
 + if(direction == -1)
 + {
 + compbuff[5] = 0x00;
 + compbuff[4] = speed;
 + }
 +
 + break;
 +
 + case 3: //OK
 +
 + if(direction == 1)
 + {
 + compbuff[2] = 0x00;
 + compbuff[3] = speed;
 + }
 + if(direction == -1)
 + {
 + compbuff[3] = 0x00;
 + compbuff[2] = speed;
 + }
 +
 + break;
 + 
 + //default:
 +
 +
 + }
 +}
 +</code>
 +
 +PWM generaator:
 +
 +<code c>
 +//*****************************************************************************
 +//
 +// 10 Channel software PWM
 +//
 +//  - AppNote           : AVR136 - Low-Jitter Multi-Channel Software PWM
 +//
 +// Introduction
 +// This documents data structures, functions, variables, defines, enums, and
 +// typedefs in the software for application note AVR136.
 +//
 +//
 +// Channels are mapped to specific port pins in the SoftPWM.h file
 +// \section PWMinfo PWM frequency and crystal selection
 +//
 +// The PWM base frequency is the crystal frequency divided by 65536, e.g. for
 +// a 7.3728MHz crystal the PWM base frequency will be 112.5Hz. The standard
 +// STK500 3.6864MHz oscillator could be used as a clock source, but the PWM
 +// base frequency would be reduced which may result in unacceptable ripple.
 +// Jitter will be +/-1 clock cycle max, or +/-0.0015% of base frequency.
 +//
 +// This demonstration shows ten PWM channels, for GCC the ISR uses less than
 +// 50% of processing time during the softcount=0 interrupt. The principles
 +// shown should accomodate up to 24 channels on suitable AVR devices whilst
 +// maintaining PWM accuracy, ISR optimisation may improve this even further.  
 +//*****************************************************************************
 +
 +#include "SoftPWM.h"
 +
 +// global buffers
 +unsigned char compare[CHMAX];
 +extern volatile unsigned char compbuff[CHMAX];
 +
 +//
 +// Init function. This function initialises the hardware
 +//
 +void InitSoftPWM(void)
 +{
 +  unsigned char i, pwm;
 +
 +  CLKPR = (1 << CLKPCE);        // enable clock prescaler update
 +  CLKPR = 0;                    // set clock to maximum (= crystal)
 +
 +  __watchdog_reset();           // reset watchdog timer
 +  MCUSR &= ~(1 << WDRF);        // clear the watchdog reset flag
 +  WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence
 +  WDTCSR = 0x00;                // disable watchdog timer
 +
 +  DDRD = PORTD_MASK;            // set port pins to output
 +  DDRB = PORTB_MASK;            // set port pins to output
 +
 +
 +  pwm = PWMDEFAULT;
 +
 +
 +  for(i=0 ; i<CHMAX ; i++)      // initialise all channels
 +  {
 +    compare[i] = pwm;           // set default PWM values
 +    compbuff[i] = pwm;          // set default PWM values
 +  }
 +
 +
 +  TIFR0 = (1 << TOV0);           // clear interrupt flag
 +  TIMSK0 = (1 << TOIE0);         // enable overflow interrupt
 +  TCCR0B = (1 << CS00);         // start timer, no prescale
 +
 +  sei();         // enable interrupts
 +}
 +
 +//
 +// Interrupt Service Routine
 +//
 +ISR (TIMER0_OVF_vect)
 +{
 +  static unsigned char pinlevelB=PORTB_MASK, pinlevelD=PORTD_MASK;
 +  static unsigned char softcount=0xFF;
 +
 +  PORTB = pinlevelB;            // update outputs
 +  PORTD = pinlevelD;            // update outputs
 +
 +
 +  if(++softcount == 0){         // increment modulo 256 counter and update
 +                                // the compare values only when counter = 0.
 +    compare[0] = compbuff[0];   // verbose code for speed
 +    compare[1] = compbuff[1];
 +    compare[2] = compbuff[2];
 +    compare[3] = compbuff[3];
 +    compare[4] = compbuff[4];
 +    compare[5] = compbuff[5];
 +    compare[6] = compbuff[6];
 +    compare[7] = compbuff[7];
 + //compare[8] = compbuff[8];
 + //compare[9] = compbuff[9];
 +    // last element should equal CHMAX - 1
 +
 +    pinlevelB = PORTB_MASK;     // set all port pins high
 +    pinlevelD = PORTD_MASK;     // set all port pins high
 +  }
 +  // clear port pin on compare match (executed on next interrupt)
 +  if(compare[0] == softcount) CH0_CLEAR;
 +  if(compare[1] == softcount) CH1_CLEAR;
 +  if(compare[2] == softcount) CH2_CLEAR;
 +  if(compare[3] == softcount) CH3_CLEAR;
 +  if(compare[4] == softcount) CH4_CLEAR;
 +
 +  if(compare[5] == softcount) CH5_CLEAR;
 +  if(compare[6] == softcount) CH6_CLEAR;
 +  if(compare[7] == softcount) CH7_CLEAR; 
 +  //if(compare[8] == softcount) CH8_CLEAR;
 +  //if(compare[9] == softcount) CH9_CLEAR;   
 +
 +
 +}
 +</code>
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0