Загрузка данных



#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_ */