eeprom-STK500

Тут обсуждаем все что связано с микроконтроллерами.

Модератор: gurvinok

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

eeprom-STK500

Сообщение AVRIK » 29 окт 2016, 18:28

Приветствую Вас!
При дальнейшем изучении программирования путем научного тыка завис на следующей задаче:
Записать байт в еепром и при необходимости считать ее оттуда.
Для совершения этокого чуда, я использовал возможный, при наличии имеющего программатора, вариант.
Алгоритм следующий: подключаем к камню STK500>Atmel Studio 6>Tools>Devise Programming>apply>memoris.
Скачиваю содержимое еепром, hex.h файл в папку, открываю, а там "непонятки"!
В студии еепром начинается с адреса 0х0060, а в скачанном файле адрес начинается с 0х1000. Да и прописанного байта, число-"77" я там не нашел.
У вас есть мультик на эту тему? Подскажете как через студию читать байт с камня? Я руководствовался видео

https://www.youtube.com/watch?v=eHXXNkWcXBk
В общем задача считать байт с камня с использованием STK500 и Atmel Studio 6.
Подскажите как это сотворить!
Снимок 1.PNG
Студио 6
Снимок 1.PNG (8.86 КБ) 1235 просмотров
Вложения
Снимок.PNG
файл с камня

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: eeprom-STK500

Сообщение gurvinok » 29 окт 2016, 22:05

Без проблем. Мультик
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: eeprom-STK500

Сообщение AVRIK » 02 ноя 2016, 21:05

Приветствую ВАС ! С STK все раскидал, не знаю откуда глюк в прошлый раз в еепром прописался, но с вашей подсказки все прояснилось. Делаю шаг следующий!!! Загружаю простинкую программку, которая в потеусе пляшет,
а тут, на камне тормоз. Блин, "я х-ею дорогая редакция", других эмоций нет!!! "Доктор", поставьте диагноз мне или
програмке! (Думаю шутки принимаются).
Вот код:

Код: Выделить всё

     * _8_zvonok_int0.c
 *
 * Created: 28.10.2016 0:06:03
 *  Author: SUN
 */ 


#define F_CPU1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
uint8_t kod EEMEM;
volatile unsigned char  A=0;
unsigned char i=0;
//__________________________________________________________________________

void port_set(void)
{
	 DDRD&=0xfb;                                       
	 PORTD&=0x04;
	 DDRB|=0xFF;
	 PORTB=0x00;
	 DDRC|=0xfe;                                      
	 PORTC&=0x00;		
}
void int0_set(void)
{
	MCUCR = 0x00;   
	MCUCR |= ((1<<ISC01)|(1<<ISC00));                                         
	GICR |= (1<<INT0);                                           
}

ISR(INT0_vect)
{		
	GICR&=~(1<<INT0);
	PORTC|=(1<<1);              //  подключается в тестовом режиме для
	PORTC&=~(1<<1);             //  наглядноти точки замера
	 i++; 	 
	 	if (PINC&(1<<PINC0))
	 	{ 
			 PORTC|=(1<<2);     // подключается в тестовом режиме для 
	         PORTC&=~(1<<2);    // наглядности результата дешифровки
			  A=(A<<1);
			  A|=1;
	 	} 
	 	else
	 	{
			 A=(A<<1);
	 	}	 	  	 
 	  if (i==8)
 	  {		  	 	  
		  eeprom_write_byte(&kod,A); 
 	  } 			   	 	                          	
      asm("nop"); 
	  GICR|=(1<<INT0);     	  
}                       

 int main (void)
{		
 	 port_set();                                                    
	   A=0;
	 int0_set();                                                                                                       	 
	asm("sei");                                          	 
    while(1)
    {	   	 
			asm("nop");	 		 					
	} 
} 
А вот его работа в протеусе:

На порте С2 дешифровка кода, но она в еепром не пишется!!!
Вложения
Снимок.PNG
Снимок.PNG (2.68 КБ) 1228 просмотров

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: eeprom-STK500

