ATMega32 Помогите разобраться прошивкой

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 19, 2015 13:01:08

Сообщение osuss »

Есть проект который более менее стабильно работает под ATMega328p
Было решено перенести его на 32 мегу. Где он благополучно отказался работать.
Я уже полторы недели его ковыряю, сократил код на 90%, а воз и ныне там.
Симуляция в протеусе регулярно перезагружает МК и пишет сообщения об ошибках
UPD: Пишу в Atmel Studio 7
Изображение
Изображение
Изображение

Код, который падает
Перестает падать если убрать memset(srv_cmd1, 0, 5) перед циклом в main
или есть раскомментировать //_delay_ms(100); в том-же цикле
Еще есть ощущение что это как-то с таймером связано.
По отдельности таймер без testFunct(1) и эта функция без таймера работают отлично

Помогите советом, что я делаю не так...

Прошу отнестись с пониманием, что это кусок из всего проекта и код собирался из нескольких разных файлов в один.

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

 #define F_CPU 12500000;	
 
 #include <avr/io.h>
 #include <avr/pgmspace.h>
 #include "USART.h"
 #include "util/delay.h"				// Для _delay_ms
 
 #define BUFFER_SIZE 512
 uint8_t buf[BUFFER_SIZE+1];
 #define IO_SIZE 	4

// Структура описывающая порт
typedef struct {
	char 	name[8];
	uint8_t type;
	uint8_t state;
	uint8_t event;
	uint8_t prevState;
} portStruct;
portStruct _portsArr[IO_SIZE];					// 	static

int gmsec=0;

ISR(TIMER1_COMPA_vect) {           //every 5ms
	gmsec++;
	if (gmsec>200){			// каждые 5ms, в секунду 200 раз
		gmsec=0;
		send_Uart_str("trick");
		USART_Transmit(13);
	}
	return;
}

void testFunct(uint8_t portNum){
	//send_int_Uart(portNum);
	//USART_Transmit(13);
	//return;
	
	char port_letter='\0';		//Буква порта
	int8_t port_num=0;		//Номер порта
	
	//uint8_t i,j,k;
	uint8_t j=0,k=0;
	char srv_cmd[33];
	char sendToSrvBuff[16];
	char tmpBuff[5];
	uint8_t portChangeFlag=0;
	
	memset(srv_cmd, 0, sizeof(srv_cmd));
	memset(sendToSrvBuff, 0, sizeof(sendToSrvBuff));
	memset(tmpBuff, 0, sizeof(tmpBuff));
	tmpBuff[0]='\0';
	srv_cmd[0]='\0';
	sendToSrvBuff[0]='\0';
	
	port_letter = _portsArr[portNum].name[0];
	port_num = atoi(&_portsArr[portNum].name[1]);

	
	if (_portsArr[portNum].type == 0){
		send_Uart_str("00");
		USART_Transmit(13);
		if (_portsArr[portNum].event != 0){	//Обрабатываем события
			if ( port_letter == 'D' ){
				if (((PIND & (1<<port_num))!=0)!=_portsArr[portNum].state){ //если значение на ноге МК поменялось
					_portsArr[portNum].state=((PIND & (1<<port_num))!=0);		//пересохраняю состояние порта
					portChangeFlag=1;
				}
			}
			if ( port_letter == 'C' ){
				if (((PINC & (1<<port_num))!=0)!=_portsArr[portNum].state){ //если значение на ноге МК поменялось
					_portsArr[portNum].state=((PINC & (1<<port_num))!=0);		//пересохраняю состояние порта
					portChangeFlag=1;
				}
			}
			if ( port_letter == 'B' ){
				if (((PIND & (1<<port_num))!=0)!=_portsArr[portNum].state){ //если значение на ноге МК поменялось
					_portsArr[portNum].state=((PINB & (1<<port_num))!=0);		//пересохраняю состояние порта
					portChangeFlag=1;
				}
			}
			if ( port_letter == 'A' ){
				if (((PINA & (1<<port_num))!=0)!=_portsArr[portNum].state){ //если значение на ноге МК поменялось
					_portsArr[portNum].state=((PINA & (1<<port_num))!=0);		//пересохраняю состояние порта
					portChangeFlag=1;
				}
			}			
		}
	}
}



int main(void){	
	TCCR1B |=   (1 << WGM12);         	//Timer1 Mode 2: CTC
	TCCR1B |=   (1 << CS12);          	//Divide by 256
	
	//OCR1A    =  100;	//F_CPU / 512 * 10e-3; 	//Set CTC compare value to 5ms at 12,5 MHz AVR clock, with a prescaler of 256
	OCR1AH=0x01;
	OCR1AL=0x00;	
	TIMSK =   (1 << OCIE1A);         	//Enable T1 interrupt
	
	
	/*TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
	TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
	TCNT1H=0x00;
	TCNT1L=0x00;
	ICR1H=0x00;
	ICR1L=0x00;
	OCR1AH=0xF4;
	OCR1AL=0x23;
	OCR1BH=0x00;
	OCR1BL=0x00;
	TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (1<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);	
	*/
	
	sei();	//Запускаем обработку прерываний
	uart_init();
	
	int8_t srv_cmd1[33];
	int8_t test[64];

	_portsArr[1].event=0;
	strcpy(_portsArr[1].name,"D1");
	_portsArr[1].prevState=0;
	_portsArr[1].state=0;
	_portsArr[1].type=255;

	send_Uart_str("---->>");
	USART_Transmit(13);
	memset(buf, 0, 10);
	buf[0]='\0';
	memset(srv_cmd1, 0, 5);
	while(1){
		//send_Uart_str("---->>");
		testFunct(1);
		//_delay_ms(100);
	}
	strcpy(test, "");
	return 0;	
}
Вложения
atmega32emptyTest.zip
Архив с кодом программы
(281.35 КБ) 169 скачиваний
Реклама
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 19, 2015 13:01:08

