Jump to content

    
Sign in to follow this  
David_Ali

Нужен учитель

Recommended Posts

Для обмена по 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); // то выключаем вызов прерывания по освобождению буфера передатчика
}

 

Share this post


Link to post
Share on other sites
Для обмена по UART правильнее использовать FIFO буфер.

Спасибо большое, я обязательно попрактикую это сегодня же, я сам дописал с горем пополам свой код, все работает нормально, даже добавил туда еще функции. Теперь стоит эта штука на борту ВАЗ2107. Заводит ее, открывает закрывает окна, блокирует двери и прочие мелочи. Хоть и мелочи, но приятно. Даже маленький дисплей от нокиа показывает температуру в салоне(датчик тмпературы dht11), потом думаю встроить ее куда нибудь в более важную часть. Пока работы много время нет, но опыт с ней и приходит. Хочу подключить ко всему этому делу gsm sim900 и пару датчиков и сигнализацию получать в виде смс, просто самоучкой быть тяжеловато немного. В принципе как и всегда. Еще раз спасибо за ответ.

Share this post


Link to post
Share on other sites

#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, им реально удобно пользоватся.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this