Sisujuht
Läbitehtud koodinäited
Programmeerimiseks kasutatud vahendid
- WinAVR C++ Extension
- ProjectWizard
Näide 1 (2.04.2007)
#include <inttypes.h> #include <avr/io.h> void delay(uint16_t time) { uint16_t i; for (i = 0; i < time; i++) { } } // delay int main (void) { DDRC |= _BV(PC4) | _BV(PC5); //0x10 LED1 ja LED2 väljund PORTC |= _BV(PC4) | _BV(PC5); // LED1 ja LED1 põlema PORTB |= _BV(PB5); // mikrolüliti sisendiks PORTC &= ~_BV(PC4); // LED1 kustu while (1) { if (!(PINB & _BV(PB5))) // kui mikrolüliti ei ole allavajutatud { PORTC ^= _BV(PC4); // LED1 vilkuma delay(15000); // ootame ... } } return 0; } // main
Näide 2 (9.04.2007)
ProjectName.cpp
#include "ProjectName.h" void Delay(uint16_t time) { uint16_t i; for (i = 0; i < time; i++) ; } // Delay int main (void) { //DDRC |= _BV(PC4) | _BV(PC5); //0x10 LED1 ja LED2 väljund LEDs::InitOutput(); /* Alternatiivid: PortC::SetAsOutput(_PC4 | _PC5); SetBits<_DDRC>(_BV(PC4) | _PC5); Bits<_DDRC, _BV(PC4) | _PC5>::Set();*/ MotorPins::InitOutput(); // PORTC |= _BV(PC4) | _BV(PC5); // LED1 ja LED1 põlema LEDs::Set(); //PORTB |= _BV(PB5); // mikrolüliti sisendiks Buttons::InitInput(); //PORTC &= ~_BV(PC4); // LED1 kustu LED1::Clear(); while (true) { // if (!(PINB & _BV(PB5))) // kui mikrolüliti ei ole allavajutatud if (Button1::IsSet() ) // kui mikrolüliti ei ole allavajutatud { //PORTC ^= _BV(PC4); // LED1 vilkuma LED2::Toggle(); Delay(15000); // ootame ... } } return 0; } // main
ProjectName.h
#include "Precompiled.h" #include "Config.h"
Config.h
/* ----- Roboti muutmatud pinnid ----- LED 1: PC4 LED 2: PC5 Nupp 1: PB3 Nupp 2: PB5 Vasak mootor: Pluss (punane): PC2 Miinus (must): PC3 Parem mootor: Pluss (punane): PC0 Miinus (must): PC1 */ typedef InputPin3<PortB> Button1; typedef InputPin5<PortB> Button2; typedef InputPins<PortB, _PB3 | _PB5> Buttons; typedef OutputPin4<PortC> LED1; typedef OutputPin5<PortC> LED2; typedef OutputPins<PortC, _PC4 | _PC5> LEDs; typedef OutputPin2<PortC> LeftMotorRed; typedef OutputPin3<PortC> LeftMotorBlack; typedef OutputPin0<PortC> RightMotorRed; typedef OutputPin1<PortC> RightMotorBlack; typedef OutputPins<PortC, _PC0 | _PC1 | _PC2 | _PC3> MotorPins; template <class Red, class Black> struct Motor { static inline void Forward() { Red::Set(); Black::Clear(); } // Forward static inline void Reverse() { Red::Clear(); Black::Set(); } // Reverse static inline void Stop() { Red::Clear(); Black::Clear(); } // Stop }; typedef Motor<RightMotorRed, RightMotorBlack> RightMotor; typedef Motor<LeftMotorRed, LeftMotorBlack> LeftMotor;
Precompiled.h
#include <IO.h> #include <DiverseIO.h> #include <Assembler.h> #include <Interrupt.h> #include <ExternalInterrupt.h> #include <Timer.h> #include <Sleeping.h> #include <ADC.h> #include <EEPROM.h> #include <USART.h> #include <Delegate.h>
Näide 3 (16.04.2007, parandused 19.04.2007)
- Terve projekti saab tõmmata siit:
Vajab WinAVR C++ Extension versioon 1.0.7't.
#include "ProjectName.h" USING_DATA_DELEGATE(TIMER2_COMP, SystemClock); SystemClock &systemClock = SystemTimer::CompareMatchInterrupt::Controller<SystemClock>(); SpeedSetMotor<LeftMotor> leftMotor; SpeedSetMotor<RightMotor> rightMotor; int main() { AllInput::InitInput(); AllOutput::InitOutput(); GlobalInterrupts::Enable(); LEDs::Set(); systemClock.Delay(2000); rightMotor.SetSpeed(3); leftMotor.SetSpeed(3); while (systemClock.GetTimerCounter() < 60000) { if (!Button1::IsSet() ) { rightMotor.Increase(); leftMotor.Increase(); } else if (!Button2::IsSet() ) { rightMotor.Decrease(); leftMotor.Decrease(); } systemClock.Delay(500); LED1::Toggle(); } LED1::Clear(); LED2::Set(); return 0; } // main
ProjectName.h
#include "Precompiled.h" using namespace CppDelegate; #include "Config.h" #include "SystemClock.h" #include "SpeedSetMotor.h"
SystemClock.h
class SystemClock : public DelegateController<SystemClock> { private: uint8_t motorsCounter; uint32_t timerCounter; volatile uint32_t delayCounter; static const uint8_t motorsPeriod = 16; /* SystemTimer: TOP = CPU Frequency / Prescaler / Frequency - Constant 1 */ static const uint8_t systemTimerTop = F_CPU / 32 / 1000 - 1; virtual bool Before() { motorsCounter++; timerCounter++; if (delayCounter > 0) delayCounter--; if (motorsCounter >= motorsPeriod) motorsCounter = 0; return true; } public: SystemClock() : DelegateController<SystemClock>(), motorsCounter(0), timerCounter(0), delayCounter(0) { using namespace Timer; SystemTimer::OutputCompare::Set(systemTimerTop); SystemTimer::NonPWM::SetUp ( ZPrescale32, CTC, NormalPortOperation ); SystemTimer::CompareMatchInterrupt::Enable(); } // SystemClock CONSTRUCTOR inline uint8_t GetMotorsCounter() { return motorsCounter; } inline void ResetTimerCounter() { GlobalInterrupts::Disable(); { timerCounter = 0; } GlobalInterrupts::Enable(); } // ResetTimerCounter inline uint32_t GetTimerCounter() { uint32_t result; GlobalInterrupts::Disable(); { result = timerCounter; } GlobalInterrupts::Enable(); return result; } // GetTimerCounter void Delay(uint32_t time) { using namespace GlobalInterrupts; Disable(); delayCounter = time; Enable(); while (true) { Disable(); if (delayCounter == 0) break; Enable(); Assembler::NOP(); } Enable(); } // Delay }; // class SystemClock
SpeedSetMotor.h
template <class Motor> class SpeedSetMotor { private: int8_t speed; static const int8_t maxSpeed = 16; void OnInterrupt(SystemClock &systemClock) { if (speed == 0) { Motor::Stop(); } else if (speed < 0) { if (systemClock.GetMotorsCounter() < -speed) Motor::Reverse(); else Motor::Stop(); } else { if (systemClock.GetMotorsCounter() < speed) Motor::Forward(); else Motor::Stop(); } } // OnInterrupt public: SpeedSetMotor() : speed(0) { SystemTimer::CompareMatchInterrupt::Me<DataDelegate<SystemClock> >().Add ( this, &SpeedSetMotor<Motor>::OnInterrupt ); } // SpeedSetMotor CONSTRUCTOR bool SetSpeed(int8_t speedToSet) { if (speedToSet <= maxSpeed && speedToSet >= -maxSpeed) { speed = speedToSet; return true; } return false; } // SetSpeed bool Increase() { if (speed == maxSpeed) return false; speed++; return true; } // Increase bool Decrease() { if (speed == -maxSpeed) return false; speed--; return true; } // Decrease }; // class SpeedSetMotor
Config.h
/* ----- Roboti muutmatud pinnid ----- Nupud ees: Paremal: PD4 Keskel: PD3 Vasakul: PD2 Nupud taga: Paremal: PD1 Vasakul: PD0 LED 1: PC4 LED 2: PC5 Nupp 1: PB3 Nupp 2: PB5 Vasak mootor: Pluss (punane): PC2 Miinus (must): PC3 Parem mootor: Pluss (punane): PC0 Miinus (must): PC1 */ /* Sisendid */ typedef InputPin4<PortD> FrontRight; typedef InputPin3<PortD> FrontCenter; typedef InputPin2<PortD> FrontLeft; typedef InputPin1<PortD> BackRight; typedef InputPin0<PortD> BackLeft; typedef InputPins<PortD, _PD0 | _PD1 | _PD2 | _PD3 | _PD4> FrontAndBack; typedef InputPin3<PortB> Button1; typedef InputPin5<PortB> Button2; typedef InputPins<PortB, _PB3 | _PB5> Buttons; typedef CombinedInputPins<Buttons, FrontAndBack> AllInput; /* Väljundid */ typedef OutputPin4<PortC> LED1; typedef OutputPin5<PortC> LED2; typedef OutputPins<PortC, _PC4 | _PC5> LEDs; typedef OutputPin2<PortC> LeftMotorRed; typedef OutputPin3<PortC> LeftMotorBlack; typedef OutputPin0<PortC> RightMotorRed; typedef OutputPin1<PortC> RightMotorBlack; typedef OutputPins<PortC, _PC0 | _PC1 | _PC2 | _PC3> MotorPins; typedef CombinedOutputPins<LEDs, MotorPins> AllOutput; /* Mootorid */ template <class Red, class Black> struct Motor { static inline void Forward() { Red::Set(); Black::Clear(); } // Forward static inline void Reverse() { Red::Clear(); Black::Set(); } // Reverse static inline void Stop() { Red::Clear(); Black::Clear(); } // Stop }; typedef Motor<RightMotorRed, RightMotorBlack> RightMotor; typedef Motor<LeftMotorRed, LeftMotorBlack> LeftMotor; /* Taimerid */ typedef Timer::TimerCounter2 SystemTimer;
Precompiled.h
#include <IO.h> #include <DiverseIO.h> #include <Assembler.h> #include <Interrupt.h> #include <ExternalInterrupt.h> #include <Timer.h> #include <Sleeping.h> #include <ADC.h> #include <EEPROM.h> #include <USART.h> #include <Delegate.h>