Atmega IrDA loopback

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 34
Зарегистрирован: Пн сен 29, 2008 21:47:32

Сообщение Andrejkin »

Привет,

Приходится часто иметь дело со связкой TFDU4101+ТOIM4232 (кто не в курсе, это ИК UART приёмо-передатчик и формирователь импульсов)
Перед установкой в устройство желательно удостоверится, что модуль работает. Так как приемопередатчик может ловить свой собственный отраженный сигнал, то алгоритм проверки очень простой - посылаем информацию с атмеги на ТOIM4232 Тх и представляем принятый сигнал простым миганием светодиода. Логически реализуемо, чтобы UART атмеги обрабатывал свои-же закольцованные данные с Тх на Rх?
Как можно доработать на сигнализацию приёма светодиодом код, который раз в некоторый интервал времени посылает на UART"Hello World"?

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

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
 
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
 
//Declaration of our functions
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);
 
char String[]="Hello world!!";    //String[] is in fact an array but when we put the text between the " " symbols the compiler threats it as a String and automatically puts the null termination character in the end of the text
 
int main(void){
USART_init();        //Call the USART initialization code
 
while(1){        //Infinite loop
 USART_putstring(String);    //Pass the string to the USART_putstring function and sends it over the serial
 _delay_ms(5000);        //Delay for 5 seconds so it will re-send the string every 5 seconds
 }
 
return 0;
}
 
void USART_init(void){
 
 UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
 UBRR0L = (uint8_t)(BAUD_PRESCALLER);
 UCSR0B = (1<<RXEN0)|(1<<TXEN0);
 UCSR0C = (3<<UCSZ00);
}
 
unsigned char USART_receive(void){
 
 while(!(UCSR0A & (1<<RXC0)));
 return UDR0;
 
}
 
void USART_send( unsigned char data){
 
 while(!(UCSR0A & (1<<UDRE0)));
 UDR0 = data;
 
}
 
void USART_putstring(char* StringPtr){
 
while(*StringPtr != 0x00){
 USART_send(*StringPtr);
 StringPtr++;}
 
}
Спасибо за подсказки

Андрей
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

делаете обработчик прерывания по приему байта USART, в этом обработчике складываете полученные байты в массив. когда отработает ваша функция USART_putstring(String), в этом массиве должна собраться копия строки - производите сравнение этой строки с содержимым массива и мигаете светодиодом, если совпали. само собой, перед очередной передачей-приемом надо проинициализировать массив и вспомогательные переменные.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 34
Зарегистрирован: Пн сен 29, 2008 21:47:32

Сообщение Andrejkin »

ARV писал(а):делаете обработчик прерывания по приему байта USART, в этом обработчике складываете полученные байты в массив. когда отработает ваша функция USART_putstring(String), в этом массиве должна собраться копия строки - производите сравнение этой строки с содержимым массива и мигаете светодиодом, если совпали. само собой, перед очередной передачей-приемом надо проинициализировать массив и вспомогательные переменные.
Прерывание должно быть как RXCIE: UART Receive Complete Interrupt Enable ?

Спасибо
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Andrejkin писал(а):Прерывание должно быть как RXCIE
оно самое
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 34
Зарегистрирован: Пн сен 29, 2008 21:47:32

Сообщение Andrejkin »

Правильно ли написан обработчик прерываний по UART? Функция по сравнению строки и массива Rх будет работать в таком виде?

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

#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>
#include<avr/interrupt.h>
#include <stdio.h>
#include <string.h>


#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

 
//Declaration of our functions
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);
volatile unsigned char data_in[8] ;
volatile unsigned char data_count;

ISR(USART_RXC_vect)
{
    // Get data from the USART in register
    data_in [data_count]  = UDR;

    // End of line!
    if (data_in[data_count] == '\n') {
        // Reset to 0, ready to go again
        data_count = 0;
    } else {
        data_count++;
   }
}


char String[]="Hello";    //String[] is in fact an array but when we put the text between the " " symbols the compiler threats it as a String and automatically puts the null termination character in the end of the text

 
int main(void){
DDRB = 0xFF; 
PORTB = 0x00; 
USART_init(); //Call the USART initialization code
sei();        
 
while(1){        //Infinite loop
USART_putstring(String);//Pass the string to the USART_putstring function and sends it over the serial

 if (strcmp(data_in, "Hello") == 0)
{
PORTB |= (1 << PB0); 
}
else
{
PORTB &= ~(1 << PB0); 
       }
 _delay_ms(1000);      //Delay for 1 seconds so it will re-send the string every 1 seconds
 }
 
return 0;
}


