Загрузка данных
#define F_CPU 8000000UL // Частота - 8 MHz
#define number_of_led 0
#define Port_DAT PORTB
#define Pin_DAT PINB5
#define Port_CLK PORTB
#define Pin_CLK PINB7
#define N_takts 14 // сенсорная лента
#define PINS_Data PIND5
#define Port_SHCP PORTD
#define Pin_SHCP PIND6
#define Port_STCP PORTD
#define Pin_STCP PIND7
#define sens_obuch 9
#define sens_kontr 10
#define sens_demo 0
#define sens_yes 11
#define sens_nou 12
#define sens_pause 13
// #define zhest_levo 9
// #define zhest_prvo 10
// #define zhest_verx 11
// #define zhest_vniz 12
#define led_obuch 9
#define led_kontr 10
#define led_verno 11
#define led_never 12
#define led_pause 13
#define num_qst 10
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include "UniShift_Out_old.h" // сенсорная лента
//#include "UniShift_InOut_old.h" // входные платы
volatile uint8_t i, ii, j, k, all, num, num_led, play_active, key, kase, razd, punkt, num_old;
volatile uint8_t rndcase, was[num_qst+1], rnd_max = num_qst;
volatile uint8_t Out_RGB[number_of_led+1], RGB[3][number_of_led+1];
volatile uint8_t count, num_color, num_led_1, num_takt, num_bit, pause, out;
volatile uint8_t start, pp, ik_new, kod, count, DU_key; // для пульта
char r_Data, status ;
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
//const uint8_t acc[3][12] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
// {0, 0, 0, 15, 20, 19, 12, 22, 13, 14, 16, 18},
// {0, 0, 0, 0, 0, 0, 0, 0, 17, 21, 0, 0}};
// { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
const uint8_t answ[num_qst+1]={ 0,11,12,11,12,11,12,11,12,11,11};
void PLAY (char track)
{ int a,b,c;
a = (track/100);
b = (track/10)-(a*10);
c = (track/1)-(a*100)-(b*10);
UDR = 0xff;
while (!(UCSRA & (1<<UDRE))); UDR = a+48;
while (!(UCSRA & (1<<UDRE))); UDR = b+48;
while (!(UCSRA & (1<<UDRE))); UDR = c+48;
play_active = 1;
}
ISR(USARTRXC_vect)
{ status = UCSRA; r_Data = UDR;
if (r_Data == '@') play_active = 2;
}
/*
void Opros(void) // входные платы
{ num = 0;
for (j = 1; j < N_takts_In+1; j++)
if (In[j] & 0x10) num = j; //обработка In платы
}
*/
void Opros(void) // сенсорная лента
{ num = 0;
Port_STCP&=~(1<<Pin_STCP); _delay_ms(0.1);
Port_STCP|=(1<<Pin_STCP); _delay_ms(0.1);
for (j = 1; j < N_takts+1; j++)
{ if (~(PIND) & (1<<PINS_Data)) num = j;
Port_SHCP&=~(1<<Pin_SHCP); _delay_ms(0.1);
Port_SHCP|=(1<<Pin_SHCP); _delay_ms(0.1);
}
_delay_ms(1);
}
void RGB_Update(void)
{ uint8_t i;
for (i = 1; i < (number_of_led+1); i++)
{ if (Out_RGB[i] == 0) {RGB[0][i] = 0; RGB[1][i] = 0; RGB[2][i] = 0;} // нет цвета
else if (Out_RGB[i] == 1) {RGB[0][i]=100; RGB[1][i] = 0; RGB[2][i] = 0;} // красный
else if (Out_RGB[i] == 2) {RGB[0][i] = 0; RGB[1][i]=100; RGB[2][i] = 0;} // зелёный
else if (Out_RGB[i] == 3) {RGB[0][i] = 0; RGB[1][i] = 0; RGB[2][i]=100;} // синий
else if (Out_RGB[i] == 4) {RGB[0][i]=120; RGB[1][i]= 80; RGB[2][i] = 0;} // желтый
else if (Out_RGB[i] == 5) {RGB[0][i]=100; RGB[1][i]=100; RGB[2][i]=100;} // белый
}
Port_CLK &=~(1 << Pin_CLK); _delay_us(1500);
cli();
for (num_led = 1; num_led <=number_of_led; num_led++)
{ for (num_color = 0; num_color < 3; num_color++)
{ for (num_bit = 0; num_bit < 8; num_bit++)
{ Port_DAT &=~(1 << Pin_DAT);
Port_CLK &=~ (1 << Pin_CLK);
if (RGB[num_color][num_led] & (1 << num_bit)) Port_DAT |= (1 << Pin_DAT); else Port_DAT &=~(1 << Pin_DAT);
asm("nop");
Port_CLK |= (1 << Pin_CLK);
}
}
Port_CLK &=~(1 << Pin_CLK);
}
Port_DAT |=(1 << Pin_DAT); Port_CLK |=(1 << Pin_CLK);
sei();
}
void ALL_OFF () // тушим всё
{ if (number_of_led == 0) { for (j = 1; j < led_obuch; j++) Out[16+j] &=~DS; }
else { for (j = 1; j < led_obuch; j++) Out_RGB[j] = 0; RGB_Update(); }
}
void RND()
{ rndcase = 1 + rand()%rnd_max; // выбор процессора
while (was[rndcase]==1)
{ rndcase = 1 + rand()%rnd_max; // перевыбор процессора если такое уже было
for (k=0; k < rnd_max; k++) all = all + was[k]; // подсчет общего числа уже бывших вариантов
if (all > rnd_max-3) for (k=0; k < rnd_max; k++) was[k] = 0; // сброс учета бывших вариантов, когда уже почти все побывали
all = 0;
}
was[rndcase] = 1;
}
void STUDY()
{ if (number_of_led == 0) Out[16+led_obuch]|= DS; else { Out_RGB[led_obuch] = 2; RGB_Update(); }
PLAY(201); _delay_ms(1000); // обучение
//kase = 1; //Out_RGB[kase] = 2; RGB_Update();
razd = 1; punkt = 1;
while (num != sens_kontr) //&&(num != zhest_vniz)) // пока не нажат контроль
{ Opros();
// if (ik_new == sens_demo) num = sens_kontr;
if (((num == sens_pause)||(ik_new == 35))&&(play_active == 1)) // пауза
{ if (key == 0) { UDR = 'p'; key = 1; if (number_of_led == 0) Out[16+led_pause]|= DS; else Out_RGB[led_pause] = 2;}
else { UDR = 'r'; key = 0; if (number_of_led == 0) Out[16+led_pause]&=~DS; else Out_RGB[led_pause] = 0;}
if (number_of_led != 0) RGB_Update(); _delay_ms(800); ik_new = 0; }
// if ((ik_new == 4)||(ik_new == 6))
// { UDR = 's'; Out[16+punkt]&=~DS; Out[16+razd]&=~DS; //Out_RGB[kase] = 0;
// if (ik_new == 4) {punkt--; if (punkt == 0) punkt =17; } // лево
// if (ik_new == 6) {punkt++; if (punkt ==18) punkt = 1; } // право
// if ((punkt == 1)||(punkt == 2)||(punkt == 3)) razd = punkt;
// if ((punkt > 3)&&(punkt < 10)) razd = 3;
// if ((punkt >10)&&(punkt < 14)) razd =10;
// if ((punkt >14)&&(punkt < 18)) razd =14;
// Out[16+punkt]|= DS; Out[16+razd]|= DS; //Out_RGB[punkt] = 2; RGB_Update();
// _delay_ms(500); ik_new = 0;
// }
// if (ik_new == 9)
// { ALL_OFF(); UDR = 's';
// key = 0; num_old = 0;
// _delay_ms(500); ik_new = 0;
// }
// if (ik_new == 5) num = punkt;
if ((num > 0) && (num < sens_obuch))
{ ALL_OFF();
if (num_old == num) { num_old = 0; UDR = 's'; key = 0; } // if (number_of_led == 0) { Out[16+num]&=~DS; Out[16+led_pause]&=~DS; }
// else { Out_RGB[num] = 0; Out_RGB[led_pause] = 0; RGB_Update(); } }
else { PLAY(num); if (number_of_led == 0) Out[16+num]|=DS; else { Out_RGB[num] = 2; RGB_Update(); } num_old = num; }
_delay_ms(800); ik_new = 0;
}
if (play_active == 2) { play_active = key = 0; Out[16+num_old]&=~DS; if (number_of_led == 0) Out[16+led_pause]&=~DS; else { Out_RGB[led_pause] = 0; RGB_Update(); } }
// if ((ik_new == 4)||(ik_new == 5)||(ik_new == 6)) num = 13;
// if (ik_new > 0) { _delay_ms(500); ik_new = 0; }
}
ALL_OFF(); UDR = 's'; key = 0;
if (number_of_led == 0) { Out[16+led_obuch]&=~DS; Out[16+led_pause]&=~DS; } // при выходе из режима всё тушим и стоп воспроизведения
else { Out_RGB[led_obuch] = 0; Out_RGB[led_pause] = 0; RGB_Update(); }
}
void KONTROL(void)
{ if (number_of_led == 0) Out[16+led_kontr]|= DS; else { Out_RGB[led_kontr] = 2; RGB_Update(); }
PLAY(202); _delay_ms(1000); // трек контроль
srand(TCNT2); out = 1;
razd = 1; punkt = 1;
while (num != sens_obuch) //&&(num != zhest_verx)) // пока не нажато обучение
{ if (out == 1) RND(); _delay_ms(500);
// if (rndcase < 14) Out[16+rndcase+18]|= DS; else PLAY(rndcase-13+100);
PLAY(rndcase+100);
out = 0;
while ((out == 0)&&(num != sens_obuch)) //&&(num != zhest_verx))
{ Opros();
// if (ik_new == sens_demo) num = sens_obuch;
if (((num == sens_pause)||(ik_new == 35))&&(play_active == 1)) // пауза
{ if (key == 0) { UDR = 'p'; key = 1; if (number_of_led == 0) Out[16+led_pause]|= DS; else Out_RGB[led_pause] = 2;}
else { UDR = 'r'; key = 0; if (number_of_led == 0) Out[16+led_pause]&=~DS; else Out_RGB[led_pause] = 0;}
if (number_of_led != 0) RGB_Update(); _delay_ms(500); ik_new = 0; }
// if ((ik_new == 4)||(ik_new == 6))
// { UDR = 's'; Out[16+punkt]&=~DS; //Out[16+razd]&=~DS; //Out_RGB[kase] = 0;
// if (ik_new == 4) {punkt--; if (punkt == 0) punkt =17; } // лево
// if (ik_new == 6) {punkt++; if (punkt ==18) punkt = 1; } // право
// if ((punkt == 1)||(punkt == 2)||(punkt == 3)) razd = punkt;
// if ((punkt > 3)&&(punkt < 10)) razd = 3;
// if ((punkt >10)&&(punkt < 14)) razd =10;
// if ((punkt >14)&&(punkt < 18)) razd =14;
// Out[16+punkt]|= DS; //Out[16+razd]|= DS; //Out_RGB[punkt] = 2; RGB_Update();
// _delay_ms(500); ik_new = 0;
// }
// if (ik_new == 5) num = punkt;
// if (num == zhest_levo) num = sens_yes; // если жест "ДА"
// if (num == zhest_prvo) num = sens_nou; // если жест "НЕТ"
// if ((num > 0)&&(num < sens_obuch))
if ((num == sens_yes) || (num == sens_nou))
{ if (num == answ[rndcase])
{ if (number_of_led == 0) Out[16+led_verno]|= DS; else { Out_RGB[led_verno] = 2; RGB_Update(); } PLAY(203); _delay_ms(1000); // верно
if (number_of_led == 0) Out[16+led_verno]&=~DS; else { Out_RGB[led_verno] = 0; RGB_Update(); } out = 1;
}
else
{ if (number_of_led == 0) Out[16+led_never]|= DS; else { Out_RGB[led_never] = 1; RGB_Update(); } PLAY(204); _delay_ms(1000); // не верно
if (number_of_led == 0) Out[16+led_never]&=~DS; else { Out_RGB[led_never] = 0; RGB_Update(); } out = 2;
}
}
// if (num != 0) { _delay_ms(500); ik_new = 0; }
// if ((ik_new == 1)||(ik_new == 2)||(ik_new == 3)) { num = 12; ik_new = 0; }
}
ALL_OFF();
}
ALL_OFF(); UDR = 's'; key = 0;
if (number_of_led == 0) { Out[16+led_kontr]&=~DS; Out[16+led_pause]&=~DS; } // при выходе из режима всё тушим и стоп воспроизведения
else { Out_RGB[led_kontr] = 0; Out_RGB[led_pause] = 0; RGB_Update(); }
}
void DEMO(void)
{ ALL_OFF();
punkt = 1; PLAY(punkt); Out[16+punkt] |=DS;
_delay_ms(500); ik_new = num = 0;
while ((num != sens_obuch)&&(num != sens_kontr)&&(ik_new != 9))
{ Opros();
if (play_active == 2)
{ Out[16+punkt]&=~DS; Out[16+razd]&=~DS;
punkt++; if (punkt ==18) punkt = 1;
_delay_ms(500);
PLAY(punkt);
if ((punkt == 1)||(punkt == 2)||(punkt == 3)) razd = punkt;
if ((punkt > 3)&&(punkt < 10)) razd = 3;
if ((punkt >10)&&(punkt < 14)) razd =10;
if ((punkt >14)&&(punkt < 18)) razd =14;
Out[16+punkt]|= DS; Out[16+razd]|= DS; //Out_RGB[punkt] = 2; RGB_Update();
}
if (((num == sens_pause)||(ik_new == 35))&&(play_active == 1)) // пауза
{ if (key == 0) { UDR = 'p'; key = 1; if (number_of_led == 0) Out[16+led_pause]|= DS; else Out_RGB[led_pause] = 2;}
else { UDR = 'r'; key = 0; if (number_of_led == 0) Out[16+led_pause]&=~DS; else Out_RGB[led_pause] = 0;}
if (number_of_led != 0) RGB_Update(); _delay_ms(500); ik_new = 0; }
}
ALL_OFF(); UDR = 's'; key = 0; _delay_ms(500); ik_new = 0;
}
/*
ISR(INT0_vect)
{ if ((start == 1)&&(pp > 0)&&(pp < 8)) { DU_key++; }
if (start == 0) { TCNT0 = 188; start = 1; DU_key = pp = ik_new = 0;}
}
// для 8 МГц параметры 188 и 204 подобранны по осциллографу (новый пульт)
// для 16МГц параметры 120 и 152 подобранны по осциллографу (новый пульт)
ISR(TIMER0_OVF_vect)
{ TCNT0 = 204; pp++;
if (pp > 7)
{ if (start == 1)
{ if (~(PIND) & (1<<PD2))
{ if (pp== 8) kod = kod + 32; // старший разряд
if (pp== 9) kod = kod + 16; //
if (pp==10) kod = kod + 8; //
if (pp==11) kod = kod + 4; //
if (pp==12) kod = kod + 2; //
if (pp==13) kod = kod + 1; // младший разряд
}
if ((pp == 13)&&(DU_key > 4)) { ik_new = kod; start = kod = DU_key = 0; }
}
}
count++;
if (count == 250) {Out[13] &=~DS; Out[14] &=~DS;} // стоп регулятора громкости
if ((ik_new == 16)&&(play_active == 1)) {Out[14] |= DS; ik_new = 0; count = 0;} // –– громкости
if ((ik_new == 17)&&(play_active == 1)) {Out[13] |= DS; ik_new = 0; count = 0;} // ++ громкости
}
*/
ISR(TIMER2_OVF_vect)
{ TCNT2 = 2;
// Shift_Takt_In(); // входные платы
Shift_Takt(); // сенсорная лента
}
int main(void)
{
DDRB = 0b10100000; PORTB = 0b00000000;
DDRC = 0b11000000; PORTC = 0b00111111;
// DDRD = 0b11101010; PORTD = 0b00010110; // входные платы
DDRD = 0b11001000; PORTD = 0b00100000; // сенсорная лента
// TCCR0 = TCCR0 | (1<<CS02); // CTC, предделитель 256
// TIMSK = TIMSK | (1<<TOIE0); // Задаем прерывание по переполнению
// TCNT0 = 200;
TCCR2 = TCCR2 | (1<<CS22); // CTC, предделитель 256
TIMSK = TIMSK | (1<<TOIE2); // Задаем прерывание по переполнению
TCNT2 = 1;
UCSRB = (1 << RXEN)|(1 << TXEN)|(1<<RXCIE); // receive/transmit USART
UBRRL = 51;
// MCUCR = (1 << ISC01); // разрешаем прерывание по спаду вх импульса
// GICR = (1 << INT0);
sei(); // Разрешаем прерывания, аналог SREG = (1<<I);
RGB_Update(); _delay_ms(300); Opros();
while (1)
{ Opros();
// ii++; Out_RGB[ii] = 1; RGB_Update();_delay_ms(300);
// if ((ik_new == 1)||(ik_new == 2)||(ik_new == 3)) num = 12;
// if ((ik_new == 4)||(ik_new == 5)||(ik_new == 6)) num = 13;
if (num == sens_obuch) STUDY(); // обработка нажатия "ОБУЧЕНИЕ" ||(num == zhest_verx))
// if (ik_new == sens_demo) DEMO();
if (num == sens_kontr) KONTROL(); // обработка нажатия "КОНТРОЛЬ" ||(num == zhest_vniz))
// if (ik_new == sens_demo) DEMO();
_delay_ms(10);
}
}
/*
* UniShift_InOut.c
*
* Created: 16.06.2012 14:50:55
* Author: User
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "UniShift_Out_old.h"
void Shift_Takt()
{
if (takt_cnt == 0)
{
OUT_Port_SHCP&=~(1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
OUT_Port_Data &=~ OUT_Pin_Data;
OUT_Port_Data |= Out[N_takts_Out];
} else
if (takt_cnt == 1)
{
OUT_Port_SHCP|= (1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
} else
if (takt_cnt == 2)
{
OUT_Port_SHCP&=~(1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
OUT_Port_Data &=~ OUT_Pin_Data;
OUT_Port_Data|= Out[N_takts_Out-1];
} else
if ((takt_cnt & 0x01) == 1)
{
if (takt_cnt < (N_takts_Out*2)+1)
{
OUT_Port_SHCP|= (1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
} else
{
OUT_Port_SHCP&=~(1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
}
} else
if ((takt_cnt & 0x01) == 0)
{
if (takt_cnt == (N_takts_Out*2))
{
OUT_Port_SHCP&=~(1<<OUT_Pin_SHCP);
OUT_Port_STCP|= (1<<OUT_Pin_STCP);
OUT_Port_Data &=~ OUT_Pin_Data;
} else
{
OUT_Port_SHCP&=~(1<<OUT_Pin_SHCP);
OUT_Port_STCP&=~(1<<OUT_Pin_STCP);
OUT_Port_Data &=~ OUT_Pin_Data;
OUT_Port_Data|= Out[N_takts_Out+1-(takt_cnt/2+1)];
}
}
if (takt_cnt==(N_takts_Out*2)+1) takt_cnt = 0; else takt_cnt++;
}
// if (++timeout_UART > max_timeout_UART) // если превышен таймаут обмена, посылаем пакет
// {
// timeout_UART = 0;
// Answer.Command = CMD_Set;
// Answer.CRC16 = CRC16((unsigned char*)&Answer, D_len+1);
// CntAns = 0;
// UCSR0B |= (1<<UDRIE0); // разрешение прерывания по опустошению буфера USART0
// UDR0 = Answer.Command; // записываем первый байт в буфер передатчика
// }
// }
/*
int main(void)
{
// ports init
DDRA = 0b11111111; DDRB = 0b00000000; DDRE = 0b00000110; DDRG = 0b00011111;
PORTA= 0b00000000; PORTB= 0b11111111; PORTE= 0b00000110; PORTG= 0b00000000;
// T/C2 init
TCCR2 = (1<<CS20); // normal, presc.1
OCR2 = 250; // comp value
sei();
while(1)
{
if (TIFR & (1<<OCF2))
{
TIFR|= (1<<OCF2);
Shift_Takt();
}
}
}*/
/*
* UniShift_InOut.h
*
* Created: 29.06.2012 16:26:45
* Author: User
*/
#ifndef UNISHIFT_INOUT_H_
#define UNISHIFT_INOUT_H_
#define N_takts_Out 32
#define OUT_Port_SHCP PORTC
#define OUT_Pin_SHCP PINC6
#define OUT_Port_STCP PORTC
#define OUT_Pin_STCP PINC7
#define OUT_Port_Data PORTD
#define OUT_Pin_Data _BV(PD3)
#define DS _BV(PD3)
volatile unsigned int takt_cnt, Out[N_takts_Out+1];
void Shift_Takt(void);
#endif /* UNISHIFT_INOUT_H_ */