====== 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:
void dcmotor_drive(unsigned char index, signed char direction, unsigned char speed)
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|}}
/**************************************************************************
*
*
* - File : main.c
*
*
* - Supported devices : Atmega2561.
*
*
*****************************************************************************/
#include
#include "main.h"
#include
#include
#include
#include
// 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:
}
}
PWM generaator:
//*****************************************************************************
//
// 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<