roboforum.ru

Технический форум по робототехнике.

проблема с UART-ом

проблема с UART-ом

milkpower » 01 апр 2009, 11:25

не могу понять в чем проблема, МК-atmega162
программка пример для OR-AVR-M32-N-PG
файлы uart.c и uart.h переделал для 162-й, т.к. в ней 2 uart'а, пользуюсь нулевым.
компилится все нормально, но
проэмулировал в протеусе, на виртуал терминале какая-то ерунда. пробовал играться со скоростью, с частотой кварца,
пофик, все равно ерунду показывает, осцилограф показывает явно передачу, менял передаваемые значения, вроде похоже на правду.
у меня протеус глючит или что-то я не доделал?
prot-emu.JPG
результат протеуса


проект протеуса, версия 7.4 sp3
prot.rar
(24.72 КиБ) Скачиваний: 23


основная программа winAvr компилирую в avrstudio
Код: Выделить всёРазвернуть
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "defines.h"
#include "usart.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


//создаём поток UART используя функции получения символа и отправки символа из библиотеки "uart.h"
FILE uart0_str = FDEV_SETUP_STREAM(uart0_putchar, uart0_getchar, _FDEV_SETUP_RW);

int main(void)
{   

   uart0_init(); //Инициализируем UART
   stdout = stdin = &uart0_str; //Назначим потоки стандартного ввода\вывода на UART
   uint8_t btn=1; //Заведём переменную состояния кнопки
   PORTD = 0x10; //4-й пин порта D подтянем к +3.3 В
   while(1) //Бесконечный цикл
      {
      if((PIND & 0x10) == 0x00){ //Если нажата кнопка (на D4 напряжение 0 В)
      if( btn != 1){ //Если состояние стало «нажата»
//      UDR0=0b11001001;
      printf("Button pressed!"); //сообщить
      btn=1; //запомнить состояние
      };
      }else{ //Иначе не нажата (на D4 напряжение +3.3 В)
       if( btn != 0){ //Если состояние стало «не нажата»
       printf("Button released!"); //сообщить
       btn=0; //запомнить состояние
       };
      };
   _delay_ms(50); //Ждем 0.05 сек
   };
return 0;
}


usart.c
Код: Выделить всёРазвернуть
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <joerg@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Stdio demo, UART implementation
*
* $Id: uart.c,v 1.1.2.1 2005/12/28 22:35:08 joerg_wunsch Exp $
*/

#include "defines.h"

#include <stdint.h>
#include <stdio.h>

#include <avr/io.h>

#include "usart.h"

/*
* Initialize the UART to 9600 Bd, tx/rx, 8N1.
*/
void
uart0_init(void)
{
#if F_CPU < 2000000UL && defined(U2X)
  UCSR0A = _BV(U2X);             /* improve baud rate error by using 2x clk */
  UBRR0L = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
  UBRR0L = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
  UCSR0B = _BV(TXEN0) | _BV(RXEN0); /* tx/rx enable */
}

/*
* Send character c down the UART Tx, wait until tx holding register
* is empty.
*/
int
uart0_putchar(char c, FILE *stream)
{

  if (c == '\a')
    {
      fputs("*ring*\n", stderr);
      return 0;
    }

  if (c == '\n')
    uart0_putchar('\r', stream);
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = c;

  return 0;
}

int
uart0_putchar0(char c, FILE *stream)
{
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = c;
  return 0;
}

/*
* Receive a character from the UART Rx.
*
* This features a simple line-editor that allows to delete and
* re-edit the characters entered, until either CR or NL is entered.
* Printable characters entered will be echoed using uart_putchar().
*
* Editing characters:
*
* . \b (BS) or \177 (DEL) delete the previous character
* . ^u kills the entire input buffer
* . ^w deletes the previous word
* . ^r sends a CR, and then reprints the buffer
* . \t will be replaced by a single space
*
* All other control characters will be ignored.
*
* The internal line buffer is RX_BUFSIZE (80) characters long, which
* includes the terminating \n (but no terminating \0).  If the buffer
* is full (i. e., at RX_BUFSIZE-1 characters in order to keep space for
* the trailing \n), any further input attempts will send a \a to
* uart_putchar() (BEL character), although line editing is still
* allowed.
*
* Input errors while talking to the UART will cause an immediate
* return of -1 (error indication).  Notably, this will be caused by a
* framing error (e. g. serial line "break" condition), by an input
* overrun, and by a parity error (if parity was enabled and automatic
* parity recognition is supported by hardware).
*
* Successive calls to uart_getchar() will be satisfied from the
* internal buffer until that buffer is emptied again.
*/
int
uart0_getchar(FILE *stream)
{
  uint8_t c;
  char *cp, *cp2;
  static char b[RX_BUFSIZE];
  static char *rxp;

  if (rxp == 0)
    for (cp = b;;)
      {
   loop_until_bit_is_set(UCSR0A, RXC0);
   if (UCSR0A & _BV(FE0))
     return _FDEV_EOF;
   if (UCSR0A & _BV(DOR0))
     return _FDEV_ERR;
   c = UDR0;
   /* behaviour similar to Unix stty ICRNL */
   
   if (c == '\r')
     c = '\n';
   if (c == '\n')
     {
       *cp = c;
       //uart_putchar(c, stream);
       rxp = b;
       break;
     }
   else if (c == '\t')
     c = ' ';

   if ((c >= (uint8_t)' ' && c <= (uint8_t)'\x7e') ||
       c >= (uint8_t)'\xa0')
     {
       if (cp == b + RX_BUFSIZE - 1){
         //uart_putchar('\a', stream);
       }else
         {
      *cp++ = c;
      //uart_putchar(c, stream);
         }
       continue;
     }

   switch (c)
     {
     case 'c' & 0x1f:
       return -1;

     case '\b':
     case '\x7f':
       if (cp > b)
         {
      //uart_putchar('\b', stream);
      //uart_putchar(' ', stream);
      //uart_putchar('\b', stream);
      cp--;
         }
       break;

     case 'r' & 0x1f:
       //uart_putchar('\r', stream);
       for (cp2 = b; cp2 < cp; cp2++)
         //uart_putchar(*cp2, stream);
       break;

     case 'u' & 0x1f:
       while (cp > b)
         {
      //uart_putchar('\b', stream);
      //uart_putchar(' ', stream);
      //uart_putchar('\b', stream);
      cp--;
         }
       break;

     case 'w' & 0x1f:
       while (cp > b && cp[-1] != ' ')
         {
      //uart_putchar('\b', stream);
      //uart_putchar(' ', stream);
      //uart_putchar('\b', stream);
      cp--;
         }
       break;
     }
      }

  c = *rxp++;
  if (c == '\n')
    rxp = 0;

  return c;
}

