Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

UART - szukam gotowej procedury (odbior)

24 Lip 2006 11:18 1839 2
  • Poziom 10  
    Witam

    Problem jest nastepujacy:

    Szukam gotowej procedury ktora spelnia funkcje uart (potrzebny jest tylko odbior).
    Predkosc transmisji jest zniewalajaca bo az 100 bit/s ;-)
    Procedura wywolywana bedzie dokladnie co 1ms a wiec na jeden bit przypadac bedzie 10 wywolan procedury.
  • Poziom 16  
    codevision avr
    atmega 8515
    nadawanie i odbior


    /*********************************************
    This program was produced by the
    CodeWizardAVR V1.23.8a Professional
    Automatic Program Generator
    © Copyright 1998-2003 HP InfoTech s.r.l.
    http://www.hpinfotech.ro
    e-mail:office@hpinfotech.ro

    Project :
    Version :
    Date : 2006-07-02
    Author : j
    Company :
    Comments:


    Chip type : ATmega8515
    Program type : Application
    Clock frequency : 3,686400 MHz
    Memory model : Small
    External SRAM size : 0
    Data Stack size : 128
    *********************************************/

    #include <mega8515.h>

    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    // USART Receiver buffer
    #define RX_BUFFER_SIZE 8
    char rx_buffer[RX_BUFFER_SIZE];
    unsigned char rx_wr_index,rx_rd_index,rx_counter;
    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow;

    // USART Receiver interrupt service routine
    #pragma savereg-
    interrupt [USART_RXC] void uart_rx_isr(void)
    {
    char status,data;
    #asm
    push r26
    push r27
    push r30
    push r31
    in r26,sreg
    push r26
    #endasm
    status=UCSRA;
    data=UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
    rx_buffer[rx_wr_index]=data;
    if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
    if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };
    };
    #asm
    pop r26
    out sreg,r26
    pop r31
    pop r30
    pop r27
    pop r26
    #endasm
    }
    #pragma savereg+

    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    char data;
    while (rx_counter==0);
    data=rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif

    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 8
    char tx_buffer[TX_BUFFER_SIZE];
    unsigned char tx_wr_index,tx_rd_index,tx_counter;

    // USART Transmitter interrupt service routine
    #pragma savereg-
    interrupt [USART_TXC] void uart_tx_isr(void)
    {
    #asm
    push r26
    push r27
    push r30
    push r31
    in r26,sreg
    push r26
    #endasm
    if (tx_counter)
    {
    --tx_counter;
    UDR=tx_buffer[tx_rd_index];
    if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
    };
    #asm
    pop r26
    out sreg,r26
    pop r31
    pop r30
    pop r27
    pop r26
    #endasm
    }
    #pragma savereg+

    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
    {
    tx_buffer[tx_wr_index]=c;
    if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
    ++tx_counter;
    }
    else UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif

    // Standard Input/Output functions
    #include <stdio.h>

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTD=0x00;
    DDRD=0x00;

    // Port E initialization
    // Func0=In Func1=In Func2=In
    // State0=T State1=T State2=T
    PORTE=0x00;
    DDRE=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    TCCR0=0x00;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    GICR|=0x00;
    MCUCR=0x00;
    EMCUCR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;

    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud rate: 9600
    UCSRA=0x00;
    UCSRB=0xD8;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x17;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    // Analog Comparator Output: Off
    ACSR=0x80;

    // Global enable interrupts
    #asm("sei")

    while (1)
    {
    // Place your code here

    };
    }
  • Poziom 11  
    Witam. Nie chcąc bawić się z timer'ami na szybko postanowiłem napisać programowy UART z wykorzystaniem powyższego kodu. Jak na razie napisałem część wysyłania do komputera. Wprowadziłem własne modyfikacje -> LSB wysyłany pierwszy i działa. W przypadku gdy MSB był pierwszy nie chciało oczywiście nic sensownego wyświetlać. Dodam tylko że osiągnąłem jedynie max BAUD rate 1200. Pracuję pod Linuxem :)
    Pozdrawiam Radek



    Code:

    //plik główny
    int main(void)
    {
    int licznik=0;   
    //char byte='a';
    char byte[]={"abcdfghjaaaaaaaaaaaaaaaaaaaaaaaaaaaeeeeeeeeeeeeeeeeeeeeeeeeettttttttttttttttttttttttttklasd"};
    LCD_Initalize();
    LCD_Clear();
    DDRA |= _BV(0); //as output 1 in reg DDRA0
       while(1){
          for(licznik=0;NULL!=byte[licznik];licznik++){
             soft_UART(byte[licznik]);
             //itoa(byte,bufor,10);
             //LCD_WriteText(bufor);
             //LCD_Clear();
          }
       }

    return 1;
    }



    //plik Functions.c
    #include "Header.h"

    inline void _delay_uart(void){

    int rest=1000000/BAUD;   //how much us as delay
       for(;;)   {
          if (rest>=48)_delay_us(48);
          else {
             _delay_us(rest);
             break;
          }
          rest-=48;         // 48 max delay_us with 16MHz oscillator  768/16=48
       }
    }

    // uart programowy
    void soft_UART(char byte){

    unsigned short i=0;
       //start bit
       //DDRA |= _BV(0);    // port A0 as output
       PORTA &= ~_BV(0);   //set low for start bit
       _delay_uart();   
       
    // send 8bits MSB last
       
       for(i=0;i<8;i++){
          if((byte) & 0x01) {
             PORTA |= _BV(0) ;   //write bit "1"
          //   LCD_WriteText("1");
          }
          else {
             PORTA &= ~_BV(0);           //write bit "0"
          //   LCD_WriteText("0");
          }
          byte>>=1;
          _delay_uart();
       }

          PORTA |= _BV(0);   //set high for stop bits
       _delay_uart();
     
    }

    //plik Headers.h
    #include <avr/io.h>
    #include "HD44780.h"
    #include <stdlib.h>
    //#include <math.h>

    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif

    #define BAUD 1200

    #include <util/delay.h>


    //  PORTA2_WRITE_0 PORTA &= ~_BV(2)
    //  PORTA2_WRITE_1 PORTA |= _BV(2)
    //  setPORTA2_as_output DDRA |= _BV(2)
    //  setPORTA2_as_inputt DDRA &= ~_BV(2)

    void soft_UART(char);