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

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

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

Сообщение ARV »

MEGAORC писал(а):Подскажите как в CVAVR по SPI прочитать байт не изменяя его.
этот вопрос отношения к Си не имеет, т.к. это определяется аппаратурой и протоколом обмена вашего устройства: если режим чтения регистра без изменения его состояния предусмотрен, прочесть можно, если не предусмотрен - нельзя.

как правило, простое чтение, хоть и сопровождается "передачей левого байта (0xFF обычно)", не меняет состояние устройства. но не стану утверждать, что это ВСЕГДА так.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

MEGAORC писал(а):Подскажите как в CVAVR по SPI прочитать байт не изменяя его.
В данном случае операция чтения-запись устройства(радиомодуля) определяется битом R/W адресного байта.
В документации есть таблица регистров, там указано для какой операции какой режим доступа надо использовать.
Реклама
Аватара пользователя
EternalEngine
Грызет канифоль
Сообщения: 266
Зарегистрирован: Пн фев 02, 2009 08:19:53
Откуда: Москва
Контактная информация:

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

Сообщение EternalEngine »

Господа, как на ATTiny13A подцепить вход компаратора на ногу ADC2?

Инициализирую так, но увы.. Ткните носом, пожалуйста.

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

// Analog Comparator initialization
// Analog Comparator: On
// The Analog Comparator's positive input is
// connected to the Bandgap Voltage Reference
// The Analog Comparator's negative input is
// connected to the ADC multiplexer
ACSR=0x40;
ADCSRB=0x40;

ADMUX=0x10; // ADC2

// Digital input buffer on AIN0: Off
// Digital input buffer on AIN1: Off
DIDR0=0x00;
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Cогласно даташиту для подключения ADC2 нужно:
ACME= 1;
ADEN= 0;
MUX1..0= 10
У вас MUXы совсем не те, а параметризации ADCSRB не видно.
Docendo discimus
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

EternalEngine писал(а):Ткните носом, пожалуйста.
Пожалуйста, страница 78.
Реклама
Starmarik
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Чт июн 26, 2014 15:27:55

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

Сообщение Starmarik »

Привет всем радиолюбителям. Ребята, помогите новичку. Изучаю CVAVR. Разобрался наконец с динамической индикацией, написал код, который прекрасно работает, но...работает, пока не подключаю ds18b20. Как я понимаю, процедура чтения температуры запрещает прерывания, и индикация не работает. Прошу сильно не пинать, я понимаю, вопрос заезженный, но уже сколько перечитал, не могу понять, как заставить работать индикацию с датчиком. Под спойлером код, посмотрите, пожалуйста, подскажите, что не так, и как переделать. Индикация работает от прерывания таймера 2.
Спойлер

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

#include <mega8.h>
#include <7seg.h>
#include <ds18b20.h>

unsigned char tic=0,sec=0;
float t;
unsigned char dig_kat[10]={
//0bHGFEDCBA
  0b00111111,      // 0
  0b00000110,      // 1
  0b01011011,      // 2
  0b01001111,      // 3
  0b01100110,      // 4
  0b01101101,      // 5
  0b01111101,      // 6
  0b00000111,      // 7
  0b01111111,      // 8
  0b01101111      // 9
};

unsigned char dig_an[10]={
//0bHGFEDCBA
  0b11000000,      // 0
  0b11111001,      // 1
  0b10100100,      // 2  
  0b10110000,      // 3
  0b10011001,      // 4
  0b10010010,      // 5
  0b10000010,      // 6
  0b11111000,      // 7
  0b10000000,      // 8
  0b10010000      // 9
};  
volatile int temp;
int a,c;
#define digits dig_an

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
a++;
tic++; 
if (tic==125) //1 сек
{sec++;
if (sec==5){sec=0;}
tic=0;
}
}

