Консультация № 186005
11.05.2012, 11:45
0.00 руб.
0 6 0
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Помогите пожалуйста найти ошибку в программе
В результате должны выводиться время на дисплей, которое накоплено в latch
Компилятор ругается, что переменная temp должна быть long, но если сделать её такой, то как вычислять десятки сотни и тысячи?
На дисплее половина символов отображается корректно, а половина нет
Код:


#include <mega16.h>
#include <delay.h>
#include <stdio.h>
volatile unsigned long latch=0;
volatile unsigned char output_f=0;
volatile unsigned char temp=0;

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
typedef unsigned char byte;
byte command_addr;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(!(PIND&(1<<PIND2)))
{
if(TCCR0==0) //debounce
{
TCNT0=0;
//start timer 0
TCCR0=0x01; //clkio/8

PORTA.0=0;

PORTC.0=1;
PORTC.1=1;

}
}
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
if(!(PIND&(1<<PIND3)))
{
if(TCCR0!=0) //debounce
{

//stop timer
TCCR0=0;
latch+=TCNT0;

PORTA.0=1;

PORTC.0=0;
PORTC.1=0;

output_f=1;


}
}
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
latch+=0x100;
}

// Declare your global variables here

void output(unsigned long latch)
{
output_f=0;

delay_ms(10);

lcd_init(16);
lcd_clear();

lcd_gotoxy(0,0);
lcd_putsf("#Time parameter#");
delay_ms(500);
lcd_clear();
lcd_gotoxy(0,0);
command_addr=0b10000000;

temp=latch/10000000;
lcd_write_byte(command_addr,0x30+temp);
latch=latch-temp*10000000;

temp=latch/1000000;
lcd_write_byte(command_addr+1,0x30+temp);
latch=latch-temp*1000000;

temp=latch/100000;
lcd_write_byte(command_addr+2,0x30+temp);
latch=latch-temp*100000;

temp=latch/10000;
lcd_write_byte(command_addr+3,0x30+temp);
latch=latch-temp*10000;

temp=latch/1000;
lcd_write_byte(command_addr+4,0x30+temp);
latch=latch-temp*1000;

temp=latch/100;
lcd_write_byte(command_addr+5,0x30+temp);
latch=latch-temp*100;

temp=latch/10;
lcd_write_byte(command_addr+6,0x30+temp);
latch=latch-temp*10;

temp=latch/1;
lcd_write_byte(command_addr+7,0x30+temp);
latch=latch-temp*1;


}

void main()
{
// Declare your local variables here
//byte command_addr;

PORTA=0xFF;
DDRA=0xFF;

PORTB=0xFF;
DDRB=0x00;

PORTC=0xFF;
DDRC=0xFF;

PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000.000 kHz
//TCCR0=0x02;
//TCNT0=0x00;
OCR0=0x00;

MCUCR&=0xf0;
MCUCR|=(1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00);
GICR|=(1<<INT0)|(1<<INT1);
//TIMSK=0x00;

MCUCSR=0x00;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
TIFR=0x00;


PORTC=0x00;

// Global enable interrupts
#asm("sei")

while (1)
{

// Place your code here
if(output_f) output(latch);

};
}

Обсуждение

Неизвестный
11.05.2012, 12:52
общий
11.05.2012, 12:53
Код:
temp=latch/10000000;
lcd_write_byte(command_addr,0x30+temp);
latch=latch-temp*10000000;

facepalm.jpg
Это делается так:
Код:

char buffer[20];
char bp=0;
while(latch)
{
buffer[bp++]='0'+latch%10;
latch/=10;
}
while(bp)
lcd_write_byte(command_addr++,buffer[--bp]);


насчет command_addr не уверен, что нужно так записывать.
Неизвестный
11.05.2012, 15:54
общий
Попробовал как вы сказали, всё получилось!
СПАСИБО!
У меня есть ещё вопрос, я добавил после индикации latch=0; чтобы обнулять переменную
но при нажатии кнопки подключенной к INT0 у меня он продолжает считать прибавляя значение к последнему насчитанному числу.
Как сделать так чтобы таймер обнулялся перед следующим нажатием на INT0?
Неизвестный
11.05.2012, 16:25
общий
Цитата: 373177
я добавил после индикации latch=0; чтобы обнулять переменную
но при нажатии кнопки подключенной к INT0 у меня он продолжает считать прибавляя значение к последнему насчитанному числу.

В каком месте? это важно!
Если в конце функции output(), то так и должно быть, т.к. внутри функции latch становится локальной перменной и Вы можете с ней делать всё что захотите, содержимое глобальной latch не изменится.
Тут 2 выхода:
1. Передавать в функцию не значение переменной latch, а указатель на неё.
2. Занулять latch в main(). Замените строку
Код:
if(output_f) output(latch);
на
Код:
if(output_f) { output(latch); latch=0; }
Неизвестный
11.05.2012, 17:20
общий
Пробовал заменить строку, не получилось

Важно обнулить latch перед повторным пуском таймера, но при этом чтобы на дисплее выводилось текущее значение из latch
Неизвестный
11.05.2012, 17:28
общий
А так правильно будет?
Код:

if(TCCR0==0) //debounce
{
latch=0;

TCNT0=0;
//start timer 0
TCCR0=0x01; //clkio/8

PORTA.0=0;

PORTC.0=1;
PORTC.1=1;

}
Неизвестный
12.05.2012, 12:23
общий
12.05.2012, 12:31
Цитата: 373177
Пробовал заменить строку, не получилось
Т.е. также продолжает прибавлять к последнему насчитанному числу?

Цитата: 373177
А так правильно будет?
Можно и так, если работает. Тут используется глобальная latch.
Форма ответа