AVR Serial.c: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
(7 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 96: | Riadok 96: | ||
{ | { | ||
char c; | char c; | ||
DDRD = 0b00000010; | |||
PORTD = 0b00000011; // Set TxD pin as an output, RxD input | |||
inituart(); | inituart(); | ||
Riadok 110: | Riadok 113: | ||
} | } | ||
</source> | </source> | ||
== <TT>printf()</TT> 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 <TT>stdio.h</TT>, ktorá sa používa takto: | |||
<source lang="c"> | |||
... | |||
#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; | |||
} | |||
</source> | |||
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(). | |||
[[CADRS Cvičenie 11|Návrat na cvičenie 11...]] | |||
[[Category:AVR]][[Category:MMP]][[Category:DVPS]] |
Aktuálna revízia z 08:16, 26. október 2012
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;
DDRD = 0b00000010;
PORTD = 0b00000011; // Set TxD pin as an output, RxD input
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().