В процессе отладки программы в протеусе(atmega32) столкнулся с тем, что программа сбрасывается при выполнении с 32-битными числами таких операций, как остаток от деления, деление и, наверняка, что-нибудь ещё. Вместо команды "_delay_loop_2(5000)" почему-то также происходит сброс.
Кроме того, мне не удалось завести таймер1 - устанавливаю коэффициенты в TCCR1B, а регистр TCNT1 не увеличивает своего содержания.
Исходник:
- Код: Выделить всё
#define __AVR_ATmega32__ 1
#define OSCSPEED 8000000 /* in Hz */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/iom32.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <math.h>
#include <stdint.h>
void resetDisplay()
{
PORTB &= 0x80;
PORTD &= 0x83;
PORTB |= 0x1F;
PORTD |= 0x70;
}
void showDigit(long int* digit)
{
switch(*digit)
{
case 0:
PORTB &= 0xF2;
PORTD &= 0x8F;
break;
case 1:
PORTB &= 0xF7;
PORTD &= 0xBF;
break;
case 2:
PORTB &= 0xF8;
PORTD &= 0x9F;
break;
case 3:
PORTB &= 0xF1;
PORTD &= 0x9F;
break;
case 4:
PORTB &= 0xF5;
PORTD &= 0xAF;
break;
case 5:
PORTB &= 0xF1;
PORTD &= 0xCF;
break;
case 6:
PORTB &= 0xF0;
PORTD &= 0xCF;
break;
case 7:
PORTB &= 0xF7;
PORTD &= 0x8F;
break;
case 8:
PORTB &= 0xF0;
PORTD &= 0x8F;
break;
case 9:
PORTB &= 0xF1;
PORTD &= 0x8F;
break;
}
}
int wADC = 0;
long int adcData;
int adcFlag = 1;
unsigned int timer = 0;
ISR(SIG_OVERFLOW1)
{
PORTC = 1;
adcFlag = 0;
wADC = sqrt(adcData);
adcData = 0;
TCNT1 = 0xFD8F; // 64911
adcFlag = 1;
}
ISR(SIG_ADC)
{
PORTC = 1;
if(adcFlag)
{
long int adcTemp = ADCW;
adcTemp *= adcTemp;
adcData += adcTemp;
}
ADCSRA |= 0x50; // 0b01010000
}
int main (void)
{
adcData = 0;
PORTB = 0x0;
PORTC = 0x0;
PORTD = 0x0;
DDRB = 0x7F; // 0b01111111
DDRC = 0x1; // 0b00000001
DDRD = 0x7C; // 0b01111100
ADMUX = 0;
ADCSRA = 0xCD; // 0b11001101
TCCR1A = 0;
TCCR1B = 7; // 0b00000111
TCNT1 = 0xFD8F; // 64911
TIFR = 0;
TIMSK = 0x80; // 0b10000000
GIMSK = 0;
sei();
while(1)
{
long int num = wADC;
long int digit = 0;
num /= 10.3;
for(int i = 0; i < 2; i++)
{
timer = TCNT1;
resetDisplay();
if(i == 0) PORTB |= 0x40;
else PORTB |= 0x20;
digit = num % 10;
num /= 10;
showDigit(&digit);
//_delay_loop_2(5000);
}
resetDisplay();
wdt_reset();
}
}
Помогите, пожалуйста, решить проблемы!