Operácie

AVR Serial.c: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Balogh (diskusia | príspevky)
Bez shrnutí editace
Riadok 126: Riadok 126:
int main(void)
int main(void)
{  
{  
  deviceInit();               // Inicializacia displeja alebo seriovej linky
  inituart();               // Inicializacia seriovej linky
  stdout = &mystdout;          // Odteraz funguje printf();
  stdout = &mystdout;          // Odteraz funguje printf();


Riadok 134: Riadok 134:
</source>
</source>
Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami...
Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami...
Úplne rovnako sa dá implementovať printf() aj na LCD displej, len ho treba na začiatku zinicializovať a namiesto funkcie sendchar napísať niečo ako LCDsendchar().

Verzia z 20:06, 1. december 2008

serial.h

/* ************************************************************************* */
/*                                                                           */
/* Description       : Header file for serial.c                              */
/*                     Based on AppNote AVR109 - Self-programming            */
/*                                                                           */
/* FileName          : serial.h                                              */
/* Compiler          : AVR-GCC/avr-libc(>= 1.2.5), TODO: IAR C 3.10C         */
/* Revision          : 1.7                                                   */
/* Date              : 30. November 2008                                     */
/* Updated by        : Richard Balogh                                        */
/* Target platform   : ATmega88, TODO: All AVRs with bootloader support      */
/*                                                                           */
/* ************************************************************************* */

         void inituart( void );
         void sendchar( unsigned char );
unsigned char recchar( void );

serial.c

/* ************************************************************************* */
/*                                                                           */
/* Description       : UART communication routines                           */
/*                     Based on AppNote AVR109 - Self-programming            */
/*                                                                           */
/* FileName          : serial.h                                              */
/* Compiler          : AVR-GCC/avr-libc(>= 1.2.5), TODO: IAR C 3.10C         */
/* Revision          : 1.7                                                   */
/* Date              : 30. November 2008                                     */
/* Updated by        : Richard Balogh                                        */
/* Target platform   : ATmega88, TODO: All AVRs with bootloader support      */
/*                                                                           */
/* ************************************************************************* */

#include <avr\io.h>

/* baud rate register value calculation */
#define	CPU_FREQ	18432000UL      // If CKDIV8 checked, then /8!
#define	BAUD_RATE	9600
                             // BAUD = f / 16 * (UBR+1) alebo UBR = CPUFREQ/16/BAUD_RATE-1
#define	BRREG_VALUE	119  // hodnota z tabulky v datashhete pre 18,4320MHz, 2x=0, 9600Baud, error = 0%    


/* definitions for UART control */      // upravene pre ATmega88
#define	BAUD_RATE_LOW_REG	UBRR0L  // ??? (Staci Low Byte, < 255 )
#define	UART_CONTROL_REG_B	UCSR0B  // OK, checked
#define	ENABLE_TRANSMITTER_BIT	TXEN0   // OK, checked
#define	ENABLE_RECEIVER_BIT	RXEN0   // OK, checked
#define	UART_STATUS_REG		UCSR0A  // OK, checked (but also control reg.)
#define DATA_REGISTER_EMPTY_BIT UDRE0   // Added, for possible speed-up
#define	TRANSMIT_COMPLETE_BIT	TXC0    // OK, checked
#define	RECEIVE_COMPLETE_BIT	RXC0    // OK, checked
#define UART_CONTROL_REG_C      UCSR0C  // Added for mode setting
#define	UART_DATA_REG		UDR0    // OK, checked



void inituart(void)
{
  BAUD_RATE_LOW_REG = BRREG_VALUE;                 // OK, preddelic pre 9600
                                                   // bit 2x = 0
  UART_CONTROL_REG_C = (1<<UCSZ01)|(1<<UCSZ00);    // Added: Async. UART, None 
                                                   // Parity, 8-data, 1 stopbit
  UART_CONTROL_REG_B = (1 << ENABLE_RECEIVER_BIT)|
                    (1 << ENABLE_TRANSMITTER_BIT); // enable receive + transmit 
                                                   
}


void sendchar(unsigned char c)
{
  UART_DATA_REG = c;                                   // prepare transmission
  while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)));// wait until byte sendt
  UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT);          // delete TXCflag
}


unsigned char recchar(void)
{
  while( !(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT)) );  // wait for data
  return UART_DATA_REG;
}

Testovací program. Testujeme len posielanie, naše káble nemajú privedené RxD.

main.c

#include <avr\io.h>
#include "serial.h"              // Nasa kniznica... 

int main(void) 
{
 char c;
 
 inituart();
 sendchar('O');
 sendchar('K');
 sendchar('\n');

 for (c=32;c<=127;c++) 
   sendchar(c);

 for (;;) {
     /* Do nothing */
          }
}


printf() na jednočipe?

Ak si napíšete vlastnú funkciu na zobrazenie jedného znaku na displej, alebo pre vyslanie jedného znaku po sériovej linke, potom môžete používať naozaj aj funkciu printf so všetkými jej vymoženosťami. Využívame pre tom knižnicu stdio.h, ktorá sa používa takto:

...
#include <stdio.h>

FILE mystdout = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);
                              // 'sendchar' je nova funkcia pre jeden znak

int main(void)
{ 
 inituart();	               // Inicializacia seriovej linky
 stdout = &mystdout;           // Odteraz funguje printf();

 printf("Hello, world!");
 return 0;
}

Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami... Úplne rovnako sa dá implementovať printf() aj na LCD displej, len ho treba na začiatku zinicializovať a namiesto funkcie sendchar napísať niečo ako LCDsendchar().