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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

Ок.
Вложения
clock arduino 16.c
(9.73 КБ) 326 скачиваний
Реклама
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение 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 режимов по кругу.
Реклама
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение 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]++;
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

Согласен что с нулевым битом мне тоже запись непонятна,хотя и работает,кто то подсказал так сделать, а вот ваш вариант с двоичным представлением порта конечно понятнее,буду знать. А комментарии кол генератора пока не стал убирать,а касаемо регистров таймеров и прочего то в самом начале изучения так и делал расписывая на бумаге регистр и вручную выставлял каждый бит согласно даташиту. С генератором кода однако удобнее да и значения не особо отличаются и мне так проще. Отступы и прочее я необрашал внимания,пока экспериментирую.ацп совсем бегло прочитал особо не вдаваясь поэтому написал пока так лишь бы работало. Еще месяц назад и понятия не имел как устроен контроллер и тем более что то написать на него.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

А вот насчет того что функция ацп сама может возвращать, можете примерно написать как оно должно быть применительно к моему варианту?
Реклама
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение 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;
Реклама
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

Так а я не использовал плавающую точку, выводятся только целые значения от 00 до 99.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

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

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

Сообщение WiseLord »

А 0.389 о это что, про-вашему, если не число с плавающей точкой? Вы представляете, насколько медленно и ресурсоёмко это на 8бит контроллере?
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

Ну, ладно, мне например несложно искать и исправлять, все-таки каждому свое, а дробное число просто подогнал чтобы под 99 уместить,ну да ладно.Всё это эксперименты...
c717411
Встал на лапы
Сообщения: 148
Зарегистрирован: Ср дек 29, 2010 21:19:03

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

Сообщение c717411 »

CV 3.12

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

lcd_gotoxy(0,0);
lcd_puts(s); 
lcd_gotoxy(0,1);
lcd_puts(s);
простой код, выводит на LCD крякозябры в первой строке, вторая пустая. Если закомментировать первый gotoxy - выводит как надо первую строку, вторую пустую. Как починить?
Аватара пользователя
*Trigger*
Друг Кота
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

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

Сообщение *Trigger* »

Для начала - показать весь код. Откуда мы знаем, что там у Вас в строке s и как инициализирован дисплей?
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение 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);

}
Порт на выход стоит.
Так же, пробовал тактировать кнопкой. Всё та же белеберда на дисплее...
Не могу понять, где сидит проблема...
Подскажите, пожалуйста...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
c717411
Встал на лапы
Сообщения: 148
Зарегистрирован: Ср дек 29, 2010 21:19:03

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

Сообщение c717411 »

DataLife писал(а): Не могу понять, где сидит проблема...
Разбейте программу на кусочки. Получите сперва нужное значение частоты. Переменным, изменяющимся в разных прерываниях, на всякий пожарный лучше поставить модификатор volatile.
maxn
Встал на лапы
Сообщения: 88
Зарегистрирован: Чт мар 27, 2008 12:05:14

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

Сообщение maxn »

Вопрос новичка - подскажите, вот эти библиотеки http://arduino.ru/forum/proekty/modbusr ... i-owen-plc можно заюзать в CodeVision ?
И нужен ли для них какой-то особый микроконтроллер или подойдет любой AVR типа ATMEGA328P
или можно юзать среду разработки Arduino для любых AVR ?
prw07
Мучитель микросхем
Сообщения: 403
Зарегистрирован: Ср янв 26, 2011 17:00:30

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

Сообщение prw07 »

Как отредактировать существующий проект через генератор кода ?
Т.е. Имеется проект. Хочу внести изменения в программе при помощи генератора проекта. Захожу в КодеВизард. Открываю .cwp файл. Вношу изменения. Теперь если сгенерировать код (Generate, Save and Exit), то в IDE будет "чистая" программа сгенерированная КодеВизардом. Мне надо, что бы был мой код с соответствующими изменениями. Если просто вставлять в свой код то что сгенерировал КодеВизард, то файлы .cwp и .prj будут без изменений.
BEST-83154
Прорезались зубы
Сообщения: 218
Зарегистрирован: Ср дек 02, 2015 15:06:01

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

Сообщение BEST-83154 »

вот тут вписан вольтметр,амперметр,ваттметр,таймер и разложения чисел
и мне хотелось бы видеть еще и замер емкости акб в А/Ч
кто может помогите!!!
Вложения
45.c
(5.22 КБ) 363 скачивания
Аватара пользователя
rxstart1
Вымогатель припоя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

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

Сообщение rxstart1 »

Люди нужна помощь. Впервые столкнулся с этим зверем DS18B20 в общем то опросил стандартными функциями, температуру показывает, но динамическая индикация начинает дико тупить, вместо 100гц 1-2Гц. Есль ли какой нибудь простой выход или надо самому писать опрос этого термодатчика? И это 100% из-за опроса датчика. как только отключаю функции опроса все ОК.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

Насколько мне известно, библиотека использует задержку типа delay(т.е. тупой простой МК). Я сам библиотекой для DS ни разу не пользовался. Попробуйте использовать библиотеку в основном теле программы и нырять в прерывания на короткое время, может что даст, если конечно библиотека не запрещает прерывания.
Есть интересный метод работы с 1-wire, через UART, т.е. аппаратно. Но там придется задействовать оба пина UART. Поищите, в инете полно инфы по этому поводу.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

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

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

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