Страница 265 из 421

Re: CodeVision AVR в вопросах и ответах

Добавлено: Вт июн 18, 2013 20:29:40
Osolemio
Удаляем.. уже не актуально. Сам нашел.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Вт июн 18, 2013 21:48:17
vitalik_1984
Amstron писал(а):Добавляю в программе операцию, которая даже и не связанна с глюком, а глюк проявляется.
Думаю, что кончилась оперативка! КАК ПРОВЕРИТЬ???
А не думали, что 12 ошибок компиляции это слишком?
Минимальное условие для компиляции - ошибок должно быть меньше, чем единица.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 04:41:31
Amstron
vitalik_1984 писал(а):
Amstron писал(а):Добавляю в программе операцию, которая даже и не связанна с глюком, а глюк проявляется.
Думаю, что кончилась оперативка! КАК ПРОВЕРИТЬ???
А не думали, что 12 ошибок компиляции это слишком?
Минимальное условие для компиляции - ошибок должно быть меньше, чем единица.
Я сделал скриншоты, которые должны помочь разобраться в данной ситуации:
Не могу ни где найти ни где в интернете настройка конфигурации компилятора, как правильно ее настроить.
В учебнике Лебедева - рассматривают старую версию компиля, где есть не все параметры.

У меня переменные на которые компиль выдает ошибки обозначены как unsigned int indication_IND;
Понятия не имею, что за предьявы у компиля. Как убрать эти ошибки. Посоветуйте, пожалуйста!

Да, вот что самое интересное! Эти ошибки стали появляться, когда я стал дополнять программу дополнительными функциями, т.е. дополнять программу.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 07:48:53
a_skr
Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 08:03:36
Amstron
a_skr писал(а):Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.
да, переводил. именно как вы и пишате.
только я не понимаю, почему раньше в этой сточке проблем не было. появилась проблема, когда программа разласлась.
да и ы меня эта переменная не может переполница, точнее ей присваваеваеться значение не больше она может быть.
другой момент - от куда компиль знает, что переменная может переполниться?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 08:19:15
ibiza11
Amstron писал(а):откуда (пишется слитно) компиль знает, что переменная может переполниться?
он рассматривает самый худший случай. и у Вас не ошибки, а предупреждения.
при умножении двух unsigned char в худшем случае 255х255 = 65025 = 0хFE01 - результат не влезет в unsigned char. нужно использовать unsigned short (uint16_t). об этом Вас и предупреждают.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 08:32:21
a_skr
tochka_rashod_gaza - судя по всему у Вас - типа int, а переменная xg - типа char. (xg*10) - результат типа char, т.е. обрезается до 8 бит. Или сделайте обе переменных одного типа с учетом диапазона, или явно приведите xg к int, что Вам подсказывает компилятор: (int)xg*10.

p.s. прочитайте раздел Type Conversions в справке CVAVR, там как раз про это
СпойлерIt is important to note that if the Project|Configure|C Compiler|Code Generation|Promote char to int option isn't checked or the #pragma promotechar+ isn't used, the char, respectively unsigned char, type operands are not automatically promoted to int , respectively unsigned int, as in compilers targeted for 16 or 32 bit CPUs.
This helps writing more size and speed efficient code for an 8 bit CPU like the AVR.
To prevent overflow on 8 bit addition or multiplication, casting may be required.
The compiler issues warnings in these situations.
Example:


void main(void) {
unsigned char a=30;
unsigned char b=128;
unsigned int c;


/* This will generate an incorrect result, because the multiplication
is done on 8 bits producing an 8 bit result, which overflows.
Only after the multiplication, the 8 bit result is promoted to
unsigned int */
c=a*b;


/* Here casting forces the multiplication to be done on 16 bits,
producing an 16 bit result, without overflow */
c=(unsigned int) a*b;
}

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 16:42:02
Amstron
ibiza11 писал(а):
Amstron писал(а):откуда (пишется слитно) компиль знает, что переменная может переполниться?
он рассматривает самый худший случай. и у Вас не ошибки, а предупреждения.
при умножении двух unsigned char в худшем случае 255х255 = 65025 = 0хFE01 - результат не влезет в unsigned char. нужно использовать unsigned short (uint16_t). об этом Вас и предупреждают.
Исправил на int, ошибки пропали, а программа как работала глючно так и работает!!!

Я всего лишь добавил в функции switch еще одно сравнение 5
Спойлерcase 5:

{ bit a;

if (knopka2==2)
{
bukva_0 = 5; // S
bukva_1 = 10; // выкл
bukva_2 = 0; // 0
bukva_3 = 22; // n
a = 1;
}

if (knopka3==3)
{
bukva_0 = 5; // S
bukva_1 = 0; // 0
bukva_2 = 23; // F
bukva_3 = 23; // F
a = 0;
}

if (knopka1==1)
{ while (knopka1==1){ } ;
if (a == 1) stabilizator_GAZ = 1; else stabilizator_GAZ = 0;
menu_gaz = 0;
vukluchit_bukvu();
rejim=28;
xg = 5;
}


}

