реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> UART и прерывания, передает назад не все
ILYAUL
сообщение Oct 22 2010, 08:56
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Палыч @ Oct 22 2010, 11:56) *
(учите язык С).

Цитата
так в чем разница между и и или при обращении к регистрам?

Похоже и цифровую логику И и ИЛИ вспомнить не помешает


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Danis
сообщение Oct 22 2010, 16:12
Сообщение #17


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(ILYAUL @ Oct 22 2010, 12:56) *
Похоже и цифровую логику И и ИЛИ вспомнить не помешает


Конечно посмотрите таблицу истинности для И и ИЛИ. & - лог. умножение, | лог. сумма.

вот Вам Палыч писал:

PORTB|=(1<<N);

То есть эквивалентно:

PORTB = ( PORTB | (1<<N) ) ;

Предположим PORTB имеет значение 0b0000000

После лог. Или получим при N = 4:

0b00000000 | 0b00010000 = 0b00010000;

T.е установили бит 4 в регистре PORTB.


Сообщение отредактировал Danis - Oct 22 2010, 16:21


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
AnKing
сообщение Oct 23 2010, 07:27
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 2-02-08
Пользователь №: 34 686



Спасибо что разъяснили, хотя над сдвигом еще придется голову поломать
Набросал себе такой хидер для удобства, точнее украл с avrfreaks
Код
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define GETBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define BITWRITE(c,p,m) (c ? SETBIT(p,m) : CLEARBIT(p,m))

на первое время я думаю покатит, все же лучше чем сдвиги самому продумывать

А вот кольцевой буфер идею которого я нашел где-то в гугле
Правда работать не хочет... и несколько отличается от того, что мне писали здесь, вместо указателейц используется побитовая маска, идею которой я, дурак, так и не понял
В статье писали что лучше всего использовать такой буфер в размерности 256, при этом битовую маску задавать одним байтом... может кто пояснит, спасибо.
Код
#define RXBUF_SIZE    16  //размер буфера обязательно равен степени двойки!
#define RXBUF_MASK    (RXBUF_SIZE-1)
#define BLOCK_TIMEOUT 10
#define BYTE_TIMEOUT 10
#define BLOCK_SIZE 8


unsigned char rxbuf[RXBUF_SIZE];
unsigned char inrx, outrx;

unsigned char rxtimeout = 0;

unsigned char idxDiff(unsigned char idxIN, unsigned char idxOUT, unsigned char bufsize)
{
    if (idxIN >= idxOUT){
        return (idxIN - idxOUT);
        FLIPBIT(PORTB,0);
        }
    else{
        return ((bufsize - idxOUT) + idxIN);
        FLIPBIT(PORTB,1);
        }
}

//программка отслеживает прием и его таймауты, и в зависимости от приема
// сбрасывает буфер либо переключает режим работы. Подпрограмма должна
// вызываться в бесконечном цикле main.
void usartPool (void)
{
    char value;
    unsigned char rxcnt = idxDiff (inrx, outrx, RXBUF_SIZE);
    if (0 == rxcnt)
    {
        //в буфере ничего нет
        if (rxtimeout >= BLOCK_TIMEOUT)
        {
            //в буфере ничего нет давно
            //...
        }
    }
    else if (rxcnt < BLOCK_SIZE)
    {
        //в буфере что-то есть, но мало
        if (rxtimeout >= BYTE_TIMEOUT)
        {
            //прошла слишком большая пауза между байтами,
            // сбрасываем буфер приема
            outrx = inrx;
        }
    }
    else
    {
        //в буфере корректно приняты BLOCK_SIZE байт,
        // обрабатываем данные
        //...
        do{
        value = rxbuf[outrx++];
        while ( !( UCSR0A & (1<<UDRE0)) ) UDR0 = value;
        outrx &= RXBUF_MASK;
        }
        while(inrx!=outrx);
    }
}


int main (void)
{
    
USART_Init(BAUD_PRESCALE);
sei();
   for(;;) // Loop forever
   {
   usartPool();
   }  
}
ISR(USART_RX_vect)
{
   char ReceivedByte;
   ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived"
   //while ( !( UCSR0A & (1<<UDRE0)) )
   UDR0 = ReceivedByte; // Echo back the received byte back to the computer
   rxbuf[inrx++] = ReceivedByte;
   inrx &= RXBUF_MASK;
   rxtimeout = 0;
   FLIPBIT(PORTB,0);
}
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 23 2010, 08:00
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(AnKing @ Oct 23 2010, 11:27) *
... вместо указателей используется побитовая маска, идею которой я, дурак, так и не понял

Вместо указателей используются индексы (inrx, outrx). Поскольку, размер буфера равен 2 в степени N, то под индекс достаточно точно N битов. Если в переменной-индексе "отбрасывать"(обнулять) биты выше N, то значение этой переменной при наращивании на единицу будет циклически изменяться (пример для буфера длиною 256: 0,1,2,3,...,254,255,0,1,...,254,255,0,1,...). Если длина буфера 256 (т.е. 2 в степени 8), то для индексации достаточно переменной длиною ровно 8 бит (char, обычно, как раз имеет такой размер), при этом никаких "лишних" бит (корорые нужно отбрасывать/обнулять) нет - что бывает удобным.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 23 2010, 19:15
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Палыч @ Oct 23 2010, 14:00) *
Если длина буфера 256 (т.е. 2 в степени 8), то для индексации достаточно переменной длиною ровно 8 бит (char, обычно, как раз имеет такой размер), при этом никаких "лишних" бит (корорые нужно отбрасывать/обнулять) нет - что бывает удобным.
Идея использования разрядности переменных для ограничения диапазона изменения величины это очень плохая идея. Потому, что разрядность переменных архитектурно- и компиляторно-зависимая величина. В стандарте СИ разрядность переменных не определена строго. В очередной раз привожу пример: CCS от TI и МК из серии TMS320, где char 16-и битный.
Ну и добавок, отсутствие явной проверки на выход за границы диапазона отведенной памяти это источник глюков, а в ОС, например, это еще и источник появления уязвимостей.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 24 2010, 11:18
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(rezident @ Oct 23 2010, 23:15) *
Идея использования разрядности переменных для ограничения диапазона изменения величины это очень плохая идея.

Совершенно с Вами согдасен. Сказанное мной выше - "вольный перевод" на русский язык реализации циклического буфера, приведенной автором топика. В этой программе не используется разрядность переменных (если не считать того, что переменные-индексы имеют тип unsignrd char, т.е. буфер в данном случае не может содержать более 256 элементов). "Удобство" же использования буфера длиною в 256 байт в том, что при размере переменной в восемь бит транслятор, обычно, выкидывает оператор вида byte &= 0xFF при оптимизации, сокращая расходы на организацию цикличности.
Go to the top of the page
 
+Quote Post
Danis
сообщение Oct 24 2010, 18:06
Сообщение #22


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(DpInRock @ Oct 21 2010, 20:24) *
То, что вы пишите даже в мусорное ведро не залезет.


DpInRock Вы, ЧТО НАКОНЕЦ Си ВЫУЧИЛИ?


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 21:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.0141 секунд с 7
ELECTRONIX ©2004-2016