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

Обсуждаем контроллеры компании Atmel.
BeerLover
Родился
Сообщения: 3
Зарегистрирован: Пн янв 25, 2010 20:14:52

Сообщение BeerLover »

К сожалению не проще. Во-первых маленькая поправочка, в начале _END_OF_CODE должен быть один символ подчеркивания, второй компилятор сам добавляет. А во-вторых, ну не работает так, хотя не смог понять, почему. Ну и кроме того, переменная все равно потребуется, чтоб по данным бегать.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

ARV писал(а):
BeerLover писал(а):

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

extern flash char _END_OF_CODE;
char flash *EndOfCode;
EndOfCode = &_END_OF_CODE;
имхо, тогда уж корректнее и проще так:

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

extern flash char *__END_OF_CODE;
тогда не потребуется заводить отдельную переменную-указатель для получения адреса - __END_OF_CODE уже будет равна этому адресу.
Не корректнее и не проще.
В Вашем варианте _END_OF_CODE - это просто указатель на неизвестно куда (так как он там в ассемблере не проинициаизирован и что там для данного компилятора дальше - копия DATA или уже пустая флешка - я не знаю), который "как бы лежит" там же, где в его варианте "лежит" байт _END_OF_CODE;
Написав где-либо просто _END_OF_CODE он получит "значение" этого байта, а Вы - "значение" указателя (один или два байта какого-то, с точки зрения задачи, мусора).

А нужен адрес, поэтому для обеих вариантов всё равно надо писать &_END_OF_CODE;
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

согласен, поспешил :?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

привет! чет не могу понять, подскажите!
подключаю светодиодный индикатор к atmega8, порт B.
Порт настроил на выход.

суть такая, есть три кнопки, первая-скорость(меняет цифры), вторая-стоп(останавливает, ставит к скорости точку на индикаторе).
запускаю, индикатор светится слабо зелеными, если давлю кнопку -2, то индикатор начинает светиться желтым цветом(хотя он зеленый) и проц начинает греться. почему так происходит?

Текст программы прикреплен. Посмотрите пожалуйста!!!
Вложения
1.c
(4.27 КБ) 481 скачивание
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

ssvd писал(а):Текст программы прикреплен. Посмотрите пожалуйста!!!
Не буду. Сначала схему смотреть надо. Налицо явное превышение допустимых токов как для индикатора, так и для мироконтроллера.
Или Вы думаете, что определённое сочетание команд приводит к разогреву независимо от схемы?

p.s. и, как по мне, сообщение явно не в той теме.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

avreal писал(а):
ssvd писал(а):Текст программы прикреплен. Посмотрите пожалуйста!!!
Не буду. Сначала схему смотреть надо. Налицо явное превышение допустимых токов как для индикатора, так и для мироконтроллера.
Или Вы думаете, что определённое сочетание команд приводит к разогреву независимо от схемы?

p.s. и, как по мне, сообщение явно не в той теме.


на ноги порта B подключены ноги индикатора, анод на плюс. кнопки(тактовые), подключены напрямую к ногам процессора, другими ногами на минус. вот и вся схема! какие нюансы еще рассказать?
Аватара пользователя
DiGiCat
Друг Кота
Сообщения: 4793
Зарегистрирован: Пт июл 11, 2008 09:42:35
Откуда: Made in USSR

Сообщение DiGiCat »

ssvd писал(а): подключены напрямую к ногам процессора, другими ногами на минус. вот и вся схема!
:shock: Резисторы нужно ставить токоограничительные Ом на 270, попалишь все. :) Если уже не ...
Выше сказали уже:
avreal писал(а):Налицо явное превышение допустимых токов как для индикатора, так и для мироконтроллера.

В Обучалку сходи.
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

DiGiCat писал(а):
ssvd писал(а): подключены напрямую к ногам процессора, другими ногами на минус. вот и вся схема!
:shock: Резисторы нужно ставить токоограничительные Ом на 270, попалишь все. :) Если уже не ...
Выше сказали уже:
avreal писал(а):Налицо явное превышение допустимых токов как для индикатора, так и для мироконтроллера.

В Обучалку сходи.


)))) Уже! Спасибо!
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

вот еще вопрос знатокам C.
собрал термометр на 2х светодиодных индикаторах. На них будет выводиться температура, а если будут минусовая, то буду ставить точку.