break;
Даже если внутри будет так, то тоже глючит

if (knopka2==2)
{
bukva_0 = 5; // S
bukva_1 = 10; // выкл
bukva_2 = 0; // 0
bukva_3 = 22; // n
a = 1;
}


На данный момент - хочу отказаться от switch и все сделать IF

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср июн 19, 2013 19:05:01
hfelyx
Всем привет!Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD мк ATtiny2313,для вывода на них световых эффектов.
Спасибо.
И еще вопрос собрал на макетке схему,прошиваю,а она глючит,а в протеусе все работает как надо?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 07:58:16
ibiza11
hfelyx писал(а):Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD

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

unsigned int val;
PORTB = (unsigned char)(val & 0xFF);
PORTD = (unsigned char)(val>>8);

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 08:25:25
pyzhman
Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 13:55:12
Amstron
pyzhman писал(а):Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.
Я думаю, что проблема в компиле.
Компилю тремя разными версиями и результат глюков в разных местах.
Отключить оптимизацию не могу - не влазиет прошивка в контроллер.

Есть у кого дельное предложение?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 14:01:47
pyzhman
У меня, пардон, уши заложило и легкая контузия. Мой предыдущий пост - для hfelyx

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 14:06:49
ibiza11
pyzhman, у меня аналогично.
Amstron, не надо так орать! приложите весь проект сюда. У вас какая-то принципиальная ошибка. Стек или неатомарный доступ и т.п. Компиль винить сразу не надо. Он наверное, старше Вас.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 14:56:44
Amstron
ibiza11 писал(а):pyzhman, у меня аналогично.
Amstron, не надо так орать! приложите весь проект сюда. У вас какая-то принципиальная ошибка. Стек или неатомарный доступ и т.п. Компиль винить сразу не надо. Он наверное, старше Вас.
Извиняюсь, я просто хотел обратить на себя внимание.

Выкладываю начало проекта, может быть там что то не так обозначил.
Весь проект выкладывать не буду, т.к. он имеет больше 2000 строчек.
Спойлер.equ __w1_port=0x15
.equ __w1_bit=0
#endasm

#include <ds18b20.h>
#include <delay.h>

#define in_knopok PINC.3
#define in_gaz_klapon PINC.4
#define in_ACC PINC.2
#define smena_indikacii 50 // максимум 250 через какае время будет менятся информация
#define lamp_G PORTB.2 //зеленый светодиод
#define lamp_R PORTB.1 // красный светодиод
#define sredn_tochka 5 // сколько раз будет делаться измерения для вычисления среднего значения топлива в одной точке (не в массиве)
#define proz_pri_kalibr 10 //


unsigned int ADC_dathika_benz = 0;

eeprom unsigned int polnyi_bak_gaz = 0 ;
eeprom unsigned int polnyi_bak_benz = 0 ; // сохраняется значение полного бака

bit auto_toplivo = 0;// если 0 значит в ручном режиме

unsigned int tochka_rashod_benza = 0 ; // точка отсчета
unsigned int tochka_rashod_gaza = 0 ;

unsigned int rashod_gaza = 0 ;
unsigned int rashod_benza = 0 ;
unsigned int Uroven_benzina = 0; // переменная где сохраняется вычесленное значение бензина
unsigned int Uroven_gaza = 0; // переменная где сохраняется вычесленное значение газа

unsigned int obhcil_rashod_benz = 0 ;
//unsigned int obhcil_rashod_gaz = 0 ;

eeprom unsigned int ADC_dathika_benz_polnyj = 0 ; // что бы не глючил массив
eeprom unsigned int ADC_dathika_gaz_polnyj = 0 ;


unsigned int benz_srednee[20]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

eeprom unsigned char pryamoy_benz = 1;

eeprom unsigned int Litr_gaz[101]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0};//Создаем массив где будут храниться значения АЦП с газового датчика

eeprom unsigned int Litr_benz[101]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0};//1597Создаем массив где будут храниться значения АЦП с бензинового датчика


flash unsigned char digits[] = //создаём массив с цифрами, общий катод
{0b00111111, //0
0b00000110, //1
0b01011011, //2
0b01001111, //3
0b01100110, //4 vvvv
0b01101101, //5
0b01111101, //6
0b00000111, //7
0b01111111, //8
0b01101111, //9
0b00000000, //10-номер массива - выключить все сегменты
0b01111101, // 11 "Б"
0b01111001, // 12 "Е"
0b01110110, // 13 "Н"
0b00110001, // 14 "Г"
0b01110111, // 15 "А"
0b01001111, // 16 "З"
0b00111000, // 17 "L"
0b00111110, // 18 "U"
0b01100011, // 19 "gradus"
0b00110111, //20 "П"
0b01110011 //21 "Р"
};