void show (void){
if(temp<10){c=2;}else //гасим нули перед числом
if(temp<100){c=3;} else
if(temp<1000){c=4;}else
if(temp>1000){c=5;};
if(a==c){a=0;}
switch (a)
{
        case 4:PORTC=0x01; PORTD=digits[temp%10000/1000]; break;         //подаём питание на разряд 1
        case 3:PORTC=0x02; PORTD=digits[temp%1000/100]; break;         //подаём питание на разряд 2
        case 2:PORTC=0x04; PORTD=digits[temp%100/10]; break;         //подаём питание на разряд 3
        case 1:PORTC=0x08; PORTD=digits[temp%10]; break;  //подаём питание на разряд 4
}
}

void temper()
{

t=ds18b20_temperature(0);

}

void main(void)
{


PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x0F;

PORTD=0x00;
DDRD=0xff;


// Timer/Counter 2 initialization
ASSR=0x00;
TCCR2=0x0E;
TCNT2=0x00;
OCR2=0x7D;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;
w1_init();
ds18b20_init(0,10,40,DS18B20_12BIT_RES);
#asm("sei")

while (1)
      {
      if(sec==4){temper();} //считываем температуру каждые 4 сек
      temp=t*10; //число с плавающей точкой преобразуем в целое умножением на 10
      show();  //вызываем фнкцию индикации
    }
}

Последний раз редактировалось Starmarik Сб апр 30, 2016 09:24:58, всего редактировалось 1 раз.
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Starmarik писал(а):как заставить работать индикацию с датчиком
Отказаться от встроенных библиотек и анписать самому код работы с датчиком. Благо в сети на эту тему статей и примеров тьма тьмущая...
Starmarik
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Чт июн 26, 2014 15:27:55

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

Сообщение Starmarik »

Аlex писал(а):
Starmarik писал(а):как заставить работать индикацию с датчиком
Отказаться от встроенных библиотек и анписать самому код работы с датчиком. Благо в сети на эту тему статей и примеров тьма тьмущая...
Спасибо, буду читать дальше )) Но все равно, как мне кажется, даже если написать свой код работы с датчиком, все равно нужно будет запрещать прерывания, чтоб МК считал данные с датчика, а индикация работает по прерыванию, как разрешить? Меня как раз интересует этот момент, бьюсь над ним сколько времени, никак не могу придумать.

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

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


#include <mega8.h>
#include <ds18b20.h>
unsigned char dig_kat[10]={
//0bHGFEDCBA
  0b00111111,      // 0
  0b00000110,      // 1
  0b01011011,      // 2
  0b01001111,      // 3
  0b01100110,      // 4
  0b01101101,      // 5
  0b01111101,      // 6
  0b00000111,      // 7
  0b01111111,      // 8
  0b01101111      // 9
};

unsigned char dig_an[10]={
//0bHGFEDCBA
  0b11000000,      // 0
  0b11111001,      // 1
  0b10100100,      // 2  
  0b10110000,      // 3
  0b10011001,      // 4
  0b10010010,      // 5
  0b10000010,      // 6
  0b11111000,      // 7
  0b10000000,      // 8
  0b10010000      // 9
};  
volatile int temp;
int a,c;
#define digits dig_an
unsigned char tic=0,sec=0;
float t;

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
a++;
tic++; if (tic==125){tic=0;sec++;
if (sec==5){sec=0;}

}
}

void temper()
{
#asm("cli")
t=ds18b20_temperature(0);
#asm("sei")
}

void show (){
if(temp<10){c=2;}else
if(temp<100){c=3;}else
if(temp<1000){c=4;}else
if(temp>1000){c=5;};
if(a==c){a=0;}
switch (a)
{
        case 4:PORTC=0x01; PORTD=digits[temp%10000/1000]; break;         //подаём питание на разряд 1
        case 3:PORTC=0x02; PORTD=digits[temp%1000/100]; break;         //подаём питание на разряд 2
        case 2:PORTC=0x04; PORTD=digits[temp%100/10]; break;         //подаём питание на разряд 3
        case 1:PORTC=0x08; PORTD=digits[temp%10]; break;  //подаём питание на разряд 4
}

}

void main(void)
{
PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x0F;

PORTD=0x00;
DDRD=0xff;


// Timer/Counter 2 initialization
ASSR=0x00;
TCCR2=0x0E;
TCNT2=0x00;
OCR2=0x7D;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;
w1_init();
ds18b20_init(0,10,40,DS18B20_12BIT_RES);
#asm("sei")
while (1)
      {
     if(sec==4){temper();}
    temp=t*10;
     show();  
    }
}
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