void USART_init(void){
 
 UBRRH = (uint8_t)(BAUD_PRESCALLER>>8);
 UBRRL = (uint8_t)(BAUD_PRESCALLER);
 UCSRB|= (1<<TXEN)|(1<<RXEN)|(1 << RXCIE);            // enable receiver and transmitter
 UCSRC|= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);

}
 
unsigned char USART_receive(void){
 
 while(!(UCSRA & (1<<RXC)));
 return UDR;
 
}
 
void USART_send( unsigned char data){
 
 while(!(UCSRA & (1<<UDRE)));
 UDR = data;
 
}
 
void USART_putstring(char* StringPtr){
 
while(*StringPtr != 0x00){
 USART_send(*StringPtr);
 StringPtr++;}
 
}
Спасибо
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

мне показалось, у вас есть ошибки. возможно, показалось...
1. вы отправляете строку "Hello", а в прерывании проверяете принятый символ на равенство '\n' - в посылаемой строке такого символа нет, и ваш алгоритм не сработает.
2. strcmp может сравнивать строки с нулем на конце, а функция передачи не передает терминальный ноль. да и в прерывании ноль в массив не попадет ни при каких условиях. соответственно, strcmp с большой вероятностью будет всегда сообщать, что строки не равны (если вообще будет что-то сообщать, а не вешать всю программу)

смотрите, что могу предложить вам я

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

volatile uint8_t is_ok;
volatile uint8_t ch;

ISR(USART_RXC_vect){
   is_ok = (UDR == ch);
}

int main(void){
   // инициализация периферии не показана

   for(ch=0; ; ch++){
       UDR = ch;
       _delay_ms(1); // тут задержка должна быть соответствующая скорости USART - больше, чем надо для передачи байта
      if(is_ok){
         // отображаем успешную приемопередачу
      } else {
         // отображаем ошибку приемопередачи
      }
      _delay_ms(50);
   }
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 34
Зарегистрирован: Пн сен 29, 2008 21:47:32

Сообщение Andrejkin »

Спасибо за подсказки! К сожалению я совсем далек от программирования на Си
Здесь задержка для того, чтобы успеть сравнить, то что приняли с UDR на передачу, перед тем как он опустеет ?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

задержка нужна, чтобы USART смог передать байт. так как UDR по факту представляет из себя 2 независимых регистра (один на запись для передачи, другой для чтения на приеме), то после того, как UDR "опустеет" при передаче, он немедленно в то же мгновение "наполнится" принятым байтом.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 34
Зарегистрирован: Пн сен 29, 2008 21:47:32

Сообщение Andrejkin »

Код сейчас такого вида, какие моменты ещё надо подправить? На терминал идут все буквы алфавита подряд;(

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

#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>
#include<avr/interrupt.h>
#include <stdio.h>


#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

 
//Declaration of our functions
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);
volatile uint8_t is_ok;
volatile uint8_t ch;

ISR(USART_RXC_vect)
{
    is_ok = (UDR == ch);
}


char String[]="Hello";    //String[] is in fact an array but when we put the text between the " " symbols the compiler threats it as a String and automatically puts the null termination character in the end of the text

 
int main(void){
DDRB = 0xFF; 
PORTB = 0x00; 
USART_init(); //Call the USART initialization code
sei(); 

while(1){        //Infinite loop
USART_putstring(String);    //Pass the string to the USART_putstring function and sends it over the serial

 for(ch=0; ; ch++){
       UDR = ch;
       _delay_ms(1); 
      if(is_ok){

		PORTB |= (1 << PB0); 
         
      } else {
	  PORTB &= ~(1 << PB0); 
         
      }
      _delay_ms(50);
   }       
 
 }
 
return 0;
}


void USART_init(void){
 
 UBRRH = (uint8_t)(BAUD_PRESCALLER>>8);
 UBRRL = (uint8_t)(BAUD_PRESCALLER);
 UCSRB|= (1<<TXEN)|(1<<RXEN)|(1 << RXCIE);            // enable receiver and transmitter
 UCSRC|= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);

}
 
unsigned char USART_receive(void){
 
 while(!(UCSRA & (1<<RXC)));
 return UDR;
 
}
 
void USART_send( unsigned char data){
 
 while(!(UCSRA & (1<<UDRE)));
 UDR = data;
 
}
 
void USART_putstring(char* StringPtr){
 
while(*StringPtr != 0x00){
 USART_send(*StringPtr);
 StringPtr++;}
 
}
Ответить

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