unsigned char yarkost_disp = 10;
// unsigned char shet_rejim;
unsigned int a_benz = 0;
unsigned char i_benz = 0;
unsigned char sec_schet = 0;
unsigned char sec = 0 ;
unsigned char min = 0;
unsigned int hours = 12;
unsigned int raschet_adc = 0;
unsigned int ADC_FOTO_srednee;
unsigned int ADC_FOTO;

unsigned char vremay_rascheta = 105; // оптимальное значение 105


unsigned char schet_FOTO;
unsigned char digit_out[4]; //переменные для работы с LED
unsigned char r; //разряд
unsigned char knopka1=11; //какая кнопка нажата
unsigned char knopka2=22;
unsigned char knopka3=33;
unsigned char z=0; // Для таймера 1
unsigned char zz=0;
bit d=0; // Для мигания дисплея в программе принемает значение с -1, 0 , 1
unsigned char n=0; // Для таймера 0
unsigned char dlinnoe_najatie_knopki; // Для подсчета длинного нажатия кнопок
unsigned char miganie_lamp;
unsigned char v_rejim;
unsigned char el_v_rejim;
unsigned char max_delta_benz;


bit x = 0; // х = 1 - мигать индикатором
bit h = 0; // выход из режима калибровки
bit sohran_znahc_DLYA_rashoda = 0;
bit g_b = 0;

bit a = 1; // а = 0 - потушить индикатор
bit v_rejime_rashoda = 0;
bit adc = 1;
bit tochka = 1;




unsigned char g = 0;
unsigned char ff;// для подсчета времени нажатия кнопки
unsigned int indication; //переменная для хранения чисел
unsigned int ADC;
unsigned int indication_IND;
unsigned int adc_data; //для результата АЦП
unsigned char rejim = 2 ; //измерения топлива

unsigned long int ADC_dathika_benz_vsr ;
unsigned long int a_benz_sredn ;


float Srednee_znahenie_ADC;
unsigned int ADC_dathika_benzzz;
// unsigned int ADC_dathika_benzzz2;
unsigned int ADC_dathika_benzs2;
float ADC_dathika_benzs;
float ADC_dathika_gaz;



unsigned char bukva_0 = 255;
unsigned char bukva_1 = 255;
unsigned char bukva_2 = 255;
unsigned char bukva_3 = 255;

unsigned char xg = 0;
unsigned char off_displey ;


unsigned int dat_BENZ; //для хранения значения бенза
unsigned int dat_GAZ; //для хранения значения газа

unsigned int dlya_kolibrovki_benza; //нужна для колибровки бензинового бака
unsigned int dlya_kolibrovki_gaza; //нужна для колибровки газового бака


int mod_ADC_dathika_benzzz=0;
float ADC_bort;

//#include <stdio.h>
//#define ADC_pr_B 500
//#define MAX_DEVICES 8 // кол-во датчиков
/*Определяем массив данных-кодов датчиков -
распределим пространство SRAM для ROM-кода устройств и бита статуса
Для каждого устройства используется 9 байтов, но только первые 8 байтом содержат ROM-код и CRC */
//unsigned char rom_codes[MAX_DEVICES][9];

//PORTB.0 первая цифра
//PORTB.5 вторая цифра
//PORTB.3 третья цифра
//PORTB.4 четвертая цифра

//eeprom unsigned char predel_zapr_benz = 0;

//eeprom int aaaa=5788;

//eeprom unsigned int obshiy_rashod_benza; //для сохранения заначения при заправке
//eeprom unsigned int obshiy_rashod_gaza ;
/*eeprom unsigned int benz_srednee[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0}; */

unsigned char av_zapr_benz;
unsigned char shet_rashod_benza = 0; // через какое время будет идти подсчет расхода
unsigned char benz_avto = 0;
bit avto_zapravka_benz = 0;
//bit migat_do_polnogo = 1;
//bit lamp_poln_baka = 0 ;
//bit led_miganie_R_G = 0;
//bit gaz_adc = 1;
bit stop_rashod_benz = 0;
float ADC_dathika_benz_avto;

////////////////////////////////////////////////////////////////////////////////////////////////////////////



interrupt [TIM0_OVF] void timer0_ovf_isr(void) //прерывание по перепонению TC/0

