WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

FreshMan писал(а):в одной из статей нашол

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

PIND&(1<<PD5)

это аналог вышеприведенной команды ?

Еще раз.....

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

PIND&(1<<PD5)
Это не управление портом, это проверка линии порта,
например можно использовать так:

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

IF (PIND & (1<<PD5))
    ветка программы, если на линии порта 1;
ELSE
    ветка программы, если на линии порта 0;
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

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

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

Сообщение vitalik_1984 »

shads писал(а):Вывод в пин будет писаться так:

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

PIND |= (1<<PIND5) 
И кстати это нормально, такая команда инвертирует соответствующий вывод порта.

может и инвертирует, только не на всех контроллерах.

FreshMan, советую почитать про битовые операции, тогда вам станет понятно что эти магические значки означают.
Еще есть книга Кернегана и Ричи основателей языка си.Там тоже неплохо описано значение операторов.
juzik
Встал на лапы
Сообщения: 128
Зарегистрирован: Пт сен 23, 2011 23:49:20
Откуда: Симферополь, Украина

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

Сообщение juzik »

Как логическое ИЛИ (а =| как раз и есть логическое или) может инвертировать значение бита?
Таблица истинности:
x | y |
----------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 1

И это не вывод в пин, а явная его установка в состояние "1". Сброс пина будет выглядеть так:
PIND &= ~(1<<PIND5)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

juzik писал(а):Как логическое ИЛИ (а =| как раз и есть логическое или) может инвертировать значение бита?

Может...
vitalik_1984 писал(а):инвертирует, только не на всех контроллерах.

Это фича некоторых Мег...
"Я не даю готовых решений, я заставляю думать!"(С)
juzik
Встал на лапы
Сообщения: 128
Зарегистрирован: Пт сен 23, 2011 23:49:20
Откуда: Симферополь, Украина

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

Сообщение juzik »

Конкретнее, пожалуйста. Поведение WinAVR'а будет независимое в данном случае от типа камня. Значит разница должна быть в апаратной реализации инструкции ORI. А эта инструкция есть часть RISC архитектуры, которая применяется (вроде) во всех мегах. Так как тогда одна и таже инструкция может по разному работать на разных камнях?
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

Очередное открытие Америки...
http://electronix.ru/forum/index.php?showtopic=107032
"Я не даю готовых решений, я заставляю думать!"(С)
juzik
Встал на лапы
Сообщения: 128
Зарегистрирован: Пт сен 23, 2011 23:49:20
Откуда: Симферополь, Украина

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

Сообщение juzik »

Интересная инфа, спасибо!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

нужно подключить DS1307 к Atmega8
я так понимаю для данных целей задействуется аппаратный TWI
скиньте, пожалуйста, кусок кода где это описано.
Tell Me The Truth
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

juzik писал(а):Как логическое ИЛИ (а =| как раз и есть логическое или) может инвертировать значение бита?

Дело не в том, что логическое или может инвертировать, а в том, что запись логического 1 в PINxy приводит к инверсии PORTxy в некоторых типах Мк.
HHIMERA писал(а):
Это фича некоторых Мег...

Не только по некоторым данным еще в Tiny2313 есть.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

FreshMan писал(а):нужно подключить DS1307 к Atmega8
я так понимаю для данных целей задействуется аппаратный TWI

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

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

#define NOINLINE     __attribute__((__noinline__))

#define IICDDR        DDRC                        /*порт управления I2C*/
#define IICPORT        PORTC                        /*порт вывода данных на линию I2C*/
#define IICPIN        PINC                        /*порт ввода данных с линий I2C*/
#define IICData        (1<<4)                        /*линия DATA*/
#define IICClc        (1<<5)                        /*линия CLC*/

char ClockData [7] = {};//массив данных часов: секунды, минуты, часы, день, дата, месяц, год


//#######################################################################################################################
//#
//#    ФУНКЦИИ РАБОТЫ С ЧАСАМИ DS1307
//#
//#######################################################################################################################

//ФУНКЦИЯ ЧТЕНИЯ БЛОКА ДАННЫХ ИЗ МИКРОСХЕМЫ ЧАСОВ DS1307
//чтение происходит в глобальный массив ClockData[7]
//последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год
void IICClockReadData (void)
{
    IICStart();
    IICByteWrite (0xD0);                        //запись данных в DS1307
    IICByteWrite (0x00);                        //сбросить указатель адреса DS1307 на 0 
    IICStop();

    IICStart();
    IICByteWrite (0xD1);                        //команда на чтение данных

    char* pClockData = &ClockData[0];            //указатель на данные часов
    for (char i = 0; i<6; i++)
        *pClockData++ = IICByteRead (0);        //пишем, секунды, минуты, часы, день, дата, месяц (с выдачей подтверждением)
    *pClockData = IICByteRead (1);                //пишем год (без подтверждения)
    IICStop(); 
}


