В тази тема смятам да публикувам сорс кодове, вече написани функции, макроси и алгоритми (нещо като библиотека за софтуер), които да са лесни и удобни за използване. Така всеки ще може да се съсредоточи върху ефикасността на самите алгоритми, а на върху техническото им изпълнение ( или поне ще се олеснява писането им :-D ).
И така, ето ги макросите за задаване, четене и изчистване на определен пин или порт на атмел-овски микроконтролери, с примери за използването им:
#define getPin(port,pin) (port&(1<<pin))>>pin
#define setPin(port,pin) port|=1<<pin
#define clearPin(port,pin) port&=~(1<<pin)
#define setPort(port,val) port=val;
#define getPort(port) port
Ето и няколко примера:
char t=getPin(PORTB,PB3); //0 или 1, в зависимост дали на пин PB3 има напрежение или не
setPin(PORTC,4); // на пин PC4 вече има напрежение
clearPin(PORTC,4); // на пин PC4 вече няма напрежение
ШИМ - използвайки 8-битовите таймери на МК
Кода е писан за ATMEGA88 за друг МК трябва да смените съответните наименования на битовете (ако някой не може да пише)
void setTimer0(uint16_t perc) {
DDRD|=0x40; //set OC0A (PD6) pin as output
TCNT0=0x00; // Initial value of the counter
OCR0A=(uint8_t) (255*perc/100); //Compare Match Value
//Start Timer - Fast 8 bit PWM
TCCR0A=(1<<COM0A1)|(1<<WGM00)|(1<<WGM01)|(1<<CS00);
}
void setTimer2(uint16_t perc) {
DDRB|=0x08; //set OC2A (PB3) pin as output
TCNT2=0x00; // Initial value of the counter
OCR2A=(uint8_t) (255*perc/100); // Compare Match value
//Start Timer - Fast 8 bit PWM
TCCR2A=(1<<COM2A1)|(1<<WGM20)|(1<<WGM21)|(1<<CS20);
}
Функциите приемат като параметри цяло число между 0 и 100 (% от времето, в което пинът ще е с високо напрежение) и генерират ШИМ сигнал на съответните на таймерите пинове (OC0A (PD6) и OC2A (PB3) при ATMEGA88)
Кодът setTimer0(40);
ще генерира ШИМ сигнал с високо ниво на пина през 40% от времето.