выводы индикатора подключенв к порту B, а катоды к A0, A1.
Данные будут выводиться по таймеру. А Датчики температуры(их два) будут опрашиваться в основном цикле. основной цикл получился таким:

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

    while(1){
        temp=ds18b20_temperature(&rom_codes[0][0]);//Внутренняя
        if (temp>1000){               //если датчик выдаёт больше 1000
             temp=4096-temp;            //отнимаем от данных 4096
             temp=-temp;                //и ставим знак "минус"
             minus=1;
        } minus=0;
                         
        printf("%u\xdfC",temp);
        digi_out:=temp;
        delay_ms(2000);               
    }


как правильно написать printf(), что бы он сформировал целое 2х знаковое число?
как отделить минус?
То есть мне надо получить int с обработанным числом.
Подскажите плиз!

Если я напишу так: printf("%u\xdfC",temp); то он вернет целую часть числа?
Shutilla
Открыл глаза
Сообщения: 52
Зарегистрирован: Чт июл 03, 2008 12:34:48
Откуда: Волгоград

Указатели, буть они не ладны

Сообщение Shutilla »

Мяу, уважаемые!
Есть число (float a, 4 байта), есть массив из 4х байт (unsigned char b[4]). Как поместить первое во второе, не прибегая к лишним преобразованиям, работая с памятью через указатели?

Пробовал сяк:

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

float *p;
p = &a;
b[0] = *p;
b[1] = *(p + 1);
b[2] = *(p + 2);
b[3] = *(p + 3);
Но в результате - бред. На большее знаний Си не хватило (да и компилятор ругался на касты из указателя в целое число и из float * в, например, char *. Хотя, казалось бы, какая разница, указатель он и в африке указатель, на чтобы он не указывал). Возможно ли это провернуть или нет?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

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

float *f, a = 3.1415;
unsigned char b[4];

   f = b; // наверное, (void*)b будет правильнее
   *f = a; // теперь смотрите, что в массиве
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ValBag
Потрогал лапой паяльник
Сообщения: 326
Зарегистрирован: Сб сен 06, 2008 12:56:13

Re: Указатели, буть они не ладны

Сообщение ValBag »

Shutilla писал(а):Мяу, уважаемые!
Есть число (float a, 4 байта), есть массив из 4х байт (unsigned char b[4]). Как поместить первое во второе, не прибегая к лишним преобразованиям, работая с памятью через указатели?
Т. к. указатель на тип float, то третья строчка присвоит b[0], (в соответствии с приведением типов) младший байт "а". Не знаю, что там будет (не в курсе представления формата float). После (p+1) адрес будет указывать на следующую переменную float, т. е. через 4 байта, а там неизвестно что ? И так далее.
Можно попробовать так:

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

unsigned char *p;
p=(unsigned char *) &a;             //с приведением к типу unsigned char указателя на float.
// Ну а далее с третьей строчки исходного кода.
// Или:
b[0] = *p;
b[1] = *(p++);
b[2] = *(p++);
b[3] = *(p++);
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Сообщение Chip115 »

всем привет. Проблемка возникла.
МК должен мигать светодиодом...
вот код

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

#include <tiny2313>
#include <delay>
//int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char rab;
void init (void)
{

// прерывания по совпадению таймера Т1
interrupt [TIM1_COMP] void timer1_comp_isr(void)
{
    rab=rab>>1;
    if (rab==0)
        rab=0b10000000;
    PORTB=rab;
}
CLKPR=0x80; //отключить деление частоты системного генератора
CLKPR=0x00;

TCCR1A=0x00;
TCCR1B=0x0D;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x03; // наш коэффициент деления 030CH=780
OCR1AL=0x0C;
OCR1BH=0x00;
OCR1BL=0x00;

TIMSK=0x40;

GIMSK=0x00;
MCUCR=0x00;

ACSR=0x80;

// PORT A init
DDRA=0xFF;
PORTA=0x00;

// PORT B init
DDRB=0xFF;
PORTB=0x00;

// PORT D init
DDRD=0xFF;
PORTD=0xFF;

TCCR1B=0x05;

}
void main ()
{
    init();
    rab=0b00100000;
    #asm ("sei")

    while(1){};
}

выдает ошибку
Error: G:\prog\new\2_1.c(9): 'interrupt' or '__interrupt' attributes not allowed in this context
Эт он мягко намекает на недопустимый радиус кривизны рук?
Не могу понять где ошибка.
На таймере 16-ти разрядном формирую задержку.
Использую прерывание по совпадению.
Последний раз редактировалось Chip115 Ср фев 10, 2010 09:01:52, всего редактировалось 1 раз.
Аватара пользователя
ValBag
Потрогал лапой паяльник
Сообщения: 326
Зарегистрирован: Сб сен 06, 2008 12:56:13