//ФУНКЦИЯ ЗАПИСИ БЛОКА ДАННЫХ В МИКРОСХЕМУ ЧАСОВ DS1307
//запись происходит из глобального массив ClockData[7]
//последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год
void IICClockWriteData (void)
{
    IICStart();
    IICByteWrite (0xD0);                    //запись данных в DS1307
    IICByteWrite (0x00);                    //сбросить указатель адреса DS1307 на 0 

    IICByteWrite (0);                        //записать секунды
    IICByteWrite (ClockData [1]);            //минуты
    IICByteWrite (ClockData [2]);            //часы
    IICByteWrite (ClockData [3]);            //день
    IICByteWrite (ClockData [4]);            //дата 
    IICByteWrite (ClockData [5]);            //месяц
    IICByteWrite (ClockData [6]);            //год
    IICStop();
}


//#######################################################################################################################
//#
//# ФУНКЦИИ ОБСЛУЖИВАНИЯ ИНТЕРФЕЙСА I2C (софтовый вариант)
//#
//#######################################################################################################################

//задержка 2 микросекунды для формированя временных задержек IIC
NOINLINE void Delay2Mks (void)
{
    _delay_us (2);
}


//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ START ПО ИНТЕРФЕЙСУ IIC
void IICStart (void)
{
    IICDDR &= ~(IICData | IICClc);                //единички на обеих линиях
    Delay2Mks();

    IICDDR |= IICData;                            //подтяжка data к нулю
    Delay2Mks();

    IICDDR |= IICClc;                            //подтяжка clc к нулю
    Delay2Mks();            
}


//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ STOP ПО ИНТЕРФЕЙСУ IIC
void IICStop (void)
{
    IICDDR |= (IICData | IICClc);                //подтяжка обеих линий к нулю
    Delay2Mks();

    IICDDR &= ~IICClc;                            //отпустить data
    Delay2Mks();

    IICDDR &= ~IICData;                            //отпустить clc
    Delay2Mks();            
}


//ФУНКЦИЯ ЗАПИСИ БАЙТА ПО ИНТЕРФЕЙСУ IIC
//АРГУМЕНТ - байт данных для вывода по IIC
//ЗНАЧЕНИЕ - флаг подтверждения 0 (есть подтверждение) или 1 (нет подтверждения) 
char IICByteWrite (char byte)
{
    for (char i = 0; i<8; i++)
        byte = IICBit (byte);

    byte = 0x80;                                
    return IICBit 
(byte);                        //возвращаем бит подтверждения (0-есть бит подтверждения, 1-нет)
}


//ФУНКЦИЯ ЧТЕНИЯ БАЙТА ПО ИНТЕРФЕЙСУ IIC
//АРГУМЕНТ - значение бита подтверждения (0 - есть подтверждение, 1 - нет подтверждения)
//ЗНАЧЕНИЕ - принятый байт
char IICByteRead (char bit)
{
    char byte = 0xFF;
    for (char i = 0; i<8; i++)
        byte = IICBit (byte);

    bit <<= 7;
    IICBit (bit);                                //передать значение бита подтверждения
    return byte;                                //возвращаем принятый байт
}


//ФУНКЦИЯ ЗАПИСИ\ЧТЕНИЯ БИТА ПО ИНТЕРФЕЙСУ IIC
//выводится значение старшего бита аргумента
//принятый бит возвращается в младшем бите предварительно сдвинутого влево аргумента
char IICBit (char byte)                        
{
    if (byte & 0x80)                        //выводимый бит
        IICDDR &= ~IICData;                 //вывод 1 на линию данных
    else 
        IICDDR 
|= IICData;                    //вывод 0 на линию данных
    Delay2Mks();

    IICDDR &= ~IICClc;                        //старт строб импульса
    while (! (IICPIN & IICClc)){}            //ожидание формирования строба
    Delay2Mks();

    char temp;    
    if 
(IICPIN & IICData)                    //принимаем бит
        temp = 1;
    else
        temp 
= 0;
    IICDDR |= IICClc;                        //завершить строб

    byte <<= 1;
    byte |= temp;
    return byte;
}


//#######################################################################################################################
//#
//# end
//#
//#######################################################################################################################
 
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

shads писал(а):А я чет не смог дать ума аппаратному TWI, ну работало вроде, но иногда висло, лень было разбираться, легче оказалось свою программную реализацию написать.....

В 90% случаев - правильное решение...
"Я не даю готовых решений, я заставляю думать!"(С)
harrd
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Ср апр 01, 2009 17:52:51

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

Сообщение harrd »