Сообщение gurvinok » 02 ноя 2016, 22:11

Вот эта переменная

Код: Выделить всё

unsigned char i=0;
используется в теле обработчика прерывания. Сотый раз повторяю, все глобальные переменные перед обработчиками прерывания должны быть обязательно volatile!
Ну и так для кучи, нельзя делать переменную счетчика глобальной, особенно с именем i. Это связано с тем, что в теле программы инструкция вида for(unsigned char i=0; i<100; i++) вызовет ошибку. Все переменные для циклов нужно инициализировать в теле функции.
Для кого я эти фильмы записываю, а я ведь уже ссылочку давал.
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: eeprom-STK500

Сообщение AVRIK » 04 ноя 2016, 04:56

Приветствую вас!
Учел все ваши подсказки,оставил одну глобальную переменную, в счетчике применил локальную и не"i". Вынес обработку с обработчика прерывания в "main"-сектор. Получилась вот такая картина:

Код: Выделить всё


 int main (void)
{	A=1;	
 	 port_set();                                                    	   
	 int0_set();                                                                                                            	 
	asm("sei");   	                                       	 
    while(1)
    {	
			 
		 unsigned char B=0;	
		unsigned char k=0;	
			switch (A)
			{				
				case 1:
		        B=(B<<1);
			    B|=1;			   
				break;
				case 0:
				B=(B<<1);				
				break;
			}			
			k++;
			if (k==8)
			{
				kod=B;
			}
	 }
					
	
			
} 

НО! При работе кода проявляется такая, не понятная мне не стыковка! В коде я подключил динамическую переменную "В", байт, в котором по битово должно создаваться число в результате обработки функцией "switch" входящего значения "А". Дело в том, что в тестовом режиме я переменной "А" присваиваю значение "1", и соответственно "В" должно быть равно "255". Когда я вместо "В" пишу "PORTB" и при тестировании в студии в ПОРТВ все пины устанавливаются в лог"1" что соответствует "255", но когда адресом создания числа указываю переменную "В",(выше представленный код), число не создается. При пошаговом тестировании в студии, маркер шага не заходит в функцию "switch", как будто компилятор не понимает куда писать результат обработки, и соответственно "kod"=0;
В чем ошибка в этот раз?
P.S. Пробовал прописать"В" глобальным, та же фигня! Прописал отдельный тест-проект с теми-же данными, работает!!!

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: eeprom-STK500

Сообщение gurvinok » 04 ноя 2016, 12:25

:D :D :D :D Ржу немогу))) Ой насмешили. Вот сейчас я просто обязан заставить вас купить книжку по C и ее проштудировать на азы программирования. Выписываю ваш же код, напишите по шагам как он работает.

Код: Выделить всё

 while(1)
    {        
      unsigned char B=0;   

         switch (A)
         {            
            case 1:
              B=(B<<1);
              B|=1;            
             break;

            case 0:
             B=(B<<1);            
             break;
         }         
    }
Я все лишнее выбросил.
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: eeprom-STK500

Сообщение AVRIK » 04 ноя 2016, 20:30

Приветствую вас!
Значит так,прочтение кода. Сначала уточню что глобальная переменная unsigned char A=1;
1) Объявляем динамическую переменную "В".
2) Устанавливаем переменную "А" в обработку оператора "switch".
3) В случае, если "А" равно "1", (что так и есть по условию )
4) Сдвигаем число прописанное в байте, и с начала это конечно "0".
следующий такт запись в пин0 число "А" B|=A; B=0b00000001;

следующий такт, сдвиг B=(1<<B);. Это будет B=0b00000010;
следующий такт, запись значение "А" в бит "0" B=0b00000011;

B=(1<<B); B=0b00000110;
B|=A; B=0b00000111; итд.
В случае если "А"=0, произойдет только сдвиг, а в пин0 по умолчанию записана "0".
Что-то не так?

А какую книжку вы мне посоветуете по теме программирования на "С"? Только не толстую!

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: eeprom-STK500

