logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

UART odbiór – gotowa procedura na 100 bit/s, wywołania co 1 ms, 10 wywołań/bit

epikur 24 Lip 2006 11:18 2127 2
REKLAMA
  • #1 2846469
    epikur
    Poziom 11  
    Posty: 33
    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.
  • REKLAMA
  • #2 2846507
    maxiu25
    Poziom 16  
    Posty: 190
    Pomógł: 16
    Ocena: 3
    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

    };
    }
  • #3 5773957
    Radkoo
    Poziom 12  
    Posty: 14
    Pomógł: 2
    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



    
    //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);
REKLAMA