Скетч ардуино:
Спойлер
Код: Выделить всё
/*
** Энкодер
** Для управлением яркостью LED используется энкодер Sparkfun
*/
int brightness = 120; // яркость LED, начинаем с половины
int fadeAmount = 10; // шаг изменения яркости LED
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 12; // pin 12
const int pin_B = 11; // pin 11
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
void setup() {
// declare pin 9 to be an output:
pinMode(9, OUTPUT); // устанавливаем pin 9 как выход
pinMode(pin_A, INPUT);
pinMode(pin_B, INPUT);
currentTime = millis();
loopTime = currentTime;
}
void loop() {
currentTime = millis();
if(currentTime >= (loopTime + 5)){ // проверяем каждые 5мс (200 Гц)
encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера
encoder_B = digitalRead(pin_B); // считываем состояние выхода B энкодера
if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю
if(encoder_B) {
// выход В в полож. сост., значит вращение по часовой стрелке
// увеличиваем яркость, не более чем до 255
if(brightness + fadeAmount <= 255) brightness += fadeAmount;
}
else {
// выход В в 0 сост., значит вращение против часовой стрелки
// уменьшаем яркость, но не ниже 0
if(brightness - fadeAmount >= 0) brightness -= fadeAmount;
}
}
encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла
analogWrite(9, brightness); // устанавливаем яркость на 9 ножку
loopTime = currentTime;
}
}Спойлер
Код: Выделить всё
-- target PICmicro
include 12f683
pragma target CLOCK 4_000_000
pragma target OSC INTOSC_NOCLKOUT
pragma target WDT disabled
pragma target MCLR internal -- reset on pin A3
pragma target WDT DISABLED -- watchdog
pragma target BROWNOUT DISABLED -- brownout reset
pragma target FCMEN DISABLED -- clock monitoring
pragma target IESO DISABLED -- int/ext osc. switch
--
enable_digital_io() -- make all pins digital I/O
--OPTION_REG_NGPPU = 0 -- pull-ups ON
OSCCON_SCS = 0 -- select primary oscillator
OSCCON_IRCF = 0b110 -- 4 MHz
--
-- setting pins
alias enc_b is pin_A5
pin_A5_direction = input
alias enc_a is pin_A4 --энкодер на 2 и 3 ноге
pin_A4_direction = input
-- configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1) --включили ШИМ на 5й ноге
pwm1_on()
-- timer setup
const TIMER0_ISR_RATE = 1000 -- 1 kHz isr rate
const DELAY_SLOTS = 1 -- support slots
include timer0_isr_interval
timer0_isr_init() -- теперь мы можем отслеживать миллисекунды
--setting variables
var byte pwm
var bit old_a
--
pwm = 0
pwm1_set_dutycycle_percent(pwm) --светодиод не светится
forever loop
if check_delay(0) then --если таймер нащелкал 5мсек
set_delay(0, 5) --устанавливем новый интервал
if old_a & !enc_a then --если старое значение А высокое а новое низкое,тогда проверяем В
if enc_b then
if pwm!=254 then pwm = pwm + 1 end if --если В в высоком, то увеличиваем яркость
end if
if !enc_b then
if pwm!=0 then pwm = pwm - 1 end if --если В в низком, то уменьшаем яркость
end if
pwm1_set_dutycycle_percent(pwm)
end if
old_a = enc_a --запомнили значение входа А
end if
end loopСобственно, код:
Спойлер
Код: Выделить всё
//!**************************************************
//! Файл : button_enc.h
//! Авторское право (с) :
//! Разработка :
//! Дата создания :
//! Описание
//!
//!**************************************************
#ifndef __button_enc_H__
#define __button_enc_H__
typedef enum {NULL_ENC=0,PLUS_ENC,MINUS_ENC}REZ_ENC;
extern void Encoder_Init(void);
extern REZ_ENC Encoder_Exe(void);
#endif // __button_enc_H__
//!**************************************************
//! Файл : button_enc.c
//! Авторское право (с) :
//! Разработка : Ридико Л.И.
//! Модифицировал :
//! Разработка :
//! Дата создания :
//! Описание
//!
//!**************************************************
#include "button_enc.h"
#include "hard_config.h"
//----------------------------- Константы: -----------------------------------
enum { State0, StateA, StateB, StateAB }; //состояния энкодера
//----------------------------- Переменные: ----------------------------------
static char EncPrev; //предыдущее состояние энкодера
static char EncPrevPrev; //пред-предыдущее состояние энкодера
//----------------------- Инициализация энкодера: ----------------------------
void Encoder_Init(void)
{
EncPrev = State0; //инициализация предыдущего состояния
EncPrevPrev = State0; //инициализация пред-предыдущего состояния
}
//------------------------- Обработка энкодера: ------------------------------
REZ_ENC Encoder_Exe(void)
{
char EncCur = 0;
REZ_ENC cRezEnc=NULL_ENC;
if(!Pin_ENC_F1) {EncCur = StateA;} //опрос фазы 1 энкодера
if(!Pin_ENC_F2) {EncCur |= StateB;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == StateAB && //если предыдущее состояние StateAB
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == StateB) {cRezEnc=PLUS_ENC;}
else{ cRezEnc=MINUS_ENC;}
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
return cRezEnc;
}

