Ср авг 21, 2019 08:52:13
#define F_CPU 2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define PND4 (1<<PD4)
#define PND3 (1<<PD3)
#define PND2 (1<<PD2)
#define PND1 (1<<PD1)
#define PND0 (1<<PD0)
#define OUT PB1 //порт вывода данных
#define ERROR 111 //код ошибки
#define LED PB0 //порт, отвечающий за мигание диодом
#define but_0_50_4_9() !(PIND & PND4) //кнопка, отвечающая за числа 0, 4, 9, 50
#define but_10_60_3_8() !(PIND & PND3) //кнопка, отвечающая за числа 3, 8, 10, 60
#define but_20_70_2_7() !(PIND & PND2) //кнопка, отвечающая за числа 2, 7, 20, 70
#define but_30_80_1_6() !(PIND & PND1) //кнопка, отвечающая за числа 1, 6, 30, 90
#define but_40_90_0_5() !(PIND & PND0) //кнопка, отвечающая за числа 0, 5, 40, 90
#define but_from_0_to_40 0x20 //настраиваем на выход кнопку, покдлюченную к PC5
#define but_from_50_to_90 0x10 //настраиваем на выход кнопку, покдлюченную к PC4
#define but_from_5_to_9 0x08 //настраиваем на выход кнопку, покдлюченную к PC3
#define but_from_0_to_4 0x04 //настраиваем на выход кнопку, покдлюченную к PC2
uint8_t flag = 0;
void timer1_init(void) //таймер, настраивающий несущую 36 кГц
{
TCCR1B |= (1 << WGM12)|(1 << CS10);
TCCR1A |= (1 << COM1A0);
OCR1A = 27;
TCNT1 = 0;
}
void timer2_init(void) //таймер, отсчитывающий отрезки по 560 мкс
{
TCCR2 = (1 << CS21);
OCR2 = 140;
TCNT2 = 0;
}
void port_init(void) //инициализация портов для опроса кнопок и вывода сигнала
{
DDRB |= (1 << OUT)|(1 << LED);
PORTB |= (1 << OUT);
DDRD = 0b00000000;
PORTD = 0b00011111;
}
void timer(void) //счетчик, отсчитывающий отрезки по 560 мкс
{
if (TIFR & (1 << OCF2))
{
TIFR |= (1 << OCF2);
TCNT2 = 0;
if (flag) flag--;
}
}
void on(void) //функция, выдающая импульсы на выходе (формирует стартовый сигнал, сигнал единицы и сигнал нуля)
{
TCCR1A |= (1 << COM1A0);
TCCR1A &= ~(1 << COM1A1);
}
void off(void) //функция, выдающая паузу на выходе (формирует стартовый сигнал, сигнал единицы и сигнал нуля)
{
TCCR1A &= ~(1 << COM1A0);
TCCR1A |= (1 << COM1A1);
}
void start_func(void) //формирование стартовой функции
{
flag = 17;
on();
while (flag) timer();
flag = 8;
off();
while (flag) timer();
}
void one_func(void) //формирование сигнала единицы
{
flag = 1;
on();
while (flag) timer();
flag = 3;
off();
while (flag) timer();
}
void null_func(void) //формирование сигнала нуля
{
flag = 1;
on();
while (flag) timer();
flag = 1;
off();
while (flag) timer();
}
void signal_out(char command) //вывод сигнала
{
start_func(); //отправляем стартовый сигнал
for(char i=0; i<8; i++) //посылаем отдельно каждый бит
{
timer();
if (command & (1<<i)) one_func();
else null_func(); //если i-ый бит равен 1, отправляем 1, если 0, отправляем 0
}
for(char i=0; i<8; i++) //посылаем отдельно каждый бит
{
timer();
if (command & (1<<i)) null_func();
else one_func(); //если i-ый бит равен 1, отправляем 1, если 0, отправляем 0
}
one_func();
}
uint16_t button_handler (void) //обработка нажатых кнопок
{
uint16_t command1 = ERROR; //значение кнопок, отвечающих за десятки, в состоянии по умолчанию
uint16_t command2 = ERROR; //значение кнопок, отвечающих за единицы, в состоянии по умолчанию
uint16_t command = 0;
DDRC = but_from_0_to_40;
_delay_us(1.1);
if (but_0_50_4_9()) command1=0;
if (but_10_60_3_8()) command1=10;
if (but_20_70_2_7()) command1=20;
if (but_30_80_1_6()) command1=30;
if (but_40_90_0_5()) command1=40;
DDRC = but_from_50_to_90;
_delay_us(1.1);
if (but_0_50_4_9()) command1=50;
if (but_10_60_3_8()) command1=60;
if (but_20_70_2_7()) command1=70;
if (but_30_80_1_6()) command1=80;
if (but_40_90_0_5()) command1=90;
DDRC = but_from_5_to_9;
_delay_us(1.1);
if (but_0_50_4_9()) command2=9;
if (but_10_60_3_8()) command2=8;
if (but_20_70_2_7()) command2=7;
if (but_30_80_1_6()) command2=6;
if (but_40_90_0_5()) command2=5;
DDRC = but_from_0_to_4;
_delay_us(1.1);
if (but_0_50_4_9()) command2=4;
if (but_10_60_3_8()) command2=3;
if (but_20_70_2_7()) command2=2;
if (but_30_80_1_6()) command2=1;
if (but_40_90_0_5()) command2=0;
command=command1+command2; //вычисление номера этажа
if (command >= 100) command=ERROR; //условие выдачи ошибки
return command;
}
int main(void)
{
port_init();
timer1_init();
timer2_init();
sei();
while (1)
{
signal_out(button_handler());
}
}
Ср авг 21, 2019 09:18:43
Ср авг 21, 2019 09:39:09
Ср авг 21, 2019 10:06:07
Ср авг 21, 2019 10:23:05
вопрос был другим, это факт. но от того, какой вопрос вы ставите, зависит результат. если бы люди хотели достать Луну с неба для изучения, они до сих пор бы не знали о том, что она летает вокруг Земли. люди поставили другие вопросы - и нашли решения без необходимости доставать Луну.dzzzzzzz писал(а):вопрос был немного другим
Ср авг 21, 2019 10:23:48
Ср авг 21, 2019 10:37:44
Ср авг 21, 2019 11:17:56
Ср авг 21, 2019 11:46:40
Ср авг 21, 2019 12:13:49
Ср авг 21, 2019 12:31:45
Ср авг 21, 2019 12:36:08
Ср авг 21, 2019 12:44:59
Ср авг 21, 2019 13:07:09
Ср авг 21, 2019 13:07:27
Ср авг 21, 2019 13:18:03
Ср авг 21, 2019 13:35:06
мда... это вам кто-то подсказал, или вы сами додумались? вот здесь https://simple-devices.ru/prj/9-electr/ ... te-control есть исходник передатчика RC5 - там немного другие принципы, но модуляция и т.п. все то же самое. и как раз attiny13 и, вы не поверите! - там IR-посылка формируется вместе с модуляцией на тупых _delay_us! так шта...ПростоНуб писал(а):Ну и Ваш вариант не универсален. Например, на той же ATtiny13A только один таймер и именно его нужно будет использовать для модуляции IR. Для 100Гц уже таймера не останется
Ср авг 21, 2019 13:42:12
Ср авг 21, 2019 13:59:23
хотите поспорить? я могу доказать.ПростоНуб писал(а):приведенный Вами в качестве примера код, совершенно не работоспособен при разрешенных прерываниях
ISR(TIMER0_OVF_vect){
PINB |= 1;
}
ISR(TIMER0_OVF_vect){
PINB |= 1;
32: b0 9a sbi 0x16, 0 ; 22
}
34: 18 95 reti
Ср авг 21, 2019 14:10:29