Здравствуйте, уважаемые форумчане. Прошу вашей помощи. Есть программка на C, переписанная для Attiny2313, изначально предназначенная для pic16f84. Это светодиодная моргалка. Программа рассчитана на тактирование контроллера с частотой 37Кгц, на тиньке с частотой 4Мгц она работает слишком быстро, мигание светодиодов не различить. Подскажите, как её переделать, чтобы она нормально работала на 4Мгц

#include <avr/io.h>

void effect(unsigned int, unsigned char, unsigned char, unsigned char);
void pause (unsigned int);
void main (void)
{
unsigned int time, i, j;
DDRB = 0xff;
PORTB=0xFF;
pause(900000);
PORTB=0x00;


for(;;)
{effect(80,32,0b00000000,0b00000001);
effect(80,32,0b10000000,0b00000000);
effect(80,32,0b10000000,0b00000001);
effect(80,32,0b11000000,0b00000011);
effect(80,42,0b10101010,0b00000000);
effect(80,32,0b00000000,0b01010101);
effect(80,42,0b10100000,0b00000101);

effect(80,42,0b11111111,0b00000000);
effect(80,22,0b00000000,0b00000000);
time=410;
for(i=0;i<100;i++)
{
effect(time,8,0b10000000,0b00000000);
time=time-4;
}
time=410;
for(i=0;i<100;i++)
{
effect(time,8,0b00000000,0b00000001);
time=time-4; }
time=40;
for(i=0;i<100;i++)
{
effect(time,8,0b10001000,0b00000000);
time=time+40; }
time=40;
for(i=0;i<100;i++)
{
effect(time,8,0b00000000,0b00010001);
time=time+4; }
time=410;
for (j=0; j<2; j++)
{for(i=0;i<100;i++)
{effect(time,8,0b10000000,0b00000001);
time=time-4;}
for(i=0;i<100;i++)
{effect(time,8,0b10000000,0b00000001);
time=time+4;}}
effect(80,60,0b10101010,0b10101010);
effect(80,60,0b11111111,0b00000000);
effect(80,22,0b00000000,0b00000000);}
}


void init(void)
{
DDRB=0xFF;
PORTB=0x00;}


void pause(unsigned int time)
{
while (time-->0);}

void effect(unsigned int time,
unsigned char N,
unsigned char Field1,
unsigned char Field2)
{
unsigned char i;
for (i=0;i<N;i++)
{PORTB=Field1|Field2;
pause(time);
Field1=Field1>>1;
if ( Field1 & 256 ) Field1=Field1|0x80;
Field2=Field2<<1;
if (Field2 & 256 ) Field2=Field2|0x01;}}
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

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

Сообщение yaotzin »

harrd

измени
void pause(unsigned int time)
{
while (time-->0);}


на

void pause(unsigned int time)
{
_delay_ms(time*2);
}

и добавь
#include <util/delay.h>


если задержки не хватает то time*3 и т.далее
harrd
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Ср апр 01, 2009 17:52:51

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

Сообщение harrd »

yaotzin, большое спасибо! Сейчас всё отлично работает, поставил _delay_ms(time*1);. Пришлось отключить оптимизацию в настройках компилятора gcc в Atmel Studio, hex файл получился 4.86Кб, я думал не зашьётся в тиньку 2313, но всё прекрасно прошилось
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

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

Сообщение yaotzin »

harrd Д там еще pause(900000); надо убрать или уменьшить до максимального значения входящего в функцию delay.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

при написании обработчика прерываний мы пишем следующее:

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

ISR (TIMER0_OVF_vect)
{
...
}

как расшифровать ISR ?
Tell Me The Truth
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Еще бы понять для чего вам это нужно...
Может Interrupt Service Routine?
Аватара пользователя
sergeys
Поставщик валерьянки для Кота
Сообщения: 1946
Зарегистрирован: Сб сен 11, 2010 13:45:01
Откуда: Екатеринбург

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

Сообщение sergeys »

Привет всем! Пишу программу на Си для Тини2313. Это моя первая программа для АВР на Си. AVRStudio4+WinAVR.
Вообщем-то при компиляции вылазят только warning'и, warning конечно не error, но я все-равно и хочу от них избавиться.
Вот код (ну не все конечно, а только тот в чем проблема):

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

#include <avr/io.h>

unsigned char sec; //Объявление переменной

unsigned char hextobcd(sec) //Функция, вот sec в скобках правильно указано?
//Не надо ведь писать unsigned char  sec? sec ведь это глобальная переменная
{
sec++;
return;
}
 
int main(void)
{
hextobcd(sec);
while(1);
}


Значит warning такой: type of 'sec' defaults to 'int'. Это он предлагает поменять тип переменной sec на int? Зачем? Зачем сжирать в двое больше оперативки?
Ко мне можно на "ты", так даже лучше!
Ответить

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