С 1-wire можно работать через UART, только придется обе ноги задействовать.

Есть проект у меня на асме, там 1-wire программный. Экран слегка моргает, но я семисегмнетный не планировал в проект сначала. Сразу был бы заложен, то наверное не было морганий совсем. Я к чему, можно сделать и программно при желании.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Starmarik писал(а):Запретил прерывания в функции чтения температуры, индикация работает, но очень медленно = каждый символ переключается с интервалом в секунду. Что здесь не так? Код под спойлером.
Потому что ds18b20_temperature его у себя внутри запрещает.
Starmarik
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Чт июн 26, 2014 15:27:55

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

Сообщение Starmarik »

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

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

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

Starmarik писал(а):Или еще какой выход?
Аlex писал(а):Отказаться от встроенных библиотек и анписать самому код работы с датчиком.
Аватара пользователя
EternalEngine
Грызет канифоль
Сообщения: 266
Зарегистрирован: Пн фев 02, 2009 08:19:53
Откуда: Москва
Контактная информация:

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

Сообщение EternalEngine »

COKPOWEHEU писал(а):
EternalEngine писал(а):Ткните носом, пожалуйста.
Пожалуйста, страница 78.
По этой инструкции и делал. Бит 6 (ACME) в ADCRB установлен в 1, ADCRA (ниже в коде) по нулям в том числе бит ADEN. ADMUX установлен в 10, что соответствует входу 2. Что неправильно сделал?
pyzhman писал(а):Cогласно даташиту для подключения ADC2 нужно:
ACME= 1;
ADEN= 0;
MUX1..0= 10
У вас MUXы совсем не те, а параметризации ADCSRB не видно.
Спасибо! MUXы поправил, но запустить так и не получается.

__________________


Заработало! Вражеский протеус не считал нужным рассматривать вход мк как аналоговый, пока он не соединен с осциллографом. Так-то :shock: :facepalm:
MEGAORC
Родился
Сообщения: 11
Зарегистрирован: Чт фев 04, 2016 13:54:47

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

Сообщение MEGAORC »

ARV,uk8amk спасибо. Поразбирался с программными кодами SPI для похожих радио модулей, повидимому читается SPI как раз при подаче всех единиц. К тому же как я понял, для управления радиомодулем, нужно подавать 16 битные команды. А я как ни старался, через аппаратный SPI 16 бит передать не смог. В итоге нашел программный, чуть переделал, и теперь передает 16 бит.

Вопрос появился в другом, у меня в программе есть прерывание по приходу данных с UART, но после прерывания программа не возвращаться в место обрыва (while (1)), а так и идет дальше по порядку с самого начала (void main), и делает бесполезные действия. Т.е. после каждого прерывания, у меня заново происходит инициализация радиомодуля.
В чем может быть проблема? Как вернуть курсор в то место, где он прервался?
Спойлер

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

#include <mega8515.h>
#include <delay.h>
#include <stdio.h>


//  SPI  РАБОТАЕТ!!! Не забыть убрать инициализацию родного СПИ!!!
#define nIRQ PINB.2   //PIND.2 Прерывание
#define nSEL PORTB.4  //PORTB.4 SS
#define nSCK PORTB.7  //PORTB.7 SCK
#define nSDI PORTB.5  //PORTB.5 MOSI
#define nSDO PINB.6   //PINB.6  MISO