{

n++;
if (n>=smena_indikacii)
{n=0;
indication=indication_IND ;
// indication=1234;

digit_out[3]=indication%10; //Делим на 10 остаток в массив 1-разряд 2345%10=5 единицы
indication=indication/10; //оставляем 1-вые 3 разряда 2345/10=234
if (bukva_3 == 255) {}
else digit_out[3] = bukva_3;

digit_out[2]=indication%10; //Делим на 10 остаток в массив 2-разряд 234%10=4 десятки
indication=indication/10; //оставляем 1-вые 2 разряда 234/10=23
if (bukva_2 == 255) {}
else digit_out[2] = bukva_2;

digit_out[1]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 сотни
indication=indication/10;
if (bukva_1 == 255) {}
else digit_out[1] = bukva_1;

if (indication_IND < 1000) digit_out[0] = 10;
else digit_out[0]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 тысячи
if (bukva_0 == 255) {}
else digit_out[0] = bukva_0;


}
//преобразование в 4-х разрядный LED
r++; //с каждым срабатыванием таймера, увеличиваем переменную r на 1
if (r==4) r=0; //если r = 4 обнуляем

switch (r)
{
case 0:
PORTB &= ~(1 << 4); // бит 4 равен 0
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD
PORTB |= (1 << 0) ; // присвоить нулевому биту 1
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b101; // делитель 128
if (in_knopok==PINB.0)knopka3=3; //если в это время на входе единица, то knopka =1
else knopka3=33;
break;





case 1:
PORTB &= ~(1<<0) ; //выключаем разряд
if (a==0)
{PORTD=digits[10];} //это постоянно вкл. точка! общий катод
else
{PORTD=digits[digit_out[r]];} //PORTD.7=1;
if (tochka == 1) PORTD.7=1;
PORTB |= (1 << 5) ; //включаем разряд
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b101;
if (in_knopok==PINB.5) knopka2=2;
else knopka2=22;
break;






case 2: //подаём питание на разряд 3 (1)
PORTB &= ~(1<<5) ;
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]];
PORTB |= (1 << 3) ;
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b101;
if (in_knopok==PINB.3)knopka1=1;
else knopka1=11;

break;





case 3: //подаём питание на разряд 1 (1)
PORTB &= ~(1 << 3); // бит 3 равен 0
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD
PORTB |= (1 << 4) ; // присвоить нулевому биту 1
//TCNT2=200; // начать отсчет с 0 // переменная для регулировки яркости
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b101;

}


}


