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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Osolemio
Родился
Сообщения: 9
Зарегистрирован: Пн сен 24, 2012 03:08:01
Откуда: Минск

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

Сообщение Osolemio »

Удаляем.. уже не актуально. Сам нашел.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

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

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

Сообщение Amstron »

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

Я сделал скриншоты, которые должны помочь разобраться в данной ситуации:
Не могу ни где найти ни где в интернете настройка конфигурации компилятора, как правильно ее настроить.
В учебнике Лебедева - рассматривают старую версию компиля, где есть не все параметры.

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

Да, вот что самое интересное! Эти ошибки стали появляться, когда я стал дополнять программу дополнительными функциями, т.е. дополнять программу.
Вложения
конфигурация5.jpeg
(83.72 КБ) 217 скачиваний
конфигурация4.jpeg
(44.14 КБ) 316 скачиваний
конфигурация3.jpeg
(61.97 КБ) 182 скачивания
конфигурация2.jpeg
(69.78 КБ) 348 скачиваний
конфигурация1.jpeg
(67.98 КБ) 319 скачиваний
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение a_skr »

Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.
Amstron
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

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

Сообщение Amstron »

a_skr писал(а):Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.

да, переводил. именно как вы и пишате.
только я не понимаю, почему раньше в этой сточке проблем не было. появилась проблема, когда программа разласлась.
да и ы меня эта переменная не может переполница, точнее ей присваваеваеться значение не больше она может быть.
другой момент - от куда компиль знает, что переменная может переполниться?
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

Amstron писал(а):откуда (пишется слитно) компиль знает, что переменная может переполниться?
он рассматривает самый худший случай. и у Вас не ошибки, а предупреждения.
при умножении двух unsigned char в худшем случае 255х255 = 65025 = 0хFE01 - результат не влезет в unsigned char. нужно использовать unsigned short (uint16_t). об этом Вас и предупреждают.
Ставим плюсы: )
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение 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;
}
Amstron
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

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

Сообщение 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
hfelyx
Встал на лапы
Сообщения: 102
Зарегистрирован: Вт дек 28, 2010 18:25:31

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

Сообщение hfelyx »

Всем привет!Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD мк ATtiny2313,для вывода на них световых эффектов.
Спасибо.
И еще вопрос собрал на макетке схему,прошиваю,а она глючит,а в протеусе все работает как надо?
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

hfelyx писал(а):Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD

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

unsigned int val;
PORTB = (unsigned char)(val & 0xFF);
PORTD = (unsigned char)(val>>8);
Ставим плюсы: )
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.
Docendo discimus
Amstron
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

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

Сообщение Amstron »

pyzhman писал(а):Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.

Я думаю, что проблема в компиле.
Компилю тремя разными версиями и результат глюков в разных местах.
Отключить оптимизацию не могу - не влазиет прошивка в контроллер.

Есть у кого дельное предложение?
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

У меня, пардон, уши заложило и легкая контузия. Мой предыдущий пост - для hfelyx
Docendo discimus
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

pyzhman, у меня аналогично.
Amstron, не надо так орать! приложите весь проект сюда. У вас какая-то принципиальная ошибка. Стек или неатомарный доступ и т.п. Компиль винить сразу не надо. Он наверное, старше Вас.
Ставим плюсы: )
Amstron
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

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

Сообщение 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 )
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Amstron, не нужно истерик, это не по-мужски. И не стоит считать себя умнее разработчиков компилятора, тем более, не одного, а трёх ! На Ваш код без слёз не взглянешь, по первым строкам всё становится ясно.
Разберитесь в своём коде, побольше читайте литературы, и проблемы решатся.
hfelyx
Встал на лапы
Сообщения: 102
Зарегистрирован: Вт дек 28, 2010 18:25:31

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

Сообщение 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);
Спасибо!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Ругается компилятор : '(' expected
Не может быть. Посмотрите, на какую строку ругается, где-то скобку забыли.

в каком именно месте программы нужно это описывать?
Это нужно вставить туда, где Вы хотите данные из одной переменной переслать в порты.
hfelyx
Встал на лапы
Сообщения: 102
Зарегистрирован: Вт дек 28, 2010 18:25:31

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

Сообщение hfelyx »

PORTB = (unsigned char)(val & 0xFF);
на эту строку и ругается.
Так эти выражения надо вставлять в цикле где работаем с этими портами,или глобально объявить и потом оперировать только переменной val ???
Спасибо!
Amstron
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

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

Сообщение 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
}
Последний раз редактировалось Amstron Чт июн 20, 2013 18:32:04, всего редактировалось 1 раз.
Ответить

Вернуться в «AVR»