int init_UART(void)               // Инициализация ЮАРТА
{
	//	Установка скорости 
	UBRRH=0;	//	UBRR=f/(16*band)-1 f=8000000Гц band=, 
	UBRRL=3;	//	нормальный асинхронный двунаправленный режим работы
	
//			RXC			-	завершение приёма
//			|TXC		-	завершение передачи
//			||UDRE 		-	отсутствие данных для отправки
//			|||FE		-	ошибка кадра
//			||||DOR		-	ошибка переполнение буфера
//			|||||PE		-	ошибка чётности
//			||||||U2X	-	Двойная скорость
//			|||||||MPCM	-	Многопроцессорный режим
//			76543210
	UCSRA=0b00000000;

//			RXCIE		-	прерывание при приёме данных
//			|TXCIE		-	прерывание при завершение передачи
//			||UDRIE		-	прерывание отсутствие данных для отправки
//			|||RXEN		-	разрешение приёма
//			||||TXEN	-	разрешение передачи
//			|||||UCSZ2	-	UCSZ0:2 размер кадра данных
//			||||||RXB8	-	9 бит принятых данных
//			|||||||TXB8	-	9 бит переданных данных
//			76543210
	UCSRB=0b11111000;	//	разрешен приём и передача по UART

//			URSEL		-	всегда 1
//			|UMSEL		-	режим:1-синхронный 0-асинхронный
//			||UPM1		-	UPM0:1 чётность
//			|||UPM0		-	UPM0:1 чётность
//			||||USBS	-	топ биты: 0-1, 1-2
//			|||||UCSZ1	-	UCSZ0:2 размер кадра данных
//			||||||UCSZ0	-	UCSZ0:2 размер кадра данных
//			|||||||UCPOL-	в синхронном режиме - тактирование
//			76543210
	UCSRC=0b10000110;	//	8-битовая посылка
return;
}
void send_Uart(unsigned char c)//	Отправка байта через ЮАРТ
{
	while(!(UCSRA&(1<<5)))	//	Устанавливается, когда регистр свободен
	{}
	UDR = c;
}


     //SPI      РАБОТАЕТ!!!!!!!!!!!!
