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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

можно вообще сделать глобальную переменную и работать с ней, менять в подпрограмме оба порта, считывать тоже можно оба порта.
Просмотрел даташит на мегу8, в самом конце нашел адреса портов, но как то непонятно они записаны, например PORTB записан как 0x18 (0x38)

Это два адреса, абсолютный и относительный вся оперативная память находится в едином адресном пространстве некоторые функции типа чтения бита обращаются по относительному адресу(он занимает меньше бит при адресации) другие же полный адрес( чтение портов после возможного значения относительной адресации) это где нет числа в скобках.
Такие как PORTF в много ногих Мк.
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

vitalik_1984 писал(а):можно вообще сделать глобальную переменную и работать с ней, менять в подпрограмме оба порта, считывать тоже можно оба порта

Можно маленький пример, не совсем понимаю как это делать, ну к примеру объявляю глобальную переменную extern volatile unsigned char Name_Port, а дальше не совсем понятно, что в нее писать?
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

vitalik_1984 писал(а):Это два адреса, абсолютный и относительный вся оперативная память находится в едином адресном пространстве некоторые функции типа чтения бита обращаются по относительному адресу(он занимает меньше бит при адресации) другие же полный адрес( чтение портов после возможного значения относительной адресации) это где нет числа в скобках.
Такие как PORTF в много ногих Мк.

не совсем понял, то есть если я хочу считать состояние пина или записать бит в регистр, мне нужно писать по относительному адресу, а если я хочу считать состояние регистра целиком или записать в него, мне нужно обращаться уже по абсолютному адресу так? а какой из них абсолютный и относительный? Тот что в скобках относительный?
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Тут немножко вольное обращение с терминологией привело к недопониманию. "Относительный адрес" - это вольная интерпретация автора объяснения. Есть номер регистра в области ввода-вывода ( конечно, можно назвать его и "относительным", но это понятие многозначно : относительно указателя, отнсительно счетчика команд * ) -- и есть его абсолютный адрес в общем пространстве [ РОН - I/O - память ] .

Так что целиком обращение к регистру В/В можно и так, и так
clr r16 ; Clear r16
out $18,r16 ; Write zeros to Port B
sts $38,r16 ; It is the same

а битовые операции операции с РОН и I/O предусмотрены только для этих областей, поэтому
работать с битами регистра I/O можно только по типу : sbi $1C,0 ; Set read bit in EECR

Кстати, у более новых МК Атмела для новых устройств нехватило адресов в области I/O, и они расположились в резервной области, и там уж только lds/sts и уж конечно, никаких sbi/cbi .

----------

* -- конечно, не для Гарвардской архитектуры
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

спасибо за объяснение :beer:
вот переписал функцию калибровки сенсоров, с указателями на порты, чтоб не мудрить с опросом отдельных пинов, решил писать и читать весь регистр портов, правда не знаю будет ли работать вот эта строка?

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

while((*Pin_X & i)==0); // жду пока не появится 1 на пине порта

исправленная функция, так как си я учу всего несколько недель, поэтому хотелось бы услышать конструктивную критику по коду.

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

// объявляю указатели портов
volatile char *Potr_X;
volatile char *Ddr_X;
volatile char *Pin_X;

// константы адресов портов
const char PortD_Addr = 0x12;
const char PortB_Addr = 0x18;
const char PinD_Addr = 0x10;
const char PinB_Addr = 0x16;
const char DdrD_Addr = 0x11;
const char DdrB_Addr = 0x17;

void Calibrate()  //Калибруем все сенсоры по очереди
{
unsigned char i=1,k=0;
Ddr_X = DdrD_Addr; // присваиваю указателю адрес порта D
Pin_X = PinD_Addr;

    while(i!=0)
    {
        TCNT1=0x0000;   // обнуляем счетный регистр
        TCCR1B=0x01; // разрешаю счет таймера1
        *Ddr_X &= ~i;// настраиваем пин порта на вход
        while((*Pin_X & i)==0); // жду пока не появится 1 на пине порта
        TCCR1B=0x00; //останавливаю таймер
        *Ddr_X |=i;  // конфигурирую пин на выход состояние Hi-Z
        SensorTimes[k]=TCNT1; // присваиваю время зарядки сенсора
        SensorHI[k]=SensorTimes[k]+70; //задаю верхний предел
        SensorLO[k]=SensorTimes[k]+20; // и нижний
        k++;                           // увеличиваю переменную на 1
        i<<=1;                         //сдвигаю 1 влево
        if (*Pin_X == 0x80)
        {
          i = 0x01;
          Ddr_X = DdrB_Addr;
          Pin_X = PinB_Addr;
        }
           if (k = 0x0d) // если к = 13 значит все 12 сенсоров откалиброванны, на порту B всего
           {
             i = 0x00;  // 4 сенсора, обнуляю чтоб выйти из цикла.
           }
    }
}


Еще такой вопрос, можно ли чтоб не создавать константы адресов, присваивать адрес порта таким образом

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

Ddr_X = &DDRD //  присвоить адрес регистра ddrd указателю Ddr_X 
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

исправленная функция, ...
Этот код у Вас заработал ?
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

еще не проверял, разбираюсь пока с этой функцией, есть грубые ошибки, или криво написано что то?
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

есть грубые ошибки, или криво написано что то?
Я выше уже дважды писал о том, что с портами через указатель работать не получится. По этому и спросил.
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

ну я так и подумал что вы по этому поводу интересовались.
Я просто решил попробовать так, если не получится тогда уже буду выдумывать с подпрограммами.
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Не получится. Уже всё опробовано до Вас.
RossiaForever
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вс июл 29, 2012 19:09:48

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