int
uart0_getchar0(FILE *stream)
{
  uint8_t c;
  loop_until_bit_is_set(UCSR0A, RXC0);
  c = UDR0;
  return c;
}


usart.h
Код: Выделить всёРазвернуть
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <joerg@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Stdio demo, UART declarations
*
* $Id: uart.h,v 1.1.2.1 2005/12/28 22:35:08 joerg_wunsch Exp $
*/

/*
* Perform UART startup initialization.
*/
void   uart_init(void);

/*
* Send one character to the UART.
*/
int   uart_putchar(char c, FILE *stream);
int   uart_putchar0(char c, FILE *stream);

/*
* Size of internal line buffer used by uart_getchar().
*/
#define RX_BUFSIZE 80

/*
* Receive one character from the UART.  The actual reception is
* line-buffered, and one character is returned from the buffer at
* each invokation.
*/
int   uart_getchar(FILE *stream);
int   uart_getchar0(FILE *stream);


и defines.h
Код: Выделить всёРазвернуть
/* CPU frequency */
#define F_CPU 14745600UL

/* UART baud rate */
#define UART_BAUD  9600

Re: проблема с UART-ом

=DeaD= » 01 апр 2009, 12:28

Может модель кривая? МК точно на 14.ххх МГц работает?

Re: проблема с UART-ом

milkpower » 01 апр 2009, 12:38

в протеусе в свойствах мк стоит 14745600
пробовал менять на мегу 16 все соответственно.
тоже самое

Re: проблема с UART-ом

milkpower » 01 апр 2009, 23:57

после ковыряний и шаманских действий, выяснилось что скорость уарта с меги эмулируется в несколько раз медленнее чем предпологает терминал. вот и не пойму кому верить, коду или протеусу.

Re: проблема с UART-ом

Digit » 02 апр 2009, 08:36

и не поймешь без детального ковыряния в коде. в протеусе тоже такая гора ошибок, что... :o причем от одного SP к другому (не говоря о разных версиях проги) ошибки меняются так, будто совсем другое ПО ставишь
так что только внимательно разобравшись в проге поймешь.
ну и еще как вариант попытаться с чем-нить другом модельнуть.

Re: проблема с UART-ом

milkpower » 02 апр 2009, 09:59

вобщем обнаружил следующие косяки.
взял все перекомпилил для меги32.
взял старый семпл протеуса с 32-й мегой, все убрал, поставил свое. в итоге все заработало, но только вместо планируемых-9600 и 16Мгц, В протеусе нашлись значения 4мГц МК и в терминале установил 2400. и все заработало на удивление.
после я взял и тупо поменял мегу 32 на мегу 32 но уже из новой библиотеки, и какой вы предпологаете результат был?
все перестало работать, шаманство со скоростями уже не прокатывало.
походу чето с протеусом плохо.

Re: проблема с UART-ом

Master » 02 апр 2009, 21:09

Ну на то он и "бесплатный", у меня был глюк когда я менял прошивку, а в протеусе ваще ничего не менялось, 2 дня бился, клок волос вырвал. В итоге поменял CVavr на более новый и все стало гуд. Хотя CVavr старый был рабочий и на стором протеусе работал.

Re: проблема с UART-ом

avr123.nm.ru » 02 апр 2009, 21:33

milkpower писал(а):не могу понять в чем проблема


Я тоже. проект то пустой. Чего там понять можно ????????

Re: проблема с UART-ом

milkpower » 03 апр 2009, 00:24

там нет хекс файла?
я ниже исходники все выложил. возможно просто в них ошибка

Re: проблема с UART-ом

avr123.nm.ru » 03 апр 2009, 01:14

milkpower писал(а):возможно просто в них ошибка

возможно.


Rambler\'s Top100 Mail.ru counter