Страница 231 из 421
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пт янв 04, 2013 20:56:28
vitalik_1984
можно вообще сделать глобальную переменную и работать с ней, менять в подпрограмме оба порта, считывать тоже можно оба порта.
Просмотрел даташит на мегу8, в самом конце нашел адреса портов, но как то непонятно они записаны, например PORTB записан как 0x18 (0x38)
Это два адреса, абсолютный и относительный вся оперативная память находится в едином адресном пространстве некоторые функции типа чтения бита обращаются по относительному адресу(он занимает меньше бит при адресации) другие же полный адрес( чтение портов после возможного значения относительной адресации) это где нет числа в скобках.
Такие как PORTF в много ногих Мк.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пт янв 04, 2013 21:00:57
mr4ester
vitalik_1984 писал(а):можно вообще сделать глобальную переменную и работать с ней, менять в подпрограмме оба порта, считывать тоже можно оба порта
Можно маленький пример, не совсем понимаю как это делать, ну к примеру объявляю глобальную переменную extern volatile unsigned char Name_Port, а дальше не совсем понятно, что в нее писать?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 12:17:10
mr4ester
vitalik_1984 писал(а):
Это два адреса, абсолютный и относительный вся оперативная память находится в едином адресном пространстве некоторые функции типа чтения бита обращаются по относительному адресу(он занимает меньше бит при адресации) другие же полный адрес( чтение портов после возможного значения относительной адресации) это где нет числа в скобках.
Такие как PORTF в много ногих Мк.
не совсем понял, то есть если я хочу считать состояние пина или записать бит в регистр, мне нужно писать по относительному адресу, а если я хочу считать состояние регистра целиком или записать в него, мне нужно обращаться уже по абсолютному адресу так? а какой из них абсолютный и относительный? Тот что в скобках относительный?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 12:45:19
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 .
-------------------------------
* -- конечно, не для Гарвардской архитектуры
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:21:03
mr4ester
спасибо за объяснение
вот переписал функцию калибровки сенсоров, с указателями на порты, чтоб не мудрить с опросом отдельных пинов, решил писать и читать весь регистр портов, правда не знаю будет ли работать вот эта строка?
Код: Выделить всё
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
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:39:05
Аlex
исправленная функция, ...
Этот код у Вас заработал ?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:45:07
mr4ester
еще не проверял, разбираюсь пока с этой функцией, есть грубые ошибки, или криво написано что то?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:47:29
Аlex
есть грубые ошибки, или криво написано что то?
Я выше уже дважды писал о том, что с портами через указатель работать не получится. По этому и спросил.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:51:10
mr4ester
ну я так и подумал что вы по этому поводу интересовались.
Я просто решил попробовать так, если не получится тогда уже буду выдумывать с подпрограммами.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 15:53:40
Аlex
Не получится. Уже всё опробовано до Вас.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 16:09:37
RossiaForever
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 16:13:07
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);
}
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 17:02:40
mr4ester
Проверил в CVAVR + Proteus действительно работает, спасибо за правильный пример записи в регистр по адресу, только возник вопрос по синтаксису си,
Код: Выделить всё
unsigned char* ddrb = (unsigned char*)0x37;
volatile unsigned char* portb = (unsigned char*)0x38;
разжуйте пожалуйста эти 2 строки, не совсем понятно почему знак указателя ставиться после типа данных, а не перед переменной указателем, и это тоже не понятно (unsigned char*)0x37; объясните пожалуйста.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 17:10:46
a_skr
можете и перед переменной поставить. в данном случае ничего не изменится.
int a, *b, c; // здесь a и c - переменные типа int, b - указатель на int
int* a, b, c; // здесь все переменные - указатели
(unsigned char*)0x37 - преобразование типа из int(по умолчанию) в адрес. некоторые компиляторы пропустят и без преобразования, предупреждение выдадут. CVAVR даст ошибку.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 19:01:16
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 секции

Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 19:54:19
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 переключились не в той теме

Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 20:15:05
a_skr
позволю себе создать второе сообщение подряд, но, раз тема про CVAVR, то такое:
Код: Выделить всё
unsigned char *ptr_ddrb = &DDRB;
volatile unsigned char *ptr_portb = &PORTB;
*ptr_ddrb = 0xFF;
*ptr_portb = 0x55;
вполне работоспособно
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 20:28:12
vitalik_1984
uint8_t* ddrb = (uint8_t*)&DDRB;
Вот так работает, может и костыль
a_skr писал(а):ps. что-то мы на WinAVR переключились не в той теме
Точно
a_skr ваш тоже робит

Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 21:10:20
А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
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб янв 05, 2013 21:47:55
vitalik_1984
Работает в 2.05.3
Никто не мешает пользоваться адресом в виде числа
