Vetal-Soft 0 30 апреля, 2013 Опубликовано 30 апреля, 2013 · Жалоба Для обмена по UART правильнее использовать FIFO буфер. Вот пример под AVR Studio: /* Файл main.c */ //#define F_CPU 16000000UL #include <avr/io.h> #include <stdio.h> // стандартная библиотека ввода/вывод #include <avr/pgmspace.h> // утилиты пространства программ #include "uart.h" // Создаем поток для ввода/вывода на/с UART для использования стандартных // функции ввод/вывода FILE uart_file = FDEV_SETUP_STREAM(uart_put, uart_get, _FDEV_SETUP_RW); int main (void) { uart_init(); // название Ф-ции говорит само за себя stdout = stdin = &uart_file; // теперь стандартные потоки ссылаются на наш поток char str[50]; printf_P(PSTR("Hello, World!\n\r")); printf_P(PSTR("Input string:")); scanf_P(PSTR("%49s"),&str); printf_P(PSTR("%s\n\r"),str); fprintf(&uart_file, "Bye-bye\n\r"); // Так можно выбирать с каким именно // потоком работать (для примера) while (1); return 0; } /* file "uart.h" */ #ifndef UART #define UART #include <stdio.h> #include <avr/io.h> #include <avr/interrupt.h> #define UART_FIFO_SIZE 64 // Размер FIFO #define UART_BAUD 9600 // Скороть UART void uart_init(void); int uart_get (FILE *stream); uint8_t uart_test (void); int uart_put (char d, FILE *stream); #endif /* end UART */ /* file "uart.c" */ #include "uart.h" typedef struct { // Структура для FIFO uint8_t idx_w; // Указатель на конец очереди FIFO uint8_t idx_r; // Указатель на начало очереди FIFO uint8_t count; // Счетчик количества данных в FIFO uint8_t buff[uART_FIFO_SIZE]; // Сам FIFO } FIFO; static volatile FIFO txfifo, rxfifo; /* Initialize UART */ void uart_init() { rxfifo.idx_r = 0; rxfifo.idx_w = 0; rxfifo.count = 0; txfifo.idx_r = 0; txfifo.idx_w = 0; txfifo.count = 0; UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1; // Настраиваем скорость работы UART UCSRB = _BV(RXEN)|_BV(RXCIE)|_BV(TXEN); // Включаем: прием, вызов прерывания по приему, передачу } uint8_t uart_test (void) { return rxfifo.count; } int uart_get (FILE *stream) // Ф-ция чтения FIFO для приемника { char d; uint8_t i; i = rxfifo.idx_r; while(rxfifo.count == 0); // Ожидание входящих данных d = rxfifo.buff[i++]; cli(); rxfifo.count--; sei(); if(i >= UART_FIFO_SIZE) i = 0; rxfifo.idx_r = i; uart_put(d,stream); // Эхо ответ return d; } int uart_put (char d, FILE *stream) // Ф-ция записи в FIFO для передатчика { uint8_t i; i = txfifo.idx_w; while(txfifo.count >= UART_FIFO_SIZE); // ждем когда освободится место в FIFO txfifo.buff[i++] = d; cli(); txfifo.count++; UCSRB |= _BV(UDRIE); // Включаем вызов прерывания по освобождению буфера передатчика sei(); if(i >= UART_FIFO_SIZE) i = 0; txfifo.idx_w = i; return 0; } ISR(USART_RXC_vect) // Прерывание по приему { uint8_t d, n, i; d = UDR; n = rxfifo.count; if(n < UART_FIFO_SIZE) // Если FIFO заполнен данные начнут теряться { rxfifo.count = ++n; i = rxfifo.idx_w; rxfifo.buff[i++] = d; if(i >= UART_FIFO_SIZE) i = 0; rxfifo.idx_w = i; } } ISR(USART_UDRE_vect) // Прерывание по освобождению буфера передатчика { uint8_t n, i; n = txfifo.count; if(n) { txfifo.count = --n; i = txfifo.idx_r; UDR = txfifo.buff[i++]; if(i >= UART_FIFO_SIZE) i = 0; txfifo.idx_r = i; } if(n == 0) // если FIFO пуст, UCSRB &= ~_BV(UDRIE); // то выключаем вызов прерывания по освобождению буфера передатчика } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
David_Ali 0 15 мая, 2013 Опубликовано 15 мая, 2013 · Жалоба Для обмена по UART правильнее использовать FIFO буфер. Спасибо большое, я обязательно попрактикую это сегодня же, я сам дописал с горем пополам свой код, все работает нормально, даже добавил туда еще функции. Теперь стоит эта штука на борту ВАЗ2107. Заводит ее, открывает закрывает окна, блокирует двери и прочие мелочи. Хоть и мелочи, но приятно. Даже маленький дисплей от нокиа показывает температуру в салоне(датчик тмпературы dht11), потом думаю встроить ее куда нибудь в более важную часть. Пока работы много время нет, но опыт с ней и приходит. Хочу подключить ко всему этому делу gsm sim900 и пару датчиков и сигнализацию получать в виде смс, просто самоучкой быть тяжеловато немного. В принципе как и всегда. Еще раз спасибо за ответ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
David_Ali 0 16 мая, 2013 Опубликовано 16 мая, 2013 · Жалоба #include <mega8.h> #include <delay.h> int TEMP16; int T; unsigned char temp; void main(void) { DDRB=0x00; PORTB=0xFF; DDRB = 0x00; DDRD=0xFF; PORTD=0x00; DDRC = 0x00; PORTC = 0xFF; ACSR=(1<<ACBG)|(1<<ACIE)|(1<<ACIS1)|(1<<ACIS0)|(1<<ACO);//инициализация компаратора TEMP16 = 0; while(1){ // бесконечный цикл if (PINB.1 == 1 && TEMP16 == 1) { // PORTD.3=1; // включаем 3 пин delay_ms(500); // пауза 0.5 секунды PORTD.3=0; // выключаем 3 пин TEMP16 = 0; } if (PINB.1 == 0 && TEMP16 == 0) { // PORTD.3=1; //включаем 3 пин delay_ms(500); //пауза 0.5 секунды PORTD.3=0; //выключаем 3 пин delay_ms(500); //пауза 0.5 секунды PORTD.3=1; // включаем 3 пин delay_ms(500); //пауза 0.5 секунды PORTD.3=0; //выключаем 3 пин TEMP16 = 1; } if(PINB.2 == 0 && T == 0) { PORTD.2=1; // включаем второй пин delay_ms(3000); // пауза 3 секунды PORTD.2=0; //выключаем втрой пин T = 1; } if(PINB.2==1 && T == 1) { PORTD.2=1; // включаем второй пин delay_ms(3000); //пауза 3 секунды PORTD.2=0; //выключаем втрой пин T = 0; } temp = ACSR; // читаем ACSR temp &= 0x20; // 5 бит компаратора if(temp == 0x20) // если 1 PORTD.1=1; else PORTD.1=0; // если 0 } } Здравствуйте! эта штуковина у меня для получения данных о заряде аккумулятора, нескольких "прибамбасов" в виде мигания фарами и звука сирены. вопрос почему эти фнкции выполняются поочередно, если одновременно подать 0 или 1 на оба пина PB1 и PB0, ничего не просходит, а по отдельности работает. P.S. спасибо за совет с CVavr, им реально удобно пользоватся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Burner 0 16 августа, 2013 Опубликовано 16 августа, 2013 · Жалоба )) а что за классификация? можно ли узнать? http://www.tomyself.ru/mpostsocio/msociostart/49-socio3part Экстравертный этик. Вы - возможно, ЭИЭ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться