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

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

Добавлено: Ср май 18, 2016 17:58:43
ra9ust
Ок.

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

Добавлено: Ср май 18, 2016 21:47:49
ra9ust
Кстати вот код,прекрасно отрабатывает даже просто замыканием проводком вместо кнопки,

if(PINB.4==0)df++; // это антидребезг
if(PINB.4==1)df=0;
if(df==3)w++; //переключение часов,будильника,таймера, кнопка time alarm
if(w==6)w=1;

код размещен у меня в обработчике прерывания в 100Гц от таймера2 по совпадению.
как видим задержка обработки кнопки 30 миллисекунд,оптимальное значение.
Видно, что кнопка переключает 5 режимов по кругу.

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

Добавлено: Чт май 19, 2016 07:39:43
COKPOWEHEU
ra9ust писал(а):прокомментируете, как что можно улучшить или поменять?
В первую очередь - отформатировать код.
Добавить отступы перед каждым блоком кода (2-4 пробела или табуляция). Кстати, где-то они у вас одного типа, где-то другого, а где-то никакого.
Разнести объявления переменных на разные строчки или убрать кучу названий типа из одной (в строке 29, например, четыре ключевых слова char, когда достаточно одного)
Дать переменным осмысленные имена, а не просто буквы английского алфавита подряд
Массив с кодами цифр (digit) лучше заполнять сдвигами и логическими операциями, примерно так

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

#define SEG_A 0
#define SEG_B 1
...
PROGMEM const char digit[]={ //объявление в стиле avr-gcc, мне он привычнее
  (1<<SEG_A | 1<<SEG_B | 1<<SEG_C | 1<<SEG_D | 1<<SEG_E | 1<<SEF_F),
  (1<<SEG_B | 1<<SEG_C),
...
};
Хоть это и выглядит длиннее, зато понятнее и проще редактировать если захотите изменить разводку платы.
PORTD=digit[se]|PORTD.0<<0;
Вот это действие мне непонятно. Вы хотите поменять все биты кроме нулевого? Обычно это делается как-то так

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

PORTD = (PORTD &~(1<<0) ) | digit[se];
PORTD = (PORTD & 0b11111110) | digit[se];
PORTD = (PORTD & 0xF7) | digit[se];
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x02;
TCCR0B=0x04;
TCNT0=0x00;
OCR0A=0xB7; // динамическая индикация 83 Гц
OCR0B=0x00;
Выкиньте этот автосгенерированный мусор! Лучше разобраться самостоятельно и записать по-человечески. Не говоря о простыне бесполезных комментариев и традиционном отсутствии форматирования.
read_adc(6);
a=(ADCH*0.389); // показатель преобразования из АЦП до 99
Функция read_adc() сама по себе должна возвращать значение АЦП, почему вы этим не пользуетесь? Ну и использовать числа с плавающей точкой без крайней необходимости не стоит.
Вообще, в main() какая-то каша, на мой взгляд. Без форматирования и комментариев сложно разобраться что же имелось в виду.
В прерывании Int1 напрашивается вынести проверку PC4 во внешний if или использовать массив переменных, что-то вроде if( PINC & (1<<4) )arr[w]++;

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

Добавлено: Чт май 19, 2016 08:38:01
ra9ust
Согласен что с нулевым битом мне тоже запись непонятна,хотя и работает,кто то подсказал так сделать, а вот ваш вариант с двоичным представлением порта конечно понятнее,буду знать. А комментарии кол генератора пока не стал убирать,а касаемо регистров таймеров и прочего то в самом начале изучения так и делал расписывая на бумаге регистр и вручную выставлял каждый бит согласно даташиту. С генератором кода однако удобнее да и значения не особо отличаются и мне так проще. Отступы и прочее я необрашал внимания,пока экспериментирую.ацп совсем бегло прочитал особо не вдаваясь поэтому написал пока так лишь бы работало. Еще месяц назад и понятия не имел как устроен контроллер и тем более что то написать на него.

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

Добавлено: Чт май 19, 2016 08:54:04
ra9ust
А вот насчет того что функция ацп сама может возвращать, можете примерно написать как оно должно быть применительно к моему варианту?

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

Добавлено: Чт май 19, 2016 11:43:34
pokk
Ну как-то так

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

unsigned char ADC;  
  f=10;e=11;
  ADC=read_adc(6);
  a=(ADC*0.389); // показатель преобразования из АЦП до 99
  g=a%10;         // а больше и не надо,0-100 градусов,(10-50)
  h=a/10;
или так

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

  f=10;e=11;
  a=(read_adc(6)*0.389); // показатель преобразования из АЦП до 99
  g=a%10;         // а больше и не надо,0-100 градусов,(10-50)
  h=a/10;

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

Добавлено: Чт май 19, 2016 16:02:44
ra9ust
Так а я не использовал плавающую точку, выводятся только целые значения от 00 до 99.

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

Добавлено: Чт май 19, 2016 21:43:53
COKPOWEHEU
ra9ust писал(а):Так а я не использовал плавающую точку, выводятся только целые значения от 00 до 99.
0,389 по-вашему не число с плавающей точкой?
Я имел в виду скорее что-то типа такого
a = (unsigned char)( ( (unsigned int)read_adc(6)*100) >>8 );
Перевод в unsigned int нужен для корректного умножения на 100, потому что получается двухбайтное число, а 100/256 составляет как раз 0,39. Только работает на порядки быстрее умножения дробных чисел.
ra9ust писал(а):С генератором кода однако удобнее да и значения не особо отличаются и мне так проще. Отступы и прочее я необрашал внимания
Проще пока не понадобится что-то исправить. С форматированием тоже самое - когда захотите что-то исправить будете мучиться что к чему относится. Ну и выкладывать такое на всеобщее обозрение мне было бы стыдно, надо же уважать тех, кто хочет помочь.

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

Добавлено: Чт май 19, 2016 21:48:00
WiseLord
А 0.389 о это что, про-вашему, если не число с плавающей точкой? Вы представляете, насколько медленно и ресурсоёмко это на 8бит контроллере?

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

Добавлено: Чт май 19, 2016 22:06:40
ra9ust
Ну, ладно, мне например несложно искать и исправлять, все-таки каждому свое, а дробное число просто подогнал чтобы под 99 уместить,ну да ладно.Всё это эксперименты...

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

Добавлено: Пн май 23, 2016 15:19:42
c717411
CV 3.12

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

lcd_gotoxy(0,0);
lcd_puts(s); 
lcd_gotoxy(0,1);
lcd_puts(s);
простой код, выводит на LCD крякозябры в первой строке, вторая пустая. Если закомментировать первый gotoxy - выводит как надо первую строку, вторую пустую. Как починить?

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

Добавлено: Пн май 23, 2016 15:48:25
*Trigger*
Для начала - показать весь код. Откуда мы знаем, что там у Вас в строке s и как инициализирован дисплей?

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

Добавлено: Пн май 30, 2016 18:15:32
DataLife
Доброго времени суток.
Помоги, пожалуйста, разобраться.

Стоит задача в измерении частоты импульсов и их длины (продолжительности).
Перечитал много статей, решил воспользоваться материалом отсюда. Таймер в режиме захвата и так далее...

Вышел вот такой код:
Спойлер/*****************************************************
Chip type : ATmega8
AVR Core Clock frequency: 16,000000 MHz
*****************************************************/

#include <mega8.h>
#include <alcd.h>
#include <delay.h>
#include <stdio.h>

#define INPUT_PIN PINB.0


// Обьявзяем переменные
unsigned char lcd_buffer_1[16];
unsigned char lcd_buffer_2[16];

unsigned int OverflowP, OverflowF; //счётчик переполнений для таймера 1
unsigned int EdgeR, EdgeF; //время переднего фронта и заднего фронта
unsigned int Pulse1, Pulse2; //время переднего двух фронтов
unsigned long PulseClocks; //количество тактовых импульсов внутри импульса на входе ICP
unsigned long FreqClocks; //количество тактовых импульсов между импульсами на входе INT1
bit FreqFlag = 1; // флаг для измерение частоты

// Переполнения таймера измерения ДЛИНЫ импульса
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
OverflowP++; //инкрементируется количество переполнений
OverflowF++;
}

// Захват импульса
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
//Блок для измерения длительности импульса
if(INPUT_PIN == 1) //если на входе захвата 1 (передний фронт ПОЛОЖИТЕЛЬНОГО импульса)
{
EdgeF = ICR1; //запоминаем значениие счётчика
TCCR1B &= ~(1<<ICES1); //устанавливаем прерывание по спадающему фронту импульса
OverflowP = 0; //обнуляем количество переполнений счётчика

if (FreqFlag == 1) // измеряем частоту
{
Pulse1 = ICR1; // запоминаем значения счётчика при первом импульсе
OverflowF = 0; // сбрасываем счётчик прерываний
FreqFlag = 0; // сбрасываем флаг для подсчёта второго импульса
}
else
{
Pulse2 = ICR1; // запомингаем значения счётчика при втором импульсе
FreqFlag = 1; // устанавливаем флаг для подсчёта второго импульса
/** РАСЧЁТ ЧАСТОТЫ **/
FreqClocks = ((unsigned long)Pulse2 - (unsigned long)Pulse1 + ((unsigned long)OverflowF *65535)); // количество "тиков" в периоде. Один "тик" = 1/16 мкс при 16 МГц
};
}
else //если на входе захвата 0 (задний фронт ПОЛОЖИТЕЛЬНОГО импульса)
{
EdgeR = ICR1; //запоминаем значение счётчика
TCCR1B |= (1<<ICES1); //устанавливаем прерывание по нарастающему фронту импульса
PulseClocks = ((unsigned long)EdgeR - (unsigned long)EdgeF + ((unsigned long)OverflowP *65535)); // количество "тиков" в длине импульса. Один "тик" = 1/16 мкс при 16 МГц.
};
}