Сообщение ValBag »

Chip115 писал(а):всем привет. Проблемка возникла.
МК должен мигать светодиодом...
Не могу понять где ошибка.
Вектор прерывания неправильно записан: [TIM1_COMPA]
Или поставить [5]
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Сообщение Chip115 »

Не помогло:(
Такая же весчь творится:(
Аватара пользователя
ValBag
Потрогал лапой паяльник
Сообщения: 326
Зарегистрирован: Сб сен 06, 2008 12:56:13

Сообщение ValBag »

Chip115 писал(а):Не помогло:(
Такая же весчь творится:(
Поставь после tiny2313.h :))
То же самое относится и к delay.h
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

если бы вы оформляли код красиво - вы сразу бы увидели ошибку. вот смотрите: я убрал "тело" функций, оставив только фигурные скобки и расположил их "красиво". видно ошибку?

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

#include <tiny2313>
#include <delay>
//int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char rab;

void init (void)
   {
      // прерывания по совпадению таймера Т1
     
         interrupt [TIM1_COMP] void timer1_comp_isr(void)
         {
         }
   }

void main ()
   {
       init();
       rab=0b00100000;
       #asm ("sei")
 
       while(1){};
   }


и, кстати, чем мигать-то вы собрались? в программе нет ни одного обращения к портам...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Labus
Открыл глаза
Сообщения: 48
Зарегистрирован: Пн фев 01, 2010 22:48:14

Сообщение Labus »

Советую код создавать мастером и дополнять позже - тогда таких ЛЕментарных ошибок не будет. Будут только тотальные :lol:
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Сообщение Chip115 »

Спасибо большое... :)
Действительно, "кривое" оформление внесло коррективы :)
Сча все прошло без ошибки. Вечером прошью МК :)
обращение к портам добавил :) Тож как то пропустил :oops:
Аватара пользователя
ssvd
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Ср ноя 04, 2009 18:00:56
Откуда: Алтайский край
Контактная информация:

Сообщение ssvd »

вот не могу найти от чего так происходит...

есть такой код, просто выводим температуру на два индикатора, если я вывожу просто число, то отображается все нормально, а если вывожу температуру, то сначала загорается один сегмент, а потом второй...

а если так, то все нормально...:

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

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
  TCNT1H=0x8F;
  TCNT1L=0xD1;

    indication=22;
}


хотя какая разница? ведь, прерывание то пока не отработается, не запуститься другое прерывание?

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

unsigned char devices;
unsigned char rom_codes[2][9];
unsigned char temp;
char indication, digit_out[2], cur_dig=0;
unsigned int minus,dTemp;

#define digit1 PORTA.0      //катод первой цифры
#define digit2 PORTA.1      //катод второй цифры
char bCharacter[12]={
    0b00111111,//0
    0b00000110,//1
    0b01011011,//2
    0b01001111,//3
    0b01100110,//4
    0b01101101,//5
    0b01111101,//6
    0b00000111,//7
    0b01111111,//8
    0b01101111,//9
    0b00000000,//
    0b10000000 //.
};

void __init(void){
    #pragma optsize-
    CLKPR=0x80;
    CLKPR=0x00;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif

    PORTA=0x00;
    DDRA=0x07;

    PORTB=0x00;
    DDRB=0xFF;

PORTD=0x1B;
DDRD=0x00;
TCCR0A=0x00;
TCCR0B=0x02;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0x03;
TCNT1L=0xD1;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

OCR1BH=0x00;
OCR1BL=0x00;

GIMSK=0x00;
MCUCR=0x00;

TIMSK=0x82;
USICR=0x00;

ACSR=0x80;
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void){
  TCNT0=0x00;
  if(indication<100){
    digit_out[0]=indication/10;
    digit_out[1]=indication%10;
  }
  PORTB=0xFF;
  switch (cur_dig){
    case 0:{digit2=1; digit1=0; break;};
    case 1:{digit2=0; digit1=1; break;};
  }
  PORTB=bCharacter[digit_out[cur_dig]];
  cur_dig++;
  if(cur_dig==2)cur_dig=0;
}

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
  TCNT1H=0x8F;
  TCNT1L=0xD1;

    temp=ds18b20_temperature(&rom_codes[dTemp][0]);
    indication=temp;
}

void main(void){
   __init();
   #asm("cli");
   devices=w1_search(0xf0,rom_codes);
   #asm("sei");
   if (devices==0){
     while(1){
       indication=00;
     }
   }

    while(1){
    }
}

Ответить

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