CodeVision AVR в вопросах и ответах
Re: CodeVision AVR в вопросах и ответах
Удаляем.. уже не актуально. Сам нашел.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
А не думали, что 12 ошибок компиляции это слишком?Amstron писал(а):Добавляю в программе операцию, которая даже и не связанна с глюком, а глюк проявляется.
Думаю, что кончилась оперативка! КАК ПРОВЕРИТЬ???
Минимальное условие для компиляции - ошибок должно быть меньше, чем единица.
Re: CodeVision AVR в вопросах и ответах
vitalik_1984 писал(а):А не думали, что 12 ошибок компиляции это слишком?Amstron писал(а):Добавляю в программе операцию, которая даже и не связанна с глюком, а глюк проявляется.
Думаю, что кончилась оперативка! КАК ПРОВЕРИТЬ???
Минимальное условие для компиляции - ошибок должно быть меньше, чем единица.
Я сделал скриншоты, которые должны помочь разобраться в данной ситуации:
Не могу ни где найти ни где в интернете настройка конфигурации компилятора, как правильно ее настроить.
В учебнике Лебедева - рассматривают старую версию компиля, где есть не все параметры.
У меня переменные на которые компиль выдает ошибки обозначены как 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 скачиваний
Re: CodeVision AVR в вопросах и ответах
Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.
Re: CodeVision AVR в вопросах и ответах
a_skr писал(а):Переводили предупреждения на русский? Компилятор дает предупреждение на возможное переполнение в 8-битном умножении. Переменная xg.
да, переводил. именно как вы и пишате.
только я не понимаю, почему раньше в этой сточке проблем не было. появилась проблема, когда программа разласлась.
да и ы меня эта переменная не может переполница, точнее ей присваваеваеться значение не больше она может быть.
другой момент - от куда компиль знает, что переменная может переполниться?
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: CodeVision AVR в вопросах и ответах
он рассматривает самый худший случай. и у Вас не ошибки, а предупреждения.Amstron писал(а):откуда (пишется слитно) компиль знает, что переменная может переполниться?
при умножении двух unsigned char в худшем случае 255х255 = 65025 = 0хFE01 - результат не влезет в unsigned char. нужно использовать unsigned short (uint16_t). об этом Вас и предупреждают.
Ставим плюсы: )
Re: CodeVision AVR в вопросах и ответах
tochka_rashod_gaza - судя по всему у Вас - типа int, а переменная xg - типа char. (xg*10) - результат типа char, т.е. обрезается до 8 бит. Или сделайте обе переменных одного типа с учетом диапазона, или явно приведите xg к int, что Вам подсказывает компилятор: (int)xg*10.
p.s. прочитайте раздел Type Conversions в справке CVAVR, там как раз про это
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;
}
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 в вопросах и ответах
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 в вопросах и ответах
Всем привет!Подскажите,как можно,с помощью одной переменной типа int,управлять сразу двумя портами PORTB и PORTD мк ATtiny2313,для вывода на них световых эффектов.
Спасибо.
И еще вопрос собрал на макетке схему,прошиваю,а она глючит,а в протеусе все работает как надо?
Спасибо.
И еще вопрос собрал на макетке схему,прошиваю,а она глючит,а в протеусе все работает как надо?
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: CodeVision AVR в вопросах и ответах
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 в вопросах и ответах
Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.
Docendo discimus
Re: CodeVision AVR в вопросах и ответах
pyzhman писал(а):Выявить место глюка с помощью контрольных точек, ловушек. И для начала проверить монтаж.
Я думаю, что проблема в компиле.
Компилю тремя разными версиями и результат глюков в разных местах.
Отключить оптимизацию не могу - не влазиет прошивка в контроллер.
Есть у кого дельное предложение?
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
У меня, пардон, уши заложило и легкая контузия. Мой предыдущий пост - для hfelyx
Docendo discimus
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: CodeVision AVR в вопросах и ответах
pyzhman, у меня аналогично.
Amstron, не надо так орать! приложите весь проект сюда. У вас какая-то принципиальная ошибка. Стек или неатомарный доступ и т.п. Компиль винить сразу не надо. Он наверное, старше Вас.
Amstron, не надо так орать! приложите весь проект сюда. У вас какая-то принципиальная ошибка. Стек или неатомарный доступ и т.п. Компиль винить сразу не надо. Он наверное, старше Вас.
Ставим плюсы: )
Re: CodeVision AVR в вопросах и ответах
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 в вопросах и ответах
Amstron, не нужно истерик, это не по-мужски. И не стоит считать себя умнее разработчиков компилятора, тем более, не одного, а трёх ! На Ваш код без слёз не взглянешь, по первым строкам всё становится ясно.
Разберитесь в своём коде, побольше читайте литературы, и проблемы решатся.
Разберитесь в своём коде, побольше читайте литературы, и проблемы решатся.
Re: CodeVision AVR в вопросах и ответах
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 в вопросах и ответах
Не может быть. Посмотрите, на какую строку ругается, где-то скобку забыли.Ругается компилятор : '(' expected
Это нужно вставить туда, где Вы хотите данные из одной переменной переслать в порты.в каком именно месте программы нужно это описывать?
Re: CodeVision AVR в вопросах и ответах
PORTB = (unsigned char)(val & 0xFF);
на эту строку и ругается.
Так эти выражения надо вставлять в цикле где работаем с этими портами,или глобально объявить и потом оперировать только переменной val ???
Спасибо!
на эту строку и ругается.
Так эти выражения надо вставлять в цикле где работаем с этими портами,или глобально объявить и потом оперировать только переменной val ???
Спасибо!
Re: CodeVision AVR в вопросах и ответах
А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 раз.