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





наверное стоит поставить нормальный терминал и отладить работу прошивки на нем
при закороченных rx<->tx и пк, и минибот слышат и видят все, что пишут в уарт

 
 
#define DISABLE_RX() UCSRB &= ~(1<<RXEN)
#define ENABLE_RX()  UCSRB |= (1<<RXEN)
/* Сеанс черной магии.
 * Подробности смотри <util/atomic.h>
 */
static __inline__ uint8_t __disblRxRet()
{
  DISABLE_RX();
  return 1;
}
static __inline__ void __enblRxParam(const uint8_t *__s)
{
  ENABLE_RX();
  (void)__s; // чтобы компилятор не сыпал предупреждений про неиспользуемую переменную
}
/* OUT_BLOCK_FORCEON() {
 *   puts("output");
 * }
 */
#define OUT_BLOCK_FORCEON() for(uint8_t __st __attribute__((__cleanup__(__enblRxParam))) = __disblRxRet(); __st; __st=0)


#ifndef USART_H_
#define USART_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include "global.h"
/**
 * Use the following macros to determine the 'baud' parameter values
 * for uart_init()
 * @warning 'baud' SHOULD ALWAYS BE A CONSTANT or a lot of code
 * will be generated.
 */
//#define USART_BAUD(baud) ((uint16_t)((F_CPU / (16.0 * (baud))) + 0.5) - 1)
#define USART_BAUD(baud) ((uint16_t)((F_CPU + (baud * 8L)) / (16L * (baud))) - 1) //! vg
/**
 * Some typical baud rates
 * Confirm the cpu clock rate will support the desired baud rate
 */
#define B115200 (USART_BAUD(115200L))
#define B76800  (USART_BAUD(76800UL))
#define B57600  (USART_BAUD(57600UL))
#define B38400  (USART_BAUD(38400UL))
#define B28800  (USART_BAUD(28800U))
#define B19200  (USART_BAUD(19200U))
#define B14400  (USART_BAUD(14400))
#define B9600   (USART_BAUD(9600))
#define B4800   (USART_BAUD(4800))
#define B2400   (USART_BAUD(2400))
/**
 * Double Speed operation
 * use the following macros to determine the 'baud' parameter values
 * for uartInit() for Double Speed operation.  The macros above will
 * also work just fine.
 * @warning 'baud' SHOULD ALWAYS BE A CONSTANT or a lot of code
 * will be generated.
 */
#define DOUBLE_SPEED_BIT (1<<15)
#define USART_2x_BAUD(baud) \
   (((uint16_t)((F_CPU / (8.0 * (baud))) + 0.5) - 1) | DOUBLE_SPEED_BIT)
/**
 * Some typical baud rates
 * Confirm the cpu clock rate will support the desired baud rate
 */
#define B2x115200 (USART_2x_BAUD(115200L))
#define B2x76800  (USART_2x_BAUD(76800UL))
#define B2x57600  (USART_2x_BAUD(57600UL))
#define B2x38400  (USART_2x_BAUD(38400UL))
#define B2x28800  (USART_2x_BAUD(28800U))
#define B2x19200  (USART_2x_BAUD(19200U))
#define B2x14400  (USART_2x_BAUD(14400))
#define B2x9600   (USART_2x_BAUD(9600))
#define B2x4800   (USART_2x_BAUD(4800))
#define B2x2400   (USART_2x_BAUD(2400))
//! Type of interrupt handler to use for uart interrupts.
/// Value may be SIGNAL or INTERRUPT.
/// \warning Do not change unless you know what you're doing.
#ifndef UART_INTERRUPT_HANDLER
#define UART_INTERRUPT_HANDLER   SIGNAL
#endif
// compatibility with most newer processors
#ifdef UCSRB
   #define UCR               UCSRB
#endif
// compatibility with old Mega processors
#if defined(UBRR) && !defined(UBRRL)
   #define   UBRRL            UBRR
#endif
/** defines
**/
#define UART_DISABLE_RX() UCSRB &= ~(1<<RXEN)
#define UART_ENABLE_RX()  UCSRB |= (1<<RXEN)
// USART file device
extern FILE usart_fdev;
/**
 * This function initializes the USART
 *
 * @param baud baudrate divisor
 * @return void
 *
 * Example
 * @code
 * usart_init(B9600);
 * // or
 * usart_init(USART_BAUD(9600));
 * @endcode
 */
void usart_init(uint16_t baud);
/**
 * Send one character to the UART.
 */
int usart_putchar(char c, FILE *stream);
int usart_putchar0(char c, FILE *stream);
/**
 * Receive one character from the UART.
 */
