|
UART и прерывания, передает назад не все |
|
|
|
Oct 22 2010, 08:56
|

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

|
Цитата(Палыч @ Oct 22 2010, 11:56)  (учите язык С). Цитата так в чем разница между и и или при обращении к регистрам? Похоже и цифровую логику И и ИЛИ вспомнить не помешает
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Oct 22 2010, 16:12
|

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
|
|
|
|
|
Oct 23 2010, 07:27
|
Участник

Группа: Участник
Сообщений: 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); }
|
|
|
|
|
Oct 23 2010, 08:00
|

Гуру
     
Группа: Свой
Сообщений: 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, обычно, как раз имеет такой размер), при этом никаких "лишних" бит (корорые нужно отбрасывать/обнулять) нет - что бывает удобным.
|
|
|
|
|
Oct 23 2010, 19:15
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Палыч @ Oct 23 2010, 14:00)  Если длина буфера 256 (т.е. 2 в степени 8), то для индексации достаточно переменной длиною ровно 8 бит (char, обычно, как раз имеет такой размер), при этом никаких "лишних" бит (корорые нужно отбрасывать/обнулять) нет - что бывает удобным. Идея использования разрядности переменных для ограничения диапазона изменения величины это очень плохая идея. Потому, что разрядность переменных архитектурно- и компиляторно-зависимая величина. В стандарте СИ разрядность переменных не определена строго. В очередной раз привожу пример: CCS от TI и МК из серии TMS320, где char 16-и битный. Ну и добавок, отсутствие явной проверки на выход за границы диапазона отведенной памяти это источник глюков, а в ОС, например, это еще и источник появления уязвимостей.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|