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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

*Trigger* писал(а):P.S. Я полностью переработал в своё время библиотеку DS18B20, тоже была нехватка памяти. Ниже моя версия.

Использовал Ваш код, получилось 80,7%. Все ли верно? Инициализацию можно выкинуть наверное, ds18b20 по умолчанию включается как 12 бит

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

#include <my_ds18b20.h>
// temp. conversion time [ms] depending on the resolution
static flash int conv_delay[4]={100,200,400,800};
// valid temp. bit mask depending on the resolution
static flash unsigned bit_mask[4]={0xFFF8,0xFFFC,0xFFFE,0xFFFF};
signed int my_ds18b20_temperature()
{
unsigned char resolution;
//if (ds18b20_read_spd(addr)==0) return -9999;
resolution=(__ds18b20_scratch_pad.conf_register>>5) & 3;
//if (ds18b20_select(addr)==0) return -9999;
w1_write(0x44);
delay_ms(conv_delay[resolution]);
//if (ds18b20_read_spd(addr)==0) return -9999;
w1_init();
return ((*((int *) &__ds18b20_scratch_pad.temp_lsb) & ((int) bit_mask[resolution]))*5/8);
}

int temp=0;

    void tem(void)
    {
    temp=my_ds18b20_temperature();    // Чтение температуры
     if (temp>=0) {d1=12;  //пусто           
     };

     if (temp<0) { temp=-temp; d1=10; //минус
     };
         
     d2=temp/10;
     d3=temp%10;           
    }
       
    void main(void)
    {   
   
    w1_init();
    // ds18b20_simple_init(4);
 

    while (1)
      {   
             
           tem();
       
 
       

      }
  }
Аватара пользователя
*Trigger*
Друг Кота
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

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

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

При использовании всей библиотеки не нужно объявлять отдельно my_ds18b20_temperature(), вместо этого используется ds18b20_temperature() из библиотеки. Там код ещё меньше при определённом ONE_DS18b20.
Посмотрел даташит - да, для 12 бит инициализацию можно не использовать. Библиотека-то универсальная - иногда инициализация может потребоваться.

Вот такой код получается:

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

#include <my_ds18b20.h>

int temp=0;

    
void tem(void)
    {
    
temp=ds18b20_temperature();    // Чтение температуры 
     
if (temp>=0) {d1=12;  //пусто           
     
};

     if (
temp<0) { temp=-tempd1=10//минус
     
};
          
     
d2=temp/10;
     
d3=temp%10;            
    }
       
    
void main(void)
    {   
    
    
w1_init(); 
 
    while (
1)
      {               
           
tem();
      }
  } 
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

Если я использую стандартную функцию то не хватает места.
На данный момент пытаюсь использовать вашу библиотеку и ваш код.

В Globally #define написана строчка ONE_DS18b20
и далее

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


#include <my_ds18b20.h>


signed int my_ds18b20_temperature()
{
w1_write(0x44);
delay_ms(800);
w1_init();
return ((*((int *) &__ds18b20_scratch_pad.temp_lsb) & ((int) 0xFFFF))*5/8);
}

***

temp=my_ds18b20_temperature();



и что-то все по нулям
Аватара пользователя
*Trigger*
Друг Кота
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

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

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

:facepalm:
Не нужно при использовании моей переделанной библиотеки объявлять заново функцию my_ds18b20_temperature(), тем более неправильно (как у Вас). В моей библиотеке есть функция ds18b20_temperature(), которая при определённом ONE_DS18b20 занимает меньше места, чем стандартная (из ds18b20.lib). Называется она также, как и в стандартной библиотеке, но использовать нужно её. Библиотеку ds18b20.lib (.h) не подключать. Нужна только my_ds1820.lib (.h).
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
BEST-83154
Прорезались зубы
Сообщения: 218
Зарегистрирован: Ср дек 02, 2015 15:06:01

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

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

CodeVisionAVR 3,29 есть взломанная?
https
Родился
Сообщения: 11
Зарегистрирован: Вс окт 30, 2016 21:33:31

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

Сообщение https »

С наступившим уважаемые.
Вопрос простой.
Есть такой таймер
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