int usart_getchar(FILE *stream);
int usart_getchar0(FILE *stream);
#endif /*USART_H_*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "irs_uart.h"
// usart file device
FILE usart_fdev = FDEV_SETUP_STREAM(usart_putchar, usart_getchar, _FDEV_SETUP_RW);
// This function initializes the USART
void usart_init(uint16_t baud) {
    // disable the USART
    UCSRB = 0x00;
    UCSRA = 0x00;
    if ( baud & DOUBLE_SPEED_BIT )
        UCSRA |= (1 << U2X);
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Mode: Asynchronous
    UCSRC=0x86;
    UCSRB &= ~(UCSZ2);
    // load the baudrate divisor register
    UBRRL = baud;
    // output the upper four bits of the baudrate divisor
    UBRRH = (baud >> 8) & 0x0F;
    // enable the USART0 transmitter & receiver
    // enable RxD/TxD and interrupts
    UCSRB |= (1<<TXCIE)|(1<<RXCIE)|(1<<TXEN)|(1<<RXEN);
}
/*
 * Send character c down the UART Tx, wait until tx holding register
 * is empty.
 */
int usart_putchar(char c, FILE *stream) {
    if ( c == '\n' )
        usart_putchar('\r', stream);
    loop_until_bit_is_set(UCSRA, UDRE);
    UART_DISABLE_RX();
    UDR = c;
    return 0;
}
int usart_putchar0(char c, FILE *stream) {
    loop_until_bit_is_set(UCSRA, UDRE);
    UART_DISABLE_RX();
    UDR = c;
    return 0;
}
int usart_getchar(FILE *stream) {
    uint8_t c;
    loop_until_bit_is_set(UCSRA, RXC);
    c = UDR;
    if ( c == '\r' )
        c = '\n';
    return c;
}
int usart_getchar0(FILE *stream) {
    uint8_t c;
    loop_until_bit_is_set(UCSRA, RXC);
    c = UDR;
    return c;
}
UART_INTERRUPT_HANDLER(SIG_UART_RECV) {
}
// UART Transmit Complete Interrupt Handler
UART_INTERRUPT_HANDLER(SIG_UART_TRANS) {
    UART_ENABLE_RX();
}
[code=cpp][/code]
Толку использовать прерывания, если вызовы все равно блокирующие?
И еще маленькое замечание, копируете код — оставляйте заголовок с копирайтом/лицензией.
// ........
#define USART_BAUD(baud) ((uint16_t)((F_CPU + (baud * 8L)) / (16L * (baud))) - 1)
#define B9600   (USART_BAUD(9600))
#ifndef UART_INTERRUPT_HANDLER
#define UART_INTERRUPT_HANDLER   SIGNAL
#endif
#define UART_DISABLE_RX() UCSRB &= ~(1<<RXEN)
#define UART_ENABLE_RX()  UCSRB |= (1<<RXEN)
// .........
// ........
// This function initializes the USART
void usart_init(uint16_t baud) {
    // disable the USART
    UCSRB = 0x00;
    UCSRA = 0x00;
    if ( baud & DOUBLE_SPEED_BIT )
        UCSRA |= (1 << U2X);
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Mode: Asynchronous
    UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRC &= (~(1<<UMSEL))&(~(1<<UPM1))&(~(1<<UPM0))&(~(1<<USBS))&(~(1<<UCPOL));
    UCSRB &= ~(UCSZ2);
    // load the baudrate divisor register
    UBRRL = baud;
    // output the upper four bits of the baudrate divisor
    UBRRH = (baud >> 8) & 0x0F;
    // enable the USART0 transmitter & receiver
    // enable RxD/TxD and interrupts
    UCSRB |= (1<<TXCIE)|(1<<RXCIE)|(1<<TXEN)|(1<<RXEN);
}
// .......
int usart_putchar(char c, FILE *stream) {
    if ( c == '\n' )
        usart_putchar('\r', stream);
    loop_until_bit_is_set(UCSRA, UDRE);
    UART_DISABLE_RX();
    UDR = c;
    return 0;
}
int usart_putchar0(char c, FILE *stream) {
    loop_until_bit_is_set(UCSRA, UDRE);
    UART_DISABLE_RX();
    UDR = c;
    return 0;
}
// .......
UART_INTERRUPT_HANDLER(SIG_UART_RECV) {
}
// UART Transmit Complete Interrupt Handler
UART_INTERRUPT_HANDLER(SIG_UART_TRANS) {
    UART_ENABLE_RX();
}
// .......
// .......
usart_init(B9600);
    // use USART device for stdio
    stderr = stdout = stdin = &usart_fdev;
    char tmpbuff[5] = {'H', 'E', 'L', 'L', 'O'};
    while(1) {
        for(unsigned int i=0; i<5; i++)
            usart_putchar(tmpbuff[i], stdout);
    }
// .......
int usart_putchar(char c, FILE *stream) {
    if ( c == '\n' )
        usart_putchar('\r', stream);
    loop_until_bit_is_set(UCSRA, UDRE); // перестраховка
    UART_DISABLE_RX();
    UDR = c;
    loop_until_bit_is_set(UCSRA, UDRE); // ждем пока символ отравляется
    UART_ENABLE_RX(); // отправили, включили прием
    return 0;
}
//...
    usart_init(B9600);
    // use USART device for stdio
    stderr = stdout = stdin = &usart_fdev;
    char tmpbuff[] = "Hello world!\n";
    while(1) {
        puts(tmpbuf);
    }
//...

char tmpbuff[] = "Hi!"Вернуться в МиниБот — национальный класс роботов
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0