Сообщение RossiaForever »

Помогите плиз viewtopic.php?f=1&t=82982
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение a_skr »

Аlex писал(а):Не получится. Уже всё опробовано до Вас.
а почему? у меня получилось ;)
для WinAVR:

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

#include <avr/io.h>
#include <avr/delay.h>

int main(void)
{
  uint8_t* ddrb = (uint8_t*)0x37;
  volatile uint8_t* portb = (uint8_t*)0x38;
 
  *ddrb = 0xFF;
 
  while(1)
  {
    *portb = 0xFF;
    _delay_ms(500);
    *portb = 0;
    _delay_ms(500);
  }
}

для CVAVR:

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

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

void main(void)
{
  unsigned char* ddrb = (unsigned char*)0x37;
  volatile unsigned char* portb = (unsigned char*)0x38;
 
  *ddrb = 0xFF;
 
  while(1)
  {
    *portb = 0xFF;
    delay_ms(500);
    *portb = 0;
    delay_ms(500);
  }
}
Аватара пользователя
mr4ester
Держит паяльник хвостом
Сообщения: 900
Зарегистрирован: Чт авг 27, 2009 20:09:01
Откуда: Приднестровье г.Бендеры
Контактная информация:

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

Сообщение mr4ester »

Проверил в CVAVR + Proteus действительно работает, спасибо за правильный пример записи в регистр по адресу, только возник вопрос по синтаксису си,

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

unsigned char* ddrb = (unsigned char*)0x37;
  volatile unsigned char* portb = (unsigned char*)0x38;
 
разжуйте пожалуйста эти 2 строки, не совсем понятно почему знак указателя ставиться после типа данных, а не перед переменной указателем, и это тоже не понятно (unsigned char*)0x37; объясните пожалуйста.
Работа избавляет нас от трех великих зол: скуки, порока, нужды. (Вольтер)
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение a_skr »

можете и перед переменной поставить. в данном случае ничего не изменится.
int a, *b, c; // здесь a и c - переменные типа int, b - указатель на int
int* a, b, c; // здесь все переменные - указатели

(unsigned char*)0x37 - преобразование типа из int(по умолчанию) в адрес. некоторые компиляторы пропустят и без преобразования, предупреждение выдадут. CVAVR даст ошибку.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

a_skr,Молодчик только я бы немного по другому оформил

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

#include <avr/io.h>
#include <avr/delay.h>

int main(void)
{
  uint8_t* ptr_ddrb = (uint8_t*)&DDRB; //Тут чтобы не забивать голову константами адресов
  volatile uint8_t* ptr_portb = (uint8_t*)&PORTB;//И ptr_, чтобы было понятно, что это указатель
  
  
*ptr_ddrb = 0xFF;
}
 

Кстати в файле sfr_defs.h Вот что прописано

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

iomx8.h
#define PORTB   _SFR_IO8 (0x05)
sfr_defs.h
#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
   sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#  if __AVR_ARCH__ >= 100
#    define __SFR_OFFSET 0x00
#  else
#    define __SFR_OFFSET 0x20
#  endif
#endif
#if _SFR_ASM_COMPAT
   #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#else  /* !_SFR_ASM_COMPAT */
   #define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#endif /* !_SFR_ASM_COMPAT */
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))<<< Вот аналогичное объявление :)
 

Обращение к регистрам производится через абсолютный адрес.
Jack_A писал(а):Тут немножко вольное обращение с терминологией привело к недопониманию. "Относительный адрес" - это вольная интерпретация автора объяснения. Есть номер регистра в области ввода-вывода ( конечно, можно назвать его и "относительным", но это понятие многозначно : относительно указателя, отнсительно счетчика команд * ) -- и есть его абсолютный адрес в общем пространстве [ РОН - I/O - память ] .

Простите запамятовал, сейчас посмотрел еще раз- в скобках абсолютный, то есть нумерация начинается после РОН 32,33, и тд.
Под относительным имел ввиду тот, что без скобок те начинается с нуля относительно последнего РОН нумерация ну или относительно начала I/O секции :dont_know:
Последний раз редактировалось vitalik_1984 Сб янв 05, 2013 20:22:44, всего редактировалось 1 раз.
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение a_skr »

не будет работать.
DDRB - уже есть доступ по адресу, а не определение адреса
в sfr_defs.h:
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

ps. что-то мы на WinAVR переключились не в той теме ;)
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

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

Сообщение a_skr »

позволю себе создать второе сообщение подряд, но, раз тема про CVAVR, то такое:

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

  unsigned char *ptr_ddrb = &DDRB;
  volatile unsigned char *ptr_portb = &PORTB;
  *ptr_ddrb = 0xFF;
  *ptr_portb = 0x55;
вполне работоспособно
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

uint8_t* ddrb = (uint8_t*)&DDRB;

Вот так работает, может и костыль
a_skr писал(а):ps. что-то мы на WinAVR переключились не в той теме

Точно :oops:
a_skr ваш тоже робит :beer:
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

a_skr писал(а):позволю себе создать второе сообщение подряд, но, раз тема про CVAVR, то такое:

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

  
unsigned char *ptr_ddrb = &DDRB;
volatile unsigned char *ptr_portb = &PORTB;
вполне работоспособно

Error: ...............\main.c(53): operand type 'sfrb' is incompatible with the '&' operator
Error: ...............\main.c(54): operand type 'sfrb' is incompatible with the '&' operator

CVAVR v. 2.03.4
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Работает в 2.05.3
Никто не мешает пользоваться адресом в виде числа :)
Ответить

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