"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
ATmega8/16: шим, управляемый энкодером
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
Специально с дребезгом энкодера вроде не борются, анализа текущего и предыдущего состояния хватает.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
- Реклама
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
Вот вам модели
душа человеческая темна и с легкостью обращается ко злу
Скачал архивчик... сейчас гляну 
Сам пользуюсь элементом "MOTOR-ENCODER" (раздел электромеханики) подаешь питание как на коллекторный мотор - получаешь выход как с енкодера (только он не контактный, а внутри к шинам питания привязан) (средний вывод не используется)
Добавлено after 14 minutes 27 seconds:
Странные какието цвета на модели осциллографа в этом проекте.... (перепутанные какието) не знаю, с чем это связано, но пока себе эти файлы добавлять не буду... продолжу по старинке мотор-енкодер использовать.
Сам пользуюсь элементом "MOTOR-ENCODER" (раздел электромеханики) подаешь питание как на коллекторный мотор - получаешь выход как с енкодера (только он не контактный, а внутри к шинам питания привязан) (средний вывод не используется)
Спойлер
Странные какието цвета на модели осциллографа в этом проекте.... (перепутанные какието) не знаю, с чем это связано, но пока себе эти файлы добавлять не буду... продолжу по старинке мотор-енкодер использовать.
- Вложения
-
- enc.png
- (67.01 КБ) 245 скачиваний
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
А еще там скрипт есть, а в нем "червь", и этот "червь" у вас расположен по путиIvanoff-iv писал(а):Странные какието цвета на модели осциллографа в этом проекте.... (перепутанные какието) не знаю, с чем это связано, но пока себе эти файлы добавлять не буду...
C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\SAMPLES\Generator Scripts\
Вроде ясно написал
Dimon456 писал(а): один из библиотек самого протеуса
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
код
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/eeprom.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~ (1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
bool status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
//Timer Period: 0.5ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0x00;
//Timer/Counter 2 Interrupt (s) initialisation
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
поставил энкодеры из скрипта или скрипты из энкодеров и кручу их типа в разные стороны... кнопки нажимаю/отжимаю... вольтметры по нулям... может изъять эти злосчастные кнопки из кода
Кху Ям
Спойлер
#include <stdio.h>#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/eeprom.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~ (1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
bool status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
//Timer Period: 0.5ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0x00;
//Timer/Counter 2 Interrupt (s) initialisation
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
душа человеческая темна и с легкостью обращается ко злу
- Реклама
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Покажите настройки Атмеги168 ?
И осциллограмму с выходов ШИМ надо смотреть или регистры OCR0A и OCR1AL.
Надо для отладки учиться пользоваться файлом elf.
Прерывание таймера 0,5mc много, 1ms желательно.
И это плохая модель энкодеров, но как-то работает, можно на них в протеусе, больше всех понравилось модель на Атмега8, ближе к реальности.
На кнопки не нажимать, при включении контроллера энкодеры не блокированы.
И осциллограмму с выходов ШИМ надо смотреть или регистры OCR0A и OCR1AL.
Надо для отладки учиться пользоваться файлом elf.
Прерывание таймера 0,5mc много, 1ms желательно.
И это плохая модель энкодеров, но как-то работает, можно на них в протеусе, больше всех понравилось модель на Атмега8, ближе к реальности.
На кнопки не нажимать, при включении контроллера энкодеры не блокированы.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
душа человеческая темна и с легкостью обращается ко злу
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Вам мануал на контроллер почитать надо, почитайте хотя бы про фьюзы.
Я несколько раз упоминал 16МГц, у вас результирующая не 16МГц.
Я несколько раз упоминал 16МГц, у вас результирующая не 16МГц.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
код не компилируется
* encoder.c
*
* Created: 29.01.2021 15:49:00
* Author : admin
*/
#define F_CPU 160000000UL
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <avr/eeprom.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~ (1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
bool status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xFF;
OCR2B=0x00;
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
ошибки
Build started.
Project "encoder.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\encoder.cproj" (target "Build" depends on it):
Task "RunCompilerTask"
Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --output-sync
Building file: .././main.c
Invoking: AVR/GNU C Compiler : 5.4.0
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(46,2): error: unknown type name 'bool'
bool status;
^
.././main.c: In function 'kn_init':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(176,2): warning: implicit declaration of function 'sei' [-Wimplicit-function-declaration]
sei();
^
.././main.c: At top level:
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): warning: return type defaults to 'int' [-Wimplicit-int]
ISR(TIMER2_COMPA_vect)
^
.././main.c: In function 'ISR':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): warning: type of '__vector_7' defaults to 'int' [-Wimplicit-int]
.././main.c: At top level:
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): warning: return type defaults to 'int' [-Wimplicit-int]
ISR(PCINT1_vect)
^
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): error: redefinition of 'ISR'
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): info: previous definition of 'ISR' was here
ISR(TIMER2_COMPA_vect)
^
.././main.c: In function 'ISR':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): warning: type of '__vector_4' defaults to 'int' [-Wimplicit-int]
ISR(PCINT1_vect)
^
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(204,3): warning: implicit declaration of function 'cli' [-Wimplicit-function-declaration]
cli();
^
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\include" -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega168p -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\gcc\dev\atmega168p" -c -std=gnu99 -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.c"
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\Debug\Makefile(76,1): error: recipe for target 'main.o' failed
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(212,1): warning: control reaches end of non-void function [-Wreturn-type]
}
^
make: *** [main.o] Error 1
Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "encoder.cproj" -- FAILED.
Done building project "encoder.cproj" -- FAILED.
Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========
Спойлер
/** encoder.c
*
* Created: 29.01.2021 15:49:00
* Author : admin
*/
#define F_CPU 160000000UL
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <avr/eeprom.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~ (1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
bool status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xFF;
OCR2B=0x00;
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
Спойлер
------ Build started: Project: encoder, Configuration: Debug AVR ------Build started.
Project "encoder.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\encoder.cproj" (target "Build" depends on it):
Task "RunCompilerTask"
Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --output-sync
Building file: .././main.c
Invoking: AVR/GNU C Compiler : 5.4.0
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(46,2): error: unknown type name 'bool'
bool status;
^
.././main.c: In function 'kn_init':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(176,2): warning: implicit declaration of function 'sei' [-Wimplicit-function-declaration]
sei();
^
.././main.c: At top level:
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): warning: return type defaults to 'int' [-Wimplicit-int]
ISR(TIMER2_COMPA_vect)
^
.././main.c: In function 'ISR':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): warning: type of '__vector_7' defaults to 'int' [-Wimplicit-int]
.././main.c: At top level:
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): warning: return type defaults to 'int' [-Wimplicit-int]
ISR(PCINT1_vect)
^
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): error: redefinition of 'ISR'
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(194,1): info: previous definition of 'ISR' was here
ISR(TIMER2_COMPA_vect)
^
.././main.c: In function 'ISR':
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(200,1): warning: type of '__vector_4' defaults to 'int' [-Wimplicit-int]
ISR(PCINT1_vect)
^
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(204,3): warning: implicit declaration of function 'cli' [-Wimplicit-function-declaration]
cli();
^
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\include" -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega168p -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\gcc\dev\atmega168p" -c -std=gnu99 -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.c"
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\Debug\Makefile(76,1): error: recipe for target 'main.o' failed
c:\users\admin\Documents\Atmel Studio\7.0\encoder\encoder\main.c(212,1): warning: control reaches end of non-void function [-Wreturn-type]
}
^
make: *** [main.o] Error 1
Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "encoder.cproj" -- FAILED.
Done building project "encoder.cproj" -- FAILED.
Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========
душа человеческая темна и с легкостью обращается ко злу
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Вроде как: была пропущена какая-то цель из-за ложного условия, от этого зависит целевая сборка. ???
Я в Студии не селен, может что-то в настройках проекта изменили, попробуйте создать проект заново.
Инет на это говорит следующее
Я в Студии не селен, может что-то в настройках проекта изменили, попробуйте создать проект заново.
Инет на это говорит следующее
Спойлер
Там еще картинки есть, но я сюда их вставлять не буду.При перекомпиляции проекта Atmel Studio выдает ошибку наподобие "Целевой объект "PreBuildEvent" пропущен из-за невыполненного условия; выражение ('$(PreBuildEvent)'!='') равно (''!='')", и проект не компилируется.
Это просто глюк IDE Atmel Studio, связанный с ошибочной обработкой пустого списка событий до запуска сборки проекта (Pre-build event). Глюк можно обойти, если добавить ничего не значащее событие, которое есть, но ничего не делает. Для этого откройте свойства проекта, перейдите на закладку Build Events, нажмите кнопку Edit Pre-build и добавьте в список Pre-build event command line командную строку наподобие sleep 0, нажмите OK, сохраните проект.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
не, код я не трогал... на одном компе скомпилировался, а на другом забастовка... я худею, дорогая редакция...
душа человеческая темна и с легкостью обращается ко злу
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Я бы то же хотел знать ответ на вопрос: по чему у меня на одном компе программа работает, а на другом отказывается запускаться, пишет - Память не может быть written.
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Как вариант. В свое время студия у меня работала чем то вроде тестера на вирусы, как только студия начинала вести себя подозрительно, я проверял свой комп на вирусы. В большинстве случаев так и было - вирус.
Скормите студии другой какой-нибудь проект, создайте проект пустышку, скажем, пином дрыгнуть. Начните с этого. Если заработает ищите отличия, почему на одном работает, на другом нет.
Скормите студии другой какой-нибудь проект, создайте проект пустышку, скажем, пином дрыгнуть. Начните с этого. Если заработает ищите отличия, почему на одном работает, на другом нет.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
продолжение марлезонского балета. эпизод 471. есть код энкодера в баскоме... а как бы он выглядел для атмел студии интерестно? шим в шпротеусе шимит от 0 до 100%. как бы его приспособить для С в студии
- Вложения
-
- Encoder.rar
- (1.63 КБ) 164 скачивания
душа человеческая темна и с легкостью обращается ко злу
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Вроде от прерываний уходил, и к прерываниям возвращается?
Чем тот код не устроил?
Вот 2 видео
Вот 3 видео
Все энкодеры перебрал, в 1 видео на частоте 1МГц, в 3 видео до 100.0%, это с шагом 0,1%.
Чем тот код не устроил?
Спойлер
Вот вам 1 видеоВот 2 видео
Вот 3 видео
Все энкодеры перебрал, в 1 видео на частоте 1МГц, в 3 видео до 100.0%, это с шагом 0,1%.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
код не собирается... тяжело быть идиотом о-о-о как тяжело-о-оЧем тот код не устроил?
душа человеческая темна и с легкостью обращается ко злу
посмотрел текст на бейсике. что-то там какая-то ерунда, по моему.
второй выход энкодера ни как не анализируется в прерывании.
да и условий анализа всего два, а у энкодера 4 состояния при вращении.
у меня сделано по прерыванию таймера. но я пишу на ассемблере.
Добавлено after 1 hour 33 minutes 37 seconds:
а вообще, поиск по "работа с энкодером avr" тебе вывалит кучу вариантов и на Си и на чем угодно.
второй выход энкодера ни как не анализируется в прерывании.
да и условий анализа всего два, а у энкодера 4 состояния при вращении.
у меня сделано по прерыванию таймера. но я пишу на ассемблере.
Добавлено after 1 hour 33 minutes 37 seconds:
а вообще, поиск по "работа с энкодером avr" тебе вывалит кучу вариантов и на Си и на чем угодно.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 2466
- Зарегистрирован: Сб май 07, 2011 17:52:59
код такой собрался в студии без ошибок
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~(1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
char status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
//timer period 0.5ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0x00;
//timer/counter 2 interrupt(s) init
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
ничегошеньки не работает. на выходах вместо нулей сразу +5в.
Спойлер
#define F_CPU 16000000UL#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
uint8_t EEMEM pwm1;
uint8_t EEMEM pwm2;
void init_pwm (void)
{
DDRD |= (1<<DDD6) ;
PORTD &= ~(1<<PORTD6);
DDRB |= (1<<DDB1);
PORTB &= ~(1<<PORTB1);
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A = eeprom_read_byte (&pwm1);
OCR0B=0x00;
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1=0x00;
ICR1=0x00;
OCR1A = eeprom_read_byte (&pwm2);
OCR1B=0x00;
}
typedef struct soft_enc
{
char status;
volatile uint8_t enc_state;
volatile int8_t enc_data;
volatile int8_t enc_last;
volatile int8_t enc_new;
volatile int8_t enc_diff;
volatile uint8_t enc_pin;
} soft_enc;
soft_enc encoder1;
soft_enc encoder2;
#define encoder_init(a) _encoder_init(&a)
void _encoder_init (soft_enc *_soft_enc)
{
DDRD &= ~(_soft_enc -> enc_pin);
PORTD |= (_soft_enc -> enc_pin);
}
uint8_t konvert (uint8_t data)
{
switch (data)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 1;
case 8: return 2;
case 12: return 3;
default: return 0;
}
}
#define encoder_scan(a) _encoder_scan(&a)
void _encoder_scan (soft_enc *_soft_enc)
{
uint8_t New;
if (!_soft_enc -> status)
{
New = konvert (PIND & (_soft_enc -> enc_pin));
switch(_soft_enc -> enc_state)
{
case 2:
{
if(New == 3) _soft_enc -> enc_data++;
if(New == 0) _soft_enc -> enc_data--;
break;
}
case 0:
{
if(New == 2) _soft_enc -> enc_data++;
if(New == 1) _soft_enc -> enc_data--;
break;
}
case 1:
{
if(New == 0) _soft_enc -> enc_data++;
if(New == 3) _soft_enc -> enc_data--;
break;
}
case 3:
{
if(New == 1) _soft_enc -> enc_data++;
if(New == 2) _soft_enc -> enc_data--;
break;
}
}
_soft_enc -> enc_state = New;
}
}
#define KEY_NULL 0
#define KEY_1 1
#define KEY_2 2
#define THRESHOLD 20
volatile uint8_t pressedKey = 0;
volatile uint8_t comp = 0;
void skan_kn (void)
{
uint8_t key;
if ((PINC & (1<<PINC1))==0)
key = KEY_1;
else if ((PINC & (1<<PINC2))==0)
key = KEY_2;
else {
key = KEY_NULL;
}
if (key) {
if (comp == THRESHOLD) {
comp = THRESHOLD + 10;
pressedKey = key;
return;
}
else if (comp < (THRESHOLD+5)) comp++;
}
else comp=0;
}
uint8_t get_key(void)
{
uint8_t key = pressedKey;
pressedKey = KEY_NULL;
return key;
}
void kn_init (void)
{
DDRC &= ~((1<<DDC2) | (1<<DDC1) | (1<<DDC0));
PORTC |= (1<<PORTC2) | (1<<PORTC1);
PORTC &= ~(1<<PORTC0);
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (1<<PCIE1) | (0<<PCIE0);
PCMSK1=(0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
PCIFR=(0<<PCIF2) | (1<<PCIF1) | (0<<PCIF0);
sei();
}
void init_timer2 (void)
{
//timer period 0.5ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0x00;
//timer/counter 2 interrupt(s) init
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
sei();
}
ISR(TIMER2_COMPA_vect)
{
encoder_scan(encoder1);
encoder_scan(encoder2);
}
ISR(PCINT1_vect)
{
if((PINC & (1<<(PINC0))) == 0)
{
cli();
eeprom_update_byte(&pwm1,OCR0A);
eeprom_update_byte(&pwm2,OCR1A);
OCR0A = 0;
OCR1A = 0;
while (1) {};
}
}
#define enc_relative(a) _enc_relative(&a)
int8_t _enc_relative(soft_enc *_soft_enc)
{
_soft_enc -> enc_new = _soft_enc -> enc_data / 4;
_soft_enc -> enc_diff = (int8_t)(_soft_enc -> enc_new - _soft_enc -> enc_last);
_soft_enc -> enc_last = _soft_enc -> enc_new;
return _soft_enc -> enc_diff;
}
int main()
{ uint8_t as; int8_t tm;
encoder1.enc_pin = (1<<PIND1) | (1<<PIND0);
encoder2.enc_pin = (1<<PIND3) | (1<<PIND2);
encoder_init(encoder1);
encoder_init(encoder2);
kn_init();
init_pwm();
init_timer2();
while (1)
{
tm = enc_relative(encoder1);
if(tm > 0) { if(OCR0A != 254) OCR0A++; }
if(tm < 0) { if(OCR0A != 0) OCR0A--; }
tm = enc_relative(encoder2);
if(tm > 0) { if(OCR1A != 254) OCR1A++; }
if(tm < 0) { if(OCR1A != 0) OCR1A--; }
skan_kn();
as = get_key();
if (as == KEY_1) encoder1.status = !encoder1.status;
if (as == KEY_2) encoder2.status = !encoder2.status;
}
}
душа человеческая темна и с легкостью обращается ко злу
на некотором суперфоруме некоторые индивидуумы меня забанили за маленький нигилизм в виде керамики параллельно контактам
ohmycode!
primuss3.com
primuss3.com
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Правильно. Конденсаторы на контактах не панацея. Потому что идёт обгорание контактов из за замыкания заряженного конденсатора. А также, дешевле программно решить антидребезг. Места на плате не надо. Конденсаторы покупать не надо.