Сообщение gurvinok » 04 ноя 2016, 22:13

А теперь как по настоящему работает программа.

Код: Выделить всё

while(1)
Ага, бесконечный цикл. Входим в тело цикла.

Код: Выделить всё

unsigned char B=0;
Такс. Выделяем байт в памяти с именем В и пишем в него 0.

Код: Выделить всё

switch (A)
Ага, многомерное условие. Заходим внутрь Че у нас? Похоже единица. Цифирь переданная для сравнения равна единице? Да. Значит выполняем код за кейсом.

Код: Выделить всё

B=(B<<1);
Текс, в ячейку памяти в ОЗУ с именем В положить ее же значение сдвинутое на бит влево. (В данный момент там ноль, ну мы его и двигаем) Это что? А... Побитное ИЛИ. Нет проблем, 0 ИЛИ 1 будет 1. Походу мы нажрались и нас выкинули из бара. О, идем по следующему кругу.

Код: Выделить всё

unsigned char B=0;
Что? Опять? Дежавю? Ну ладно, удаляем старую переменную с именем В и создаем новую и записываем в нее ноль.

Код: Выделить всё

switch (A)
Ага, многомерное условие. Заходим внутрь Че у нас? Похоже единица. Цифирь переданная для сравнения равна единице? Да. Значит выполняем код за кейсом.

Код: Выделить всё

B=(B<<1);
Текс, в ячейку памяти в ОЗУ с именем В положить ее же значение сдвинутое на бит влево. (В данный момент там ноль, ну мы его и двигаем) Это что? А... Побитное ИЛИ. Нет проблем, 0 ИЛИ 1 будет 1. Ну и так далее. Теперь ошибка ясна?
На счет книги. Рекомендую эту.
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: eeprom-STK500

Сообщение AVRIK » 06 ноя 2016, 01:30

Мое приветствие! За книжку спасибо! Давно искал что по теме, по программировании много чего, а конкретно по микроконтроллерам так ничего и не нашел. Познавал мир микроконтроллеров по "мультикам". Теперь будет что прочитать. А сейчас хочу вашего совета или подсказки по поводу моего "проекта". Обсуждаемая функция "switch", это часть кода по поводу которого я и обратился к вам изначально. (Напомню, определение свой/чужой путем сравнения принятого кода с записанным в еепроме). В коде определяется лог. уровень принятого бита, и "swtch" по нему составляет байт. Дальше байт сравню с байтом в еепроме и все дела, НО!!!! Не смотря на то что по отдельности функции работают, в коде они не дают логически ожидаемого результата. Я понимаю, может я вам надоел своими примитивными вопросами, но для меня на этом этапе, эти вопросы вершина познания программирования, и для меня они важны! Спасибо за понимание и терпение! Представлю вам полный код, с учетом ваших поправок, но к сожалению не работающего, с надеждой что вы найдете время и желание просмотреть ее и подсказать в чем ошибка.

Код: Выделить всё

/*
 * _8_zvonok_int0.c
 *
 * Created: 28.10.2016 0:06:03
 *  Author: SUN
 */ 


#define F_CPU1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
uint8_t dekod EEMEM=149;               //число для сравнения с kod
volatile unsigned char  A;
unsigned char kod;

//__________________________________________________________________________

void port_set(void)
{
	 DDRD&=0xfb;                                       
	 PORTD&=0x04;
	 DDRB|=0xFF;
	 PORTB=0x00;
	 DDRC|=0xfe;                                      
	 PORTC&=0x00;		
}
void int0_set(void)
{
	MCUCR = 0x00;   
	MCUCR |= ((1<<ISC01)|(1<<ISC00));                                         
	GICR |= (1<<INT0);                                           
}