void main(void)
{

/** НАСТРОЙКА ТАЙМЕРА **/

TCCR1B |= (1<<ICES1) | (1<<CS10)| (1<<ICNC1);// входной фильтр, прерывание по нарастающему фронту, запуск таймера (такт 1/16 мкс при 16 МГц)
TIMSK |= (1<<TICIE1) | (1<<TOIE1);//разрешить прерывания по захвату и переполнению таймера 1

lcd_init(16);

#asm("sei")
while (1)
{
lcd_gotoxy(0,0);
sprintf(lcd_buffer_1, "Freq = %i Hz", 1000000/(FreqClocks*0.0625));
lcd_puts(lcd_buffer_1);

lcd_gotoxy(0,1);
sprintf(lcd_buffer_2, "Wdt = %i uS", PulseClocks*0.0625);
lcd_puts(lcd_buffer_2);
lcd_clear();
}
}
Однако на дисплей выводят значения от -30000 до +30000 и для частоты и для длины импульса (показания примерные).

Пробовал использовать код автора, но, что странно, он тоже не захотел работать.

Генератором импульсов у меня выступает АТтини13 с простым кодом:
Спойлерwhile (1)
{ // 33 гц
PORTB.0 = 1;
delay_ms(10);
PORTB.0 = 0;
delay_ms(20);

}
Порт на выход стоит.
Так же, пробовал тактировать кнопкой. Всё та же белеберда на дисплее...
Не могу понять, где сидит проблема...
Подскажите, пожалуйста...

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

Добавлено: Пн май 30, 2016 21:38:46
c717411
DataLife писал(а): Не могу понять, где сидит проблема...
Разбейте программу на кусочки. Получите сперва нужное значение частоты. Переменным, изменяющимся в разных прерываниях, на всякий пожарный лучше поставить модификатор volatile.

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

Добавлено: Вт май 31, 2016 10:03:56
maxn
Вопрос новичка - подскажите, вот эти библиотеки http://arduino.ru/forum/proekty/modbusr ... i-owen-plc можно заюзать в CodeVision ?
И нужен ли для них какой-то особый микроконтроллер или подойдет любой AVR типа ATMEGA328P
или можно юзать среду разработки Arduino для любых AVR ?

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

Добавлено: Вт май 31, 2016 23:07:53
prw07
Как отредактировать существующий проект через генератор кода ?
Т.е. Имеется проект. Хочу внести изменения в программе при помощи генератора проекта. Захожу в КодеВизард. Открываю .cwp файл. Вношу изменения. Теперь если сгенерировать код (Generate, Save and Exit), то в IDE будет "чистая" программа сгенерированная КодеВизардом. Мне надо, что бы был мой код с соответствующими изменениями. Если просто вставлять в свой код то что сгенерировал КодеВизард, то файлы .cwp и .prj будут без изменений.

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

Добавлено: Чт июн 09, 2016 06:21:34
BEST-83154
вот тут вписан вольтметр,амперметр,ваттметр,таймер и разложения чисел
и мне хотелось бы видеть еще и замер емкости акб в А/Ч
кто может помогите!!!

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

Добавлено: Чт июн 09, 2016 15:00:27
rxstart1
Люди нужна помощь. Впервые столкнулся с этим зверем DS18B20 в общем то опросил стандартными функциями, температуру показывает, но динамическая индикация начинает дико тупить, вместо 100гц 1-2Гц. Есль ли какой нибудь простой выход или надо самому писать опрос этого термодатчика? И это 100% из-за опроса датчика. как только отключаю функции опроса все ОК.

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

Добавлено: Чт июн 09, 2016 15:43:39
Z_h_e
Насколько мне известно, библиотека использует задержку типа delay(т.е. тупой простой МК). Я сам библиотекой для DS ни разу не пользовался. Попробуйте использовать библиотеку в основном теле программы и нырять в прерывания на короткое время, может что даст, если конечно библиотека не запрещает прерывания.
Есть интересный метод работы с 1-wire, через UART, т.е. аппаратно. Но там придется задействовать оба пина UART. Поищите, в инете полно инфы по этому поводу.

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

Добавлено: Чт июн 09, 2016 18:51:35
WiseLord
Думаю, дело в том, что динамическая развёртка реализована не на прерывании таймера (в отдельном, по сути, потоке), а тупо на задержках в основном цикле. Поэтому любое использование задержек, в том числе и библиотеки датчика, превращает динамическую задержку в тыкву.

Реализуйте развёртку на любом таймере, и проблема в принципе не возникнет.