Сообщение osuss »

Я вижу, что падает по переполнению памяти, но не могу понять где она переполняется
При этом на меге 328p этот же код работает без нареканий

Я еще сократил код, и все-равно он падает. Причем чем меньше период таймера - тем чаще падает

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

 #define F_CPU 12500000
 
 #include <avr/io.h>
 #include <avr/pgmspace.h>
 #include "USART.h"
 #include "util/delay.h"				// Для _delay_ms
 
 #define BUFFER_SIZE 512
 uint8_t buf[BUFFER_SIZE+1];
 #define IO_SIZE 	4

 // Структура описывающая порт
 typedef struct {
	 char 	name[8];
	 uint8_t type;
	 uint8_t state;
	 uint8_t event;
	 uint8_t prevState;
 } portStruct;
 portStruct _portsArr[IO_SIZE];					// 	static

 int gmsec=0;

 ISR(TIMER1_COMPA_vect) {           //every 5ms
	 gmsec++;
	 if (gmsec>200){			// каждые 5ms, в секунду 200 раз
		 gmsec=0;
		 send_Uart_str("trick");
		 USART_Transmit(13);
	 }
 }

 void testFunct(uint8_t portNum){
	 int8_t port_num=0;		//Номер порта
	 char srv_cmd[33];
	 char sendToSrvBuff[16];
	 char tmpBuff[5];
	 
	 memset(srv_cmd, 0, sizeof(srv_cmd));
	 //_delay_ms(50);
	 memset(sendToSrvBuff, 0, sizeof(sendToSrvBuff));
	 //_delay_ms(50);
	 memset(tmpBuff, 0, sizeof(tmpBuff));
	 //_delay_ms(50);
	 
	 port_num = atoi(&_portsArr[portNum].name[1]);

	 if (_portsArr[portNum].type == 0){
		 send_Uart_str("00");
		 USART_Transmit(13);
	 }
 }



 int main(void){
	 TCCR1B |=   (1 << WGM12);         	//Timer1 Mode 2: CTC
	 TCCR1B |=   (1 << CS12);          	//Divide by 256
	 
	 //OCR1A    =  100;	//F_CPU / 512 * 10e-3; 	//Set CTC compare value to 5ms at 12,5 MHz AVR clock, with a prescaler of 256
	 OCR1AH=0x00;
	 OCR1AL=0x10;
	 TIMSK =   (1 << OCIE1A);         	//Enable T1 interrupt
	 
	 sei();	//Запускаем обработку прерываний
	 uart_init();
	 
	 int8_t srv_cmd1[33];
	 int8_t test[64];

	 _portsArr[1].event=0;
	 strcpy(_portsArr[1].name,"D1");
	 _portsArr[1].prevState=0;
	 _portsArr[1].state=0;
	 _portsArr[1].type=255;

	 send_Uart_str("---->>");
	 USART_Transmit(13);
	 memset(buf, 0, 10);
	 buf[0]='\0';
	 memset(srv_cmd1, 0, 5);
	 
	 int8_t port_num=0;		//Номер порта
	 char srv_cmd[33];
	 char sendToSrvBuff[16];
	 
	 while(1){
		 //send_Uart_str("---->>");
		 testFunct(1);
		 //_delay_ms(100);

	 }
 }
Если смотреть на вот этот кусок кода

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

	 int8_t port_num=0;		//Номер порта
	 char srv_cmd[33];
	 char sendToSrvBuff[16];
	 char tmpBuff[5];
	 
	 memset(srv_cmd, 0, sizeof(srv_cmd));
	 //_delay_ms(50);
	 memset(sendToSrvBuff, 0, sizeof(sendToSrvBuff));
	 //_delay_ms(50);
	 memset(tmpBuff, 0, sizeof(tmpBuff));
	 //_delay_ms(50);
	 
	 port_num = atoi(&_portsArr[portNum].name[1]);

	 if (_portsArr[portNum].type == 0){
		 send_Uart_str("00");
		 USART_Transmit(13);
	 }
То раскомментирование любой задержки или удаление любого мемсета убирает ошибку.
Удаление
port_num = atoi(&_portsArr[portNum].name[1]); или if (_portsArr[portNum].type == 0) тоже убирает
Но причина её возникновения для меня непонятна
Реклама
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 19, 2015 13:01:08

Сообщение osuss »

Вообщем с проблемой разобрались
Помогли на другом ресурсе
Виноваты функции отправки по USART
send_Uart_str
Их нельзя вызхывать в обработчике прерываний, тк они имеют свою задержку и сбивают прерывание...
Ответить

Вернуться в «Разные вопросы по МК»