ISR(INT0_vect)
{	
	asm("nop");		
//	PORTC|=(1<<1);              //  подключается в тестовом режиме для
//	PORTC&=~(1<<1);             //  наглядноти точки замера	
	
	if ((PORTC&(1<<PINC1))!=(PINC&(1<<PINC0)))
             {		
		//	 PORTC|=(1<<2);     // подключается в тестовом режиме для 	    
		//     PORTC&=~(1<<2);    // наглядности результата дешифровки
			 A=1;	
		
			  
			 }
			 else
			 {
			 PORTC|=(1<<3);     
	         PORTC&=~(1<<3);
				 A=0;
			 }		 	 		 			  	 	  	   	 	                          	              	  
}                       

 int main (void)
{		
 	 port_set();                                                    	   
	 int0_set();                                                                                                            	 
	asm("sei");  
	 	                                       	 
    while(1)
    {	
			 
		 unsigned char B;	
		unsigned char k;	
			switch (A)
			{				
				case 1:
		        B=(B<<1);
			    B|=1;			   
				break;
				case 0:
				B=(B<<1);				
				break;
			}			
			k++;
			if (k==8)
			{
				kod=B;				
			}			
	 }									
} 


Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: eeprom-STK500

Сообщение gurvinok » 06 ноя 2016, 12:49

Честно говоря нифига не въехал зачем этот код и что он делает, но все же я его причесал.

Код: Выделить всё

/*
 * _8_zvonok_int0.c
 *
 * Created: 28.10.2016 0:06:03
 *  Author: SUN
 */


#define F_CPU1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#define DECODE	149	//число для сравнения с kod

// Макросы чтения пина
#define READ_PIN_0	(PINC & (1 << PINC1))
#define READ_PIN_1	(PINC & (1 << PINC0))

// Ваще не понимаю зачем константу в еепром писать.
// uint8_t dekod EEMEM=149;               //число для сравнения с kod

// Переменная для видимости в теле прерывания
volatile unsigned char  A;

//__________________________________________________________________________

void port_set(void)
{
    DDRD = 0xFB;                                       
    PORTD = 0x04;
    DDRB = 0xFF;
    PORTB = 0x00;
    DDRC = 0xFD;  // Чтобы читать нулевой и первый бит порта,
				  // то нужно здесь их занулить записав в DDRC 0xFD, а не 0xFE                                   
    PORTC = 0x00;      
}
void int0_set(void)
{
    MCUCR = 0x00;   
    MCUCR |= ((1<<ISC01)|(1<<ISC00));                                         
    GICR |= (1<<INT0);  
   
    // Глобальное разрешение прерывания нужно писать здесь.
    asm("sei"); 
}

ISR(INT0_vect)
{   
   //-------------------------------------//
   // asm("nop");   <--- на кой хрен это? //
   //-------------------------------------//
   
//   PORTC|=(1<<1);              //  подключается в тестовом режиме для
//   PORTC&=~(1<<1);             //  наглядноти точки замера   
   
   // Выполним условие если пины 0 и 1 порта С разные, то есть один из них 0, а второй 1
   if (READ_PIN_0 != READ_PIN_1)
	{      
      //    PORTC|=(1<<2);     // подключается в тестовом режиме для       
      //     PORTC&=~(1<<2);    // наглядности результата дешифровки
		A = 0x01;             
    }
   else
    {
		// оставлю как есть так как не понимаю смысла дергать ногой
        PORTC |= (1 << 3);     
        PORTC &= ~(1 << 3);
        A = 0x00;
	}                                                                                                  
}                       

 int main (void)
{      
	// Все переменные что неиспользуются вне main() объявляются здесь.
	unsigned char kod = 0x00;
	unsigned char B = 0x00;   
    unsigned char k = 0x00; 
	
    port_set();                                                          
    int0_set();                                                                                                               
   
                                                 
    while(1)
    {   
		// switch() тут нафиг не нужен
		if(A == 1)
		{
			B = ((B << 1) | 0x01);
		}
		else
		{
			B = (B << 1);
		}
          
        k++;
        if (k == 8)
        {
           kod = B;            
        }         
    }                           
}
Если долго мучиться, может быть получится.

Ответить