Заранее извиняюсь, если не в тот раздел...
Давненько почитываю ваш форум, вот наконец-таки решился прописаться здесь. Сам я к вам с "соседнего" rcdesign.ru, ибо аз есм моделист, но паяльник люблю не меньше моделек
 
 вобщем-то идея такая:
на 32й меге (пока, на ней прототипирование) сделано меню из N пунктов, меню перещелкивает кольцом по инкременту от п.1 до N от кнопки на прерывании INT2. в пункте 1 прописана функция чтения и записи АЦП на 2хстрочный ЖКИ 2х16. Проблема в следующем: хоть и ф-ия меню и чтения/записи в ЖКИ прописана в цикле while (1), у меня проц наотрез не хочет непрерывно читать. если прощелкать 3 раза (пройти по кругу), то уже можно увидить новое значение, кароче говоря не обновляется. Код прилагаю. Сам когда-то давно на сях рубился, сейчас все вспоминаю, так что не ругайте, местами он-таки кривоват.
Пишу под AVRStudio 5.0 GCC
Заранее благодарю!
- Код: Выделить всё • Развернуть
- #include <avr/io.h>
 #include <avr/interrupt.h>
 #define RS 2 // RS - PORTC 2
 #define E 3 // E - PORTC 3
 unsigned char mode=0; // индекс меню
 unsigned char flag=0; // флаг установки меню
 unsigned int u; //показание ацп
 void delay (unsigned long int a) // программа задержки
 {
 unsigned long int b;
 for (b=a;b>0;b--);
 }
 void lcd_command (unsigned char lcd) // функция отправки командв в ЖКИ
 {
 unsigned char temp;
 temp=(lcd&~(1<<RS))|(1<<E); // старшая тетрада
 PORTC=temp;
 asm ("nop");
 PORTC=temp&~(1<<E);
 
 temp=((lcd*16)&~(1<<RS))|(1<<E); // младшая тетрада
 PORTC=temp;
 asm ("nop");
 PORTC=temp&~(1<<E);
 
 delay (100);
 }
 void lcd_data (unsigned char lcd) // отправка данных в ЖКИ
 {
 unsigned char temp;
 temp=lcd|(1<<RS)|(1<<E); // старшая тетрада
 PORTC=temp;
 asm ("nop");
 PORTC=temp&~(1<<E);
 
 temp=(lcd*16)|(1<<RS)|(1<<E); // младшая тетрада
 PORTC=temp;
 asm ("nop");
 PORTC=temp&~(1<<E);
 
 delay(100);
 }
 
 void lcd_init (void) // инициализация ЖКИ
 {
 lcd_command(0x2c);
 delay (1000);
 lcd_command(0x0c);
 delay (1000);
 lcd_command(0x01);
 delay (1000);
 }
 
 
 void clean_lcd (void) // очистка ЖКИ
 {
 lcd_command(0x01);
 }
 
 
 ISR (INT2_vect) // обработчик прерывания по нажатию кнопки
 {
 if (mode++ == 2) mode=0; // инкремент индекса меню, если ==2, то сбрасываем в 0
 flag=0; // разрешаем флаг записи
 GIFR=0x00; // сбрасываем флаг прерывания
 return;
 }
 unsigned int ADC_read (void) // чтение регисра АЦП
 {
 unsigned int v;
 ADCSRA|=(1<<ADSC);
 while ((ADCSRA&_BV(ADIF))==0x00);
 v=(ADCL|ADCH<<8);
 return v;
 }
 
 void write_adc (unsigned int u) // функция записи результата АЦП (пока)
 {
 lcd_command(0xC0); // перевод на 2ю строку
 unsigned int j; // переменная
 j=u/1000; // вычисляем тысячи
 if (j==0)
 {
 lcd_data(' '); // если 0 то пришем пусто
 }
 else
 {
 lcd_data(0x30+j); // если нет, то 0+j
 }
 u=u-j*1000; // остаток сотен
 j=u/100; // вычисляем...
 lcd_data(0x30+j); // то же самое и так до едениц
 u=u-j*100;
 j=u/10;
 lcd_data(0x30+j);
 u=u-j*10;
 j=u;
 lcd_data(0x30+j);
 }
 
 void menu(void) // функция меню
 {
 
 if (mode==0) // если индекс == 0
 {
 if (flag==0) // и запись разрешена
 {
 clean_lcd(); // чистим ЖКИ
 lcd_data('1'); // пишем "1."
 lcd_data('.');
 flag=1; // запрещяем инкремент индекса на всякий случай
 write_adc(u); // пишем в 1м разделе меню рез-т АЦП
 }
 }
 else
 if (mode==1) // тоже самое, но п. "2."
 {
 if (flag==0)
 {
 clean_lcd();
 lcd_data('2');
 lcd_data('.');
 flag=1;
 }
 }
 else
 if (mode==2) // тоже самое, но п. "3."
 {
 if (flag==0)
 {
 clean_lcd();
 lcd_data('3');
 lcd_data('.');
 flag=1;
 }
 
 }
 }
 int main(void)
 {
 DDRB&=~(1<<2);
 PORTB=0x04;
 DDRC|=0xfc;
 delay(3000);
 lcd_init();
 GICR|=(1<<INT2); // разрешить прерывания от INT2
 ADCSRA=(1<<ADEN)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0); // ВКЛ АЦП
 ADMUX=(1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3); // настраиваем АЦП...
 sei();
 while(1)
 {
 u=ADC_read(); // бесконечно преобразуем и пишем в меню
 menu();
 delay(6000);
 
 }
 }