interrupt [TIM2_OVF] void timer2_ovf_isr(void) //прерывание по перепонению TC/2
{ PORTB.0 = 0, PORTB.5 = 0, PORTB.3 = 0, PORTB.4 = 0;
TCCR2B=0b0; //пределитель остановлен

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////

interrupt [TIM1_OVF] void timer1_ovf_isr(void) //прерывание по перепонению TC/1
{
//это прерывание будет с частотой 10 герц будет (10 раз в секунду)
//TCNT1 = 59285 ;// отстают должно быть оно
//TCNT1 = 59300 ; // спешат сильно
//TCNT1 = 59289; // на 6 сек перегнали за 5 часов
// 59286 надо
TCNT1L = 0x96 ;
TCNT1H = 0xE7 ; // 59286
sec_schet++;
if (sec_schet == 10)
{sec_schet = 0, sec ++;
if (sec == 60)
{min++, sec = 0;
if (min == 60)
{hours++, min = 0;
if (hours == 24) hours = 0;
}
}
}

/*
sec ++;
if (sec == 60)
{min++, sec = 0;
if (min == 60)
{hours++, min = 0;
if (hours == 24) hours = 0;
}
} */



g++;
dlinnoe_najatie_knopki++;
miganie_lamp ++;
ff++;
off_displey++;
av_zapr_benz++;
shet_rashod_benza++;
schet_FOTO++ ;

adc = 1;

if (rejim == 15) //показания топлива газа
{
if (knopka1==11) z=0;
else z++;
}


if ((rejim == 12) || (rejim == 11)||(rejim == 18)) // если выполняется одно из условий, то выполняется функция
{ //калибровка бензо/газо бака, установка времени
if (x==1) // для мигания индикатора
{d++;
if (d==1) a = !a, d = -1; }
else a = 1;
}
/* if (x==1) // для мигания индикатора // если оставить в этом варианте, то при потухании дисплея
{d++; // при входе в сервис - подмигивают цифры
if (d==1) a = !a, d = -1; }
else a = 1; */



if ((rejim == 12) || (rejim == 11)) // мигание красного светодиода в режиме калибровке бензина или газа
{g++ ; if (g > 9) g = 0, lamp_R = !lamp_R;
if (knopka1==11) zz=0;
else zz++;
if (zz==20) zz=0, h=1;//knopka1 = 11;// если h будет равно 1, то это значит выход из кал-го режима
} // держать кнопку 2 секунды, что бы выйти из калибровки



if (rejim == 14) // режим показания расхода бензина
{if (lamp_G == 0){g++ ,lamp_R = 0; if (g > 50) g = 0, lamp_R = 1;} //lamp_G == 0 надо для того чтобы ламп светился оранжевым, а подмигивал
if (knopka2==22) zz=0;
else zz++; if (zz==20) zz=0, sohran_znahc_DLYA_rashoda = 1; //20 это две секунды
}



if (rejim == 17) // режим показания расхода газа
{
if (lamp_R == 0) {g++ ,lamp_G = 0; if (g > 50) g = 0, lamp_G = 1;}
if (knopka2==22) zz=0;
else zz++; if (zz==20) zz=0, sohran_znahc_DLYA_rashoda = 1; //20 это две секунды
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////


interrupt [ADC_INT] void adc_isr(void) //прерывание по окончании преобразования
{
//в ADСW сохраняется результ. 10 битного преобразования
adc_data=ADCW; //результат переносим в ads_data
}
Немного из главного цикла
Спойлерvoid main(void)
{

// Port C initialization
DDRC=0b00000000; //все на вход
PORTC=0x00; //подтяг резисторы 1-вкл 0-откл
// Port B initialization
DDRB=0b11111111; //все на выход
PORTB=0x00; //подтяг резисторы 1-вкл 0-откл

// Port D initialization
DDRD=0b11111111; //все на выход
PORTD=0x00; //


// Настраиваем таймер 0
TCCR0B=0b100; //деление таймера 100 это 256 частота дисплея

// Настраиваем таймер 1В срабатывает по событию часы кнопки
TCCR1B=0b100;// пределитель на 256



TIMSK1 = 0b1 ;// разрешить прерывание по таймеру 1
TIMSK0 = 0b1 ;// разрешить прерывание по таймеру 0
TIMSK2 = 0b1 ;// разрешить прерывание по таймеру 2

/////////////////////////////////////////Litr_benz[65] = 1; //тут проблема, если будет НОЛЬ!!!////////////////////////////////
//////////////////////////////////////////////////// найти решение этой проблемы!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

/*/проверка датчика (ов)
if( ds18b20_init( 0, 30, 60, DS18B20_11BIT_RES ) ) //инициализация датчика. Анализ присутствия датчика
{
indication_IND=555; //delay_ms( 5000 );
}
else
{ indication_IND=222;
}; */



#asm("sei") // разрешаем прерывания

// delay_ms(5000);




while (1)

{


Smena_rejima(); //проверка режима





if (in_ACC == 0) // если ACC выключено, то гасим экран через 5 сек
{
if (off_displey > 75 )

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 17:30:37
Аlex
Amstron, не нужно истерик, это не по-мужски. И не стоит считать себя умнее разработчиков компилятора, тем более, не одного, а трёх ! На Ваш код без слёз не взглянешь, по первым строкам всё становится ясно.
Разберитесь в своём коде, побольше читайте литературы, и проблемы решатся.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 17:46:30
hfelyx
ibiza11 писал(а):
hfelyx писал(а):Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD

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

unsigned int val;
PORTB = (unsigned char)(val & 0xFF);
PORTD = (unsigned char)(val>>8);
Ругается компилятор : '(' expected
куда копать и в каком именно месте программы нужно это описывать? И надо ли для портов объявлять переменные типа так:
unsigned char b;
unsigned char d;
а потом подставить в выражение:
PORTB = (unsigned char b)(val & 0xFF);
PORTD = (unsigned char d)(val>>8);
Спасибо!

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 17:55:08
Аlex
Ругается компилятор : '(' expected
Не может быть. Посмотрите, на какую строку ругается, где-то скобку забыли.
в каком именно месте программы нужно это описывать?
Это нужно вставить туда, где Вы хотите данные из одной переменной переслать в порты.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 18:14:12
hfelyx
PORTB = (unsigned char)(val & 0xFF);
на эту строку и ругается.
Так эти выражения надо вставлять в цикле где работаем с этими портами,или глобально объявить и потом оперировать только переменной val ???
Спасибо!

Re: CodeVision AVR в вопросах и ответах

Добавлено: Чт июн 20, 2013 18:21:24
Amstron
Аlex писал(а):Amstron, не нужно истерик, это не по-мужски. И не стоит считать себя умнее разработчиков компилятора, тем более, не одного, а трёх ! На Ваш код без слёз не взглянешь, по первым строкам всё становится ясно.
Разберитесь в своём коде, побольше читайте литературы, и проблемы решатся.
Я от Котов рассчитывал на помощь, а тут опять загадки.
Лебедева я прочитал от корки до корки.
Ни где интернете не могу найти полезную информацию о том как правильно и в каком месте инициализировать переменные к примеру.

Помогите пожалуйста!
Зачем тогда обращаться за помощью, если ее не будет ?!

Я думаю, на моем примере научатся другие котята ))

Извиняюсь, я скорее всего не весь код скопировал.
Я не до копировал с верху вот эти строчки

#include <mega168.h>
#include <ds18b20.h>
#include <delay.h>
#include <1wire.h>

Сейчас что не так?

Выкладываю сново исходник
Спойлер#include <mega168.h>
#include <ds18b20.h>
#include <delay.h>
#include <1wire.h>
// #include <stdio.h> //вроде как для LCD
#asm
.equ __w1_port=8
.equ __w1_bit=0
#endasm


// для измерения температуры
unsigned char rom_code[8][9]; //масив с адресами найденых датчиков [мак кол во датчиков] []
unsigned char MAX_DEVICES ;
unsigned char nomer_datchika = 1; //переменная в которой количество присоеденённых датчиков, и номер выбранного датчика
float temp; //переменная для хранения температуры
float datchik_temp[8];
float datchik_temp_min[8];
float datchik_temp_max[8];

unsigned int nomer_dat = 0;

// unsigned int TECT ; // для теста

//unsigned char rom_codes[MAX_DEVICES][9];

#define in_knopok PINC.3
#define in_gaz_klapon PINC.4
#define in_ACC PINC.2
#define smena_indikacii 100 // максимум 250 через какае время будет менятся информация
#define lamp_G PORTB.2 //зеленый светодиод
#define lamp_R PORTB.1 // красный светодиод
#define sredn_tochka 5 // сколько раз будет делаться измерения для вычисления среднего значения топлива в одной точке (не в массиве)
#define proz_pri_kalibr 1 //

flash unsigned char digits[] = //создаём массив с цифрами, общий катод
{0b00111111, //0
0b00000110, //1
0b01011011, //2
0b01001111, //3
0b01100110, //4 vvvv
0b01101101, //5
0b01111101, //6
0b00000111, //7
0b01111111, //8
0b01101111, //9
0b00000000, //10-номер массива - выключить все сегменты
0b01111101, // 11 "Б"
0b01111001, // 12 "Е"
0b01110110, // 13 "Н"
0b00110001, // 14 "Г"
0b01110111, // 15 "А"
0b01001111, // 16 "З"
0b00111000, // 17 "L"
0b00111110, // 18 "U"
0b01100011, // 19 "gradus"
0b00110111, //20 "П"
0b01110011, //21 "Р"
0b01010100, // 22 n
0b01110001, // 23 F
0b01111000, // 24 t
0b01000000 // 25 -
//0b01000000 // 26 - S (СТАБИЛИЗАТОР ВКЛ ИЛИ ВЫКЛ ДЛЯ ДАТЧИКА)
};


eeprom unsigned char auto_toplivo = 1;// если 0 значит в ручном режиме
eeprom unsigned char avto_vremya = 0; // для возврата в режим часы через 24 секунды




eeprom unsigned char stabilizator_GAZ = 1;
eeprom unsigned char stabilizator_BENZ = 0;

eeprom unsigned int vremay_rascheta_benz = 12; // 3 секунды
eeprom unsigned int vremay_rascheta_gaz = 12;

eeprom unsigned int ADC_dathika_benz_polnyj ; // что бы не глючил массив
eeprom unsigned int ADC_dathika_gaz_polnyj ;

eeprom unsigned char pryamoy_benz ;
eeprom unsigned char pryamoy_gaz ;

eeprom unsigned char analitik_benz = 0;
eeprom unsigned char analitik_gaz = 0;

eeprom unsigned int max_delta_benz; // высчитывается в коллибровке
eeprom unsigned int max_delta_gaz;

eeprom unsigned int max_delta_benz_ustanovlenno;
eeprom unsigned int max_delta_gaz_ustanovlenno;

eeprom unsigned int tochka_rashod_benza ; // точка отсчета long
eeprom unsigned int tochka_rashod_gaza ;

eeprom unsigned int Litr_benz[101];//1597Создаем массив где будут храниться значения АЦП с бензинового датчика
eeprom unsigned int Litr_gaz[101];//Создаем массив где будут храниться значения АЦП с газового датчика

eeprom unsigned int polnyi_bak_benz ; // сохраняется значение полного бака
eeprom unsigned int polnyi_bak_gaz ;

eeprom unsigned int min_uroven_benz = 100;
eeprom unsigned int min_uroven_gaz = 100;

eeprom unsigned char zapravka_benz = 10;
eeprom unsigned char zapravka_gaz = 10;



// Здесь объявленны переменные для БЕНЗА
// Здесь объявленны переменные для ГАЗА

unsigned int benz_srednee[20];
unsigned int gaz_srednee[20];

unsigned int Uroven_benzina_dla_rashoda;
unsigned int Uroven_gaza_dla_rashoda;

unsigned int ADC_dathika_benz ;
unsigned int ADC_dathika_gaz ;

unsigned int rashod_benza ;
unsigned int rashod_gaza ;

unsigned int Uroven_benzina ; // переменная где сохраняется вычесленное значение бензина
unsigned int Uroven_gaza ; // переменная где сохраняется вычесленное значение газа

bit IGN_benz ; // смотрит включено ли зажигание
bit IGN_gaz ;

bit v_rashode_benz_migat ;
bit v_rashode_gaz_migat ;

unsigned int a_benz = 0;
unsigned int a_gaz = 0;

unsigned char i_benz = 0;
unsigned char i_gaz = 0;

unsigned int raschet_adc_BENZ = 0;
unsigned int raschet_adc_GAZ = 0;

unsigned long int ADC_dathika_benz_vsr ;
unsigned long int ADC_dathika_gaz_vsr ;

unsigned long int a_benz_sredn ;
unsigned long int a_gaz_sredn ;

unsigned int ADC_dathika_benzzz;
unsigned int ADC_dathika_gazzz;

float ADC_dathika_benzs;
float ADC_dathika_gazs;

int mod_ADC_dathika_benzzz=0; // может быть отрицателным числом
int mod_ADC_dathika_gazzz=0; // может быть отрицателным числом

unsigned int dat_BENZ; //для хранения значения бенза
unsigned int dat_GAZ; //для хранения значения газа

unsigned char menu_benzin = 0;
unsigned char menu_gaz = 0;



// здесь объявленны общии переменные


bit zap_rejim; // для запоминания последнего режива при входе в сервисное меню
bit v_dop_menu = 0; // для входа в дополнительное меню
bit x = 0; // х = 1 - мигать индикатором
bit g_b = 0; // для определение на какое топливо переключаться если в ручном рещиме
bit a = 1; // а = 0 - потушить индикатор
bit v_rejime_rashoda = 0; // если находится в режиме расхода, то = 1
bit tochka = 1; // точка третьего сегмента, включить значит = 1
bit tochka_L = 0; // точка рядом с L
unsigned char time_ACC_vyhod = 240;
unsigned char d=0; // Для мигания дисплея
unsigned char xg_max ; // выбираем максимальное значение
unsigned char xg_min ; // выбираем минимальное значение
unsigned char iz_dop_meny; // хранится режим меню для возврата из сервистного меню
unsigned char dvoinoe_najat_knopki; // переменная которая считает мин время для двойного нажатия кнопки
unsigned char vuhod_iz_zapravki; // считаем время через которое автоматически выйдет из заправочного режима
unsigned char yarkost_disp ; // для регулировки яркости дисплея
unsigned char sec_schet = 0; // считаем десятую часть секунды
unsigned char sec = 0 ; // считаем секунды
unsigned char min = 0; // считаем минуты
unsigned int hours = 12; // считаем часы
unsigned int ADC_FOTO; // считанное значение АЦП с фото датчика
unsigned char digit_out[4]; //переменные для работы с LED
unsigned char r; //разряд
unsigned char knopka1=11; // если равно 11, то кнопка не нажата. Если равно 1, то нажата
unsigned char knopka2=22;
unsigned char knopka3=33;
unsigned char z=0; // Для входа в режим колибровки когда жмем кнопку 1 и ждем 5 секунд
unsigned char n=0; // Для смены индикации
unsigned char dlinnoe_najatie_knopki; // Для подсчета длинного нажатия кнопок
unsigned char miganie_lamp; // режиме до полного бака , для отсчета времени мигания лампой
unsigned char v_rejim; // для возврата в режим
unsigned char el_v_rejim; // для возврата в режим
unsigned char g = 0; //// для мигания светодиодом в режиме колибровки
unsigned char ff;// для подсчета времени нажатия кнопки
unsigned char pereyti_v_vremy;
unsigned int indication; //переменная для хранения чисел
unsigned int indication_IND; // то что надо отобразить на индикации
unsigned int adc_data; //для результата АЦП
unsigned int bort_U; // бортовое напряжение
unsigned int max_bort_U; // бортовое напряжение максимальное
unsigned int min_bort_U; // бортовое напряжение минимальное
unsigned char rejim = 2 ; //смена режимов, 2-измерения топлива
float Srednee_znahenie_ADC;
unsigned char dly_vhoda_v_dop_meny;
unsigned char bukva_0 = 255;
unsigned char bukva_1 = 255;
unsigned char bukva_2 = 255;
unsigned char bukva_3 = 255;
unsigned int xg = 0;
unsigned char off_displey ;
unsigned int dlya_kolibrovki_baka; //нужна для колибровки бензинового бака
float ADC_bort;
unsigned char izmerenie_temperaturu;
unsigned char miganie_tochki_L;

//PORTB.0 первая цифра
//PORTB.5 вторая цифра
//PORTB.3 третья цифра
//PORTB.4 четвертая цифра












interrupt [TIM0_OVF] void timer0_ovf_isr(void) //прерывание по перепонению TC/0



{ n++;
if (n>=smena_indikacii)
{n=0;
indication=indication_IND ;
// indication=1234;

digit_out[3]=indication%10; //Делим на 10 остаток в массив 1-разряд 2345%10=5 единицы
indication=indication/10; //оставляем 1-вые 3 разряда 2345/10=234
if (bukva_3 == 255) {}
else digit_out[3] = bukva_3;

digit_out[2]=indication%10; //Делим на 10 остаток в массив 2-разряд 234%10=4 десятки
indication=indication/10; //оставляем 1-вые 2 разряда 234/10=23
if (bukva_2 == 255) {}
else digit_out[2] = bukva_2;

digit_out[1]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 сотни
indication=indication/10;
if (bukva_1 == 255) {}
else digit_out[1] = bukva_1;

if (indication_IND < 1000) digit_out[0] = 10;
else digit_out[0]=indication%10; //Делим на 10 остаток в массив 3-разряд 23%10=2 тысячи
if (bukva_0 == 255) {}
else digit_out[0] = bukva_0;
}


//преобразование в 4-х разрядный LED
r++; //с каждым срабатыванием таймера, увеличиваем переменную r на 1
if (r==4) r=0; //если r = 4 обнуляем

switch (r)

{ case 0:
PORTB &= ~(1 << 4); // бит 4 равен 0
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD
PORTB |= (1 << 0), DDRB=0b11111111; // присвоить нулевому биту 1 , DDRB=0b11111111 - для регулировки светодиодов
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b100; // делитель на 32

if (in_knopok==PINB.0)knopka3=3; //если в это время на входе единица, то knopka =1
else knopka3=33;
break;

case 1:
PORTB &= ~(1<<0), DDRB=0b11111001 ; //выключаем разряд
if (a==0)
{PORTD=digits[10];} //это постоянно вкл. точка! общий катод
else
{PORTD=digits[digit_out[r]];} //PORTD.7=1;
if (tochka == 1) PORTD.7=1;
PORTB |= (1 << 5) ; //включаем разряд
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b100; // делитель на 32

if (in_knopok==PINB.5) knopka2=2;
else knopka2=22;
break;

case 2: //подаём питание на разряд 3 (1)
PORTB &= ~(1<<5) ;
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]];
PORTB |= (1 << 3) ;
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b100; // делитель на 32

if (in_knopok==PINB.3)knopka1=1;
else knopka1=11;
break;

case 3: //подаём питание на разряд 1 (1)
PORTB &= ~(1 << 3); // бит 3 равен 0
if (a==0) PORTD=digits[10];
else PORTD=digits[digit_out[r]]; //выводим с каждым срабатыванием таймера число с массива в PORTD
if (tochka_L == 1) PORTD.7=1;
PORTB |= (1 << 4) ; // присвоить нулевому биту 1
//TCNT2=200; // начать отсчет с 0 // переменная для регулировки яркости
TCNT2=yarkost_disp; // начать отсчет с 0 // переменная для регулировки яркости
TCCR2B=0b100; // делитель на 32

}
}








interrupt [TIM2_OVF] void timer2_ovf_isr(void) //прерывание по перепонению TC/2

{ PORTB.0 = 0, PORTB.5 = 0, PORTB.3 = 0, PORTB.4 = 0 , DDRB=0b11111001 ;

TCCR2B=0b0; //пределитель остановлен
}






interrupt [TIM1_OVF] void timer1_ovf_isr(void) //прерывание по перепонению TC/1

{ //это прерывание будет с частотой 10 герц будет (10 раз в секунду)



//TCNT1 = 59285 ;// отстают должно быть оно
//TCNT1 = 59300 ; // спешат сильно
//TCNT1 = 59289; // на 6 сек перегнали за 5 часов
TCNT1L = 0x96 ;
TCNT1H = 0xE7 ; // 59286 отстают на 12 сек за 12 часов
// TCNT1L = 0x97 ;
// TCNT1H = 0xE7 ; //59287 перегнали на 5 сек за 8 часов
sec_schet++;
if (sec_schet == 10)
{sec_schet = 0, sec ++;
if (sec == 60)
{min++, sec = 0;
if (min == 60)
{hours++, min = 0;
if (hours == 24) hours = 0;
}
}
}
dvoinoe_najat_knopki++;
vuhod_iz_zapravki++;
dlinnoe_najatie_knopki++;
miganie_lamp ++;
ff++;
g++; // для мигания светодиодом в режиме колибровки
off_displey++;
dly_vhoda_v_dop_meny++;
izmerenie_temperaturu++;
miganie_tochki_L ++;
pereyti_v_vremy ++;

if (rejim == 15) //показания топлива газа
{
if (knopka1==11) z=0; // ВАЖНО для входа в режим колибровки , надо ждать 5 секунд
else z++;
}

if (rejim == 6){} // что бы не мигал индикатор когда в колибровку входит
else
{
if (x==1) // для мигания индикатора
{d++;
if (d<3)a = 0; else a = 1;

if (d>7) d = 0;
}
else a = 1;
}



if (rejim == 14) // режим показания расхода бензина
{if (lamp_G == 0){g++ ,lamp_R = 0; if (g > 18) g = 0, lamp_R = 1;} //lamp_G == 0 надо для того чтобы ламп светился оранжевым, а подмигивал

}

if (rejim == 17) // режим показания расхода газа
{
if (lamp_R == 0) {g++ ,lamp_G = 0; if (g > 18) g = 0, lamp_G = 1;}
}
}







interrupt [ADC_INT] void adc_isr(void) //прерывание по окончании преобразования

{
//в ADСW сохраняется результ. 10 битного преобразования
adc_data=ADCW; //результат переносим в ads_data
}