void SPI_WRITE(unsigned char Addr, unsigned char data)
{
unsigned char i=0;
Addr=Addr|0x00;          // старший бит в адресе дб равен 0  (Было 0х80) зачем то поставили неверно 
nSEL=0;
delay_us(10);
for (i=0; i<8; i++)
        {
        nSDI=(Addr>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        delay_us(20);
        }
for (i=0; i<8; i++)
        {
        nSDI=(data>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        delay_us(20);
        }
nSEL=1;                 // прерывание
delay_us(20);
}

unsigned char SPI_READ(unsigned char Addr)      // Чтение СПИ
{
unsigned char i=0;
unsigned char data=0;
Addr=Addr&0x7F;          // ??????? ??? ? ?????? ?? ????? ????!!!

nSEL=0;
delay_us(10);
for (i=0; i<8; i++)
        {
        nSDI=(Addr>>(7-i))&0x01;
        delay_us(10);
        nSCK=1;
        delay_us(30);
        nSCK=0;
        //delay_us(200);
        delay_us(20);
        //if (i==8) LED_OUT(255);
        }
for (i=0; i<8; i++)
        {
        nSCK=1;
        delay_us(30);
        data=data<<1;
        data|=(nSDO);
        nSCK=0;
        delay_us(20);
        }
nSEL=1;                 // ??????? ????
delay_us(20);
return data;
}

void SPI_RFM_INIT (void)              // Инициализация RFM23BP
{
SPI_WRITE(0x06, 0x00); // interrupt all disable
SPI_WRITE(0x07, 01); // to ready mode
SPI_WRITE(0x09, 0x7f); // cap = 12.5pf
SPI_WRITE(0x0a, 0x05); //clk output is 2MHz
SPI_WRITE(0x0d, 0x00); // GPIO2 for MCLK output
SPI_WRITE(0x0e, 0x00); //GPIO port use default value
SPI_WRITE(0x0f, 0x70); // NO ADC used
SPI_WRITE(0x10, 0x00); //no adc used
SPI_WRITE(0x12, 0x00); // no temperature sensor used
SPI_WRITE(0x13, 0x00); // no temperature sensor used
SPI_WRITE(0x70, 0x20); // no mancheset code, no data whiting, data rate < 30Kbps
SPI_WRITE(0x1c, 0x04); // IF filter bandwidth
SPI_WRITE(0x1d, 0x40); // AFC LOOP
SPI_WRITE(0x1e, 0x08); //AFC timing
SPI_WRITE(0x20, 0x41); //clock recovery
SPI_WRITE(0x21, 0x60); //clock recovery
SPI_WRITE(0x22, 0x27); //clock recovery
SPI_WRITE(0x23, 0x52); //clock recovery
SPI_WRITE(0x24, 0x00); //clock recovery timing
SPI_WRITE(0x25, 0x06); //clock recovery timing
SPI_WRITE(0x6e, 0x27); // Tx data rate 1
SPI_WRITE(0x6f, 0x52); // Tx data rate 0
SPI_WRITE(0x30, 0x8c); // data access control
SPI_WRITE(0x32, 0xff); // header control
SPI_WRITE(0x33, 0x42); // // header 3, 2, 1,0 used for head length, fixed packet length, synchronize word length 3, 2,
SPI_WRITE(0x34, 64); // 64 nibble = 32byte preamble
SPI_WRITE(0x35, 0x20); //0x35 need to detect 20bit preamble
SPI_WRITE(0x36, 0x2d); // synchronize word
SPI_WRITE(0x37, 0xd4);
SPI_WRITE(0x38, 0x00);
SPI_WRITE(0x39, 0x00);
SPI_WRITE(0x3a, 's'); // set tx header
SPI_WRITE(0x3b, 'o');
SPI_WRITE(0x3c, 'n');
SPI_WRITE(0x3d, 'g');
SPI_WRITE(0x3e, 1); // total tx 17 byte
SPI_WRITE(0x3f, 's'); // set rx header
SPI_WRITE(0x40, 'o');
SPI_WRITE(0x41, 'n');
SPI_WRITE(0x42, 'g');
SPI_WRITE(0x43, 0xff); // all the bit to be checked
SPI_WRITE(0x44, 0xff); // all the bit to be checked
SPI_WRITE(0x45, 0xff); // all the bit to be checked
SPI_WRITE(0x46, 0xff); // all the bit to be checked

SPI_WRITE(0x6d, 0x03); // tx power to Max
SPI_WRITE(0x79, 0x0); // no frequency hopping
SPI_WRITE(0x7a, 0x0); // no frequency hopping
SPI_WRITE(0x71, 0x23); // Gfsk, fd[8] =0, no invert for Tx/Rx data, fifo mode, txclk -->gpio
SPI_WRITE(0x72, 0x48); // frequency deviation setting to 45k = 72*625
SPI_WRITE(0x73, 0x0); // no frequency offset
SPI_WRITE(0x74, 0x0); // no frequency offset
SPI_WRITE(0x75, 0x73); // frequency set to 860MHz
SPI_WRITE(0x76, 0x00); // frequency set to 860MHz
SPI_WRITE(0x77, 0x00); // frequency set to 860MHz

SPI_WRITE(0x0C,0b00010111);     // GPIO Configuration 0.
SPI_WRITE(0x0B,0b00011000);     // GPIO Configuration 1.

SPI_WRITE(0x08, 0x03); // fifo reset
SPI_WRITE(0x08, 0x00);
}
 

void SPI_RFM_INTREAD (void)    // Разрешмет прерывание для СПИ
{
char temp;
temp = SPI_READ(0x03); //read the Interrupt Status1 register прочитать регистр состояния прерывания
temp = SPI_READ(0x04);
SPI_WRITE(0x05, 0x04); // interrupt is anable разрешить прерывание
}
 
interrupt [USART_RXC] void usart_rx_isr(void)   // Прерывание UART
{ 
char data;  
char data2;
UCSRB=0b00011000;              // запретить прерывание ЮАРТ
data=UDR;                      // записать в дату 1 байт   
delay_ms(500);                
data2=UDR;                     // запись в дату2 2 байт

delay_ms(10);
PORTC=data;                    // из даты в Порт С  
init_UART();                  // инициализация ЮАРТ
delay_ms(100);
send_Uart(data);              // отправка 1 байта
delay_ms(100);
send_Uart(data2);             // отправка 2 байта
  


SPI_WRITE(data, data2);


delay_ms(100); 
UCSRB=0b11111000;              // разрешить прерывание Юарт
}

void main(void)
{          

ACSR=0x80;

UCSRA=0x00;
UCSRB=0x90;
UCSRC=0x86;
UBRRH=0x00; 
UBRRL=3;


PORTC=0xFF;
DDRC =0xFF;     
   

DDRB.5=1;
DDRB.6=0;
DDRB.7=1;   

delay_ms(500);  

SPI_RFM_INIT();  // Инициализация RFM     


#asm("sei") 

while (1)
      {
          
PORTC=0b10000000;
delay_ms(100); 
PORTC=0b00100000;
delay_ms(100);
PORTC=0b00001000;
delay_ms(100);
PORTC=0b00000010;
delay_ms(100);
PORTC=0b00000001;  
delay_ms(100);
PORTC=0b00000100;
delay_ms(100);
PORTC=0b00010000;
delay_ms(100);
PORTC=0b01000000;
delay_ms(100); 
       };
}
ПС. Не ругайте что мигаю портами перебором, а не сдвигом... лень переделывать))
MEGAORC
Родился
Сообщения: 11
Зарегистрирован: Чт фев 04, 2016 13:54:47

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