time++;

if (time==488) {#asm("wdr");time=0;seconds++;}
if (seconds==60) {seconds=0; minutes++; }
if (minutes==60) {minutes=0; hours++; }

if( minutes==60)
{
putchar('1 hours last');
}


Хочу чтобы каждый час в uart выкидывало строчку, при такой постановке кода строки дублируется очень много раз, как сделать чтобы выкидывало 1 строчку и все, прошу прощения за мою некомпетентность в таймерах.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

А причём тут некомпетентность в таймерах? Тут просто логика неправильная.

Последний участок кода (if( minutes==60)) никак не связан с предыдущими. Поэтому выводиться это будет в любом прерывании, где minutes равно 60 - независимо от секунд и часов.

Используйте вложенные условия.
Vov123
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

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

Сообщение Vov123 »

Вообще логичны ли часы где есть 60 сек, 60 мин, 24 часа ? :)))
https
Родился
Сообщения: 11
Зарегистрирован: Вс окт 30, 2016 21:33:31

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

Сообщение https »

ВОт так
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

time++;

if (time==488) {#asm("wdr");time=0;seconds++;}
if (seconds==60) {seconds=0; minutes++; }
if (minutes==60) {minutes=0; hours++; putchar('1 Hours'); }

???
Vov123
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

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

Сообщение Vov123 »

Ты, вообще, чужие сообщения читаешь или только свои? :shock:

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

static volatile b = флаг hours; 

if (time>487) {#asm("wdr");time=0;seconds++;}
if (seconds>59) {seconds=0; minutes++; }
if (minutes>59) {minutes=0; hours++;}

if(hours!=b){
putchar('1 Hours');
b = hours;
}



Упростил :lol:
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Добавлю: Вывод в UART обязательно делать не в этом прерывании, а в основном коде. Тупо потому, что он, весьма вероятно, занимает больше времени, проходит между прерываниями.
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

Коты, как красивее можно это написать?

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

     d2=temp/1000;
     d3=(temp-(1000*d2))/100; 
     d4=(temp-((100*d3)+(1000*d2)))/10;
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

d4 = (temp /= 10) % 10;
d3 = (temp /= 10) % 10;
d2 = (temp /= 10) % 10;
достаточно красиво?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

ARV писал(а):

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

d4 = (temp /= 10) % 10;
d3 = (temp /= 10) % 10;
d2 = (temp /= 10) % 10;
достаточно красиво?



Да, отлично, спасибо. В d4 десятки, d3 сотни, d2 тысячи ?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

levaclaus писал(а):В d4 десятки, d3 сотни, d2 тысячи ?
как у вас было, так и осталось.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Плюс обычно такое зацикливают. Вместо нескольких переменных - один массив:

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

uint8_t d[4];
for (i = 0; i < 4; i++) {
  d[i] = temp % 10;
  temp /= 10;
}

В итоге в массиве d[4] лежит temp поразрядно - в нулевом разряде - единицы (10⁰), в первом - десятки (10¹), во втором - сотни (10²), в третьем - тысячи (10³).

Ну и компилятор неплохо оптимизирует сочетание %10 и /10.
Аватара пользователя
roma1984
Встал на лапы
Сообщения: 129
Зарегистрирован: Вт сен 23, 2008 14:29:06
Откуда: Ukraine
Контактная информация:

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

Сообщение roma1984 »

Здраствуйте! Прошу опять помощи, мучаюсь с этим спящим режимом в attiny 44, точнее пробуждением с него при помощи вачдога или другим методом.
Программа должна сделать замер напряжения, проверить все ли в норме и уснуть, потом через секунду проснутся и так по кругу.
Никак просто не пойму как это сделать, работает пока так - завел вачдог и по нему делаю ресет каждую секунду.
Код
Спойлер#include <tiny44.h>
#include <delay.h>
#define ADC_VREF_TYPE 0x00
#define charge_on PORTB.1=1;//включить пин заряда
#define charge_off PORTB.1=0;//отключить пин заряда
#define discharge_on PORTB.0=1;//включить пин разряда
#define discharge_off PORTB.0=0;//отключить пин разряда


unsigned int read_adc(unsigned char adc_input) // функция замера напряжения
{
ADMUX=(adc_input & 0x3f) | ADC_VREF_TYPE;
delay_us(10); // задержка для стабилизации напряжения
ADCSRA|=0x40; // включаєм АЦП
while ((ADCSRA & 0x10)==0); // Ждем завершения работи АЦП
ADCSRA|=0x10;
return ADCW;
}
// глобальниє переменнниє
unsigned short int Upin1, Upin2, Upin3, Upin4, Ipin, U1, U2 ,U3, U4;
float U1_Corr,U2_Corr,U3_Corr,U4_Corr;

void main(void)
{
// локальниє переменниє
Upin1=0; Upin2=0; Upin3=0; Upin4=0; Ipin=0; U1=0; U2=0; U3=0; U4=0;


// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization Func3=In Func2=Out Func1=Out Func0=Out State3=T State2=0 State1=0 State0=0
PORTB=0x03;
DDRB=0x07;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization, ADC Clock: 125,000 kHz ,ADC Bipolar Input Mode: Off, ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On, ADC4: On, ADC5: On, ADC6: On, ADC7: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;
ADCSRB&=0x6F;

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/128k 1 секунда
// Watchdog Timer interrupt: Off
#pragma optsize-
#asm("wdr")
WDTCSR=0x1E;
WDTCSR=0x0E;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

while (1)
{
Upin1=read_adc(0);
Upin2=read_adc(1);
Upin3=read_adc(2);
Upin4=read_adc(3);
Ipin=read_adc(4);

//вычисляем напряжение на аккумуляторах
U1=Upin1*1.5*0.0048876*1000; // 1/(20/30)* 5/1023
U2=Upin2*3.35*0.0048876*1000;// 1/(20/67) * 5/1023
U3=Upin3*4.75*0.0048876*1000; // 1/(20/95) * 5/1023
U4=Upin4*7*0.0048876*1000; // 1/(20/140) * 5/1023

U1_Corr=0; //КАЛИБРОВОЧНЫЕ ЗНАЧЕНИЯ
U2_Corr=0; //ВЫЧИТАЮТСЯ ИЗ РЕЗУЛЬТАТОВ ИЗМЕРЕНИЯ
U3_Corr=0; //ПРИ ИСПОЛЬЗОВАНИИ 0.1% РЕЗИСТОРОМ МОЖНО ОСТАВИТЬ
U4_Corr=0; //РАВНЫМИ 0

//ВЫЧИСЛЕНИЕ НАПРЯЖЕНИЙ КАЖДОЙ ЯЧЕЙКИ:
//U4=U4-U3
if (U4>U3)
{
U4=U4-U3;
if (U4>U4_Corr)
U4=U4-U4_Corr;
}
else
U4=0;

//U3=U3-U2
if (U3>U2)
{
U3=U3-U2;
if (U3>U3_Corr)
U3=U3-U3_Corr;
}
else
U3=0;

//U2=U2-U1
if (U2>U1)
{
U2=U2-U1;
if (U2>U2_Corr)
U2=U2-U2_Corr;
}
else
U2=0;

if (U1>U1_Corr)
U1=U1-U1_Corr;
else
U1=0;

//защита от переразряда
if ((U1<3000)||(U2<3000)||(U3<3000)||(U4<3000))
{
discharge_off;
}
else
{
discharge_on;
}
//защита от перезаряда
if ((U1>4200)||(U2>4200)||(U3>4200)||(U4>4200))
{
charge_off;
}
if ((U1<4150)&&(U2<4150)&&(U3<4150)&&(U4<4150))
{
charge_on;
}
//защита от КЗ
// if (Ipin>4)
// {
// discharge_off;
// charge_off;
// }

MCUCR=0x30; // разрешаєм спящий режим, Power down
#asm("sleep") // засипаем
}
}


Пробовал настраивать вачдог не на ресет, а на прерывания по срабатыванию, но ничего не вышло.
Добавлял строку
// Watchdog timeout interrupt service routine
interrupt [WDT] void wdt_timeout_isr(void)
{
// Place your code here
}

И настройки вачдога с разрешениєм прериваний:
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/128k
// Watchdog Timer interrupt: On
#pragma optsize-
#asm("wdr")
WDTCSR=0x1E;
WDTCSR=0x4E;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Global enable interrupts
#asm("sei")

Как правильно реализовать? А то реально замучался пробовать медом тика! Спасибо!
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

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

Сообщение serg_svd »

Сильно не закидывайте помидорами :)
Я присоединяюсь к теме. Решил завязать с баскомом и все же учить СИ. Выбрал кодевижен из-за более простого старта и наличия библиотек для периферии.
Из книг есть:
1. Стефан Кочан "Программирование на языке С";
2. В.В. Подбельский ""Программирование на языке С";
3. Ю. А Шпак. "Программирование на языке С для AVR и PIC микроконтроллеров"
.... ну и интернет, конечно.

Что-то получается, а что-то мой мозг вообще не хочет воспринимать и понимать в этом "странном" (после Бэйсика) для меня языке.

Скачал с официального сайта ограниченную версию 3,29. Для тренировки и обучения пока хватит и ее.

Теперь самое интересное. Написал код, который, используя встроенную библиотеку для работы с ЖК индикатором, выводит текст. Вроде проблем не возникло, пока.... пока не захотел подсчитать число символов и вывести. Вот код, я урезал лишнее и оставил лишь то, что у меня не получилось реализовать.
Спойлер

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

#include <io.h>
#include <iobits.h>
#include <string.h>
#include <alcd.h>
#include <stdio.h>


char text2[10]="Test";
char i;

,,,,,,


    lcd_init(16);               // Инициализация дисплея в 16 символов в строке
    lcd_clear();                // Очистка дисплея
    lcd_gotoxy(0,0);
    i=strlen(text2);
    lcd_puts(i);



И получаю в строке lcd_puts(i); ошибку несоответствия типов переменных Error: function argument #1 of type 'unsigned char' is incompatible with required parameter of type 'unsigned char *'

Объясните чайнику, пожалуйста, отчего она возникла? Как правильно все же должен выглядеть этот кусок кода?

Насчет литературы, может подскажете еще обучалку для чайника? Только просьба на сайт 123 не отправлять.

Добавлено after 6 minutes 7 seconds:
Кстати вдогонку еще один тупой вопрос задам.
Есть строковая переменная, допустим, состоящая из 25 символов. Эти 25 символов составляют некое предложение из N слов. Если я вывожу эту переменную на ЖК индикатор 16х2, то, заполнив первую строку 16 символами, текст перейдет на вторую строчку. При этом одно слово будет разбито на 2 строки.
Подскажите, как нужно написать код, чтобы слово не разбивалось, а переносилось на другую строчку целиком? Как я понимаю, готовой функции нет в кодевижен для этого и нужно писать свой код. Правильно?
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Не знаю CodeVision, но полагаю, что функция lcd_puts() по смыслу должна принимать в качестве аргумента строку (или указатель на char, что то же самое по сути), а Вы пытаетесь ей целое число скормить зачем-то.
заполнив первую строку 16 символами, текст перейдет на вторую строчку
Вовсе нет.
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

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

Сообщение serg_svd »

WiseLord писал(а): функция lcd_puts() по смыслу должна принимать в качестве аргумента строку

Почему тогда в примерах к этой программе через нее выводят и числа? Я в этой библиотеке для ЖК индикатора не видел других функций именно для чисел. И меня смущает наличие в строчке ошибки знака указателя (*).
Помощь к программе есть, и здоровенный файл хэлпа. Но они рассчитаны на людей уже владеющих С. А с нуля по ним учиться очень трудно. Потому, что в них (да и в моих книжках тоже) почему-то не описаны фундаментальные основы языка. Надо искать преподавателя, что-то мне так кажется.

WiseLord писал(а):Вовсе нет.

Что в баскоме, что сейчас у меня в попытках обучения С, при выводе информации на жк строка переносится автоматически. Я параллельно смотрю симуляцию в протеус.

А я и заинтересовался, как можно длинную строковый массив разбить по словам самому, потому, что это пригодится мне в моем проекте.
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Ответить

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