Сообщение MEGAORC »

Оказалось в инициализации ЮАРТ Порта были включены все прерывания. Оставил только для входящего байта, и все нормально заработало.

Теперь возник новый вопрос, довольно глупый, но все же.
Нужно в байте вычислить какой бит истина а какой ложь.
К примеру если использовать порт МК, то:
x=PINB; // записать байт порта Б в переменную x
y=PINB.3; //записать бит 3 с порта Б в переменную y

А как вытащить бит из байта в другой ситуации, если только имеется переменная? Пробовал к примеру Y=X.3; ругается.
Может быть есть уже готовая команда в CVAVR? Или только сдвигом можно добиться? Обнулить все кроме нужного бита и сдвинуть его в 0 позицию?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

А так ли нужно сдвигать в нулевую позицию? Что это даст?

Если реально не нужно, а скорее всего так оно и будет, то вполне хватит y = x & (1<<3);

Ну а если критично, чтобы y было только либо 0, либо 1, то тут уже без if/else не обойтись: y =(x & (1<<3) ? 1 : 0); Ну, или так: y = (x>>3) & 1;
MEGAORC
Родился
Сообщения: 11
Зарегистрирован: Чт фев 04, 2016 13:54:47

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

Сообщение MEGAORC »

Хм.. Интересные решения.
Мне действительно критично, что бы был либо 1 либо 0. По программе мне приходит 3 байта по Юарту, и я должен эти байты раздробить на биты, и раскидать на порты мультиплексоров.
Код я написал, и он работает. Сейчас хочу оптимизировать, вот и думаю, может можно попроще написать.
В данном случае я просто использую 2 сдвига, сначала влево, выбрасывая все лишнее, а затем вправо до 0 позиции. В итоге данные нужного бита ровны либо 1 либо 0.

x=((i<<5)>>7) - Вот таким образом к примеру для 2 байта(Если с 0 считать)

Но как я понял, каждый сдвиг, это такт процессора, то бишь 12 тактов тратиться впустую. Поэтому я и предположил, может существует обычная специальная команда для этого.

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

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

Сообщение WiseLord »

Вместо сдвига до упора влево на (7-N) позиций, а потом вправо на 7 позиций, лучше сразу сдвинуть вправо на N позиций, а затем результат побитово умножить на 1 (оно же 0b00000001).

То есть, вместо

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

x=((i<<5)>>7)
использовать

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

x=(i>>2)&1
Хотя, есть мнение, что компилятор при оптимизации оба варианта сведёт к одному и тому же коду.

Или, всё же настаивая на необязательности сдвигов (скажем, 3-й принятый бит должен отразиться на пине 2 порта D):

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

if (num & (1<<3))
  PORTD |= (1<<2);
else
  PORTD &= ~(1<<2);
Аватара пользователя
ra9ust
Потрогал лапой паяльник
Сообщения: 375
Зарегистрирован: Чт июн 24, 2010 20:58:59

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

Сообщение ra9ust »

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

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

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

А зачем спрашивать ? Скинули да и всё... :dont_know:
Ответить

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