[PIC18F]{EUSART] Podstawowe uruchomienie uartu.
: niedziela 27 lis 2016, 21:27
Witam. Wrzucam przykładowy soft uruchamiający uart w układzie PIC18F4550. Moduł EUSART potrafi pracować w trybie synchronicznym i asynchronicznym oraz pracować w sieci LIN. Ponadto ma funkcję automatycznej detekcji prędkości pracy (baudrate). Najczęściej jednak stosuje się proste rozwiązanie, czyli tryb asynchroniczny. Przy okazji można w sofcie podejrzeć konfiguracje priorytetów przerwań oraz ich obsługę. Niektórzy zauważą dwa rodzaje operacji na rejestrach. Tak, część jest wykonywana za pomocą makr, a część za pomocą pól bitowych w strukturach, które są zdefiniowane w pliku pic18f4550.h. Ten plik dostarczany jest wraz z kompilatorem, a żeby go podejrzeć, wystarczy kliknąć prawym klawiszem myszy na dowolną nazwę rejestru i wybrać "navigate / go to declaration/definition". Programik testowy wysyła kilka razy na sekundę kawałek tekstu na dowolny terminal włączony w PC z ustawieniami 19200 8N1. A tutaj main.c:
Oraz kompletny projekt:
Pozdrawiam.
Kod: Zaznacz cały
/*
* File: main.c
* Author: Arkadiusz Pytlik
*
* Created on 27 listopada 2016
*/
#include "config.h"
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 48000000UL
#endif
#include <xc.h>
#include <stdint.h>
#include <stdbool.h>
#include "usart/usart.h"
#define TMR0_RELOAD ((_XTAL_FREQ/4)/256UL/(255-100))// 100Hz
void TIMER0_Init(void);
void low_priority interrupt lowISR(void);
void high_priority interrupt highISR(void);
volatile uint8_t timer10ms;
int cnt;
int main(void)
{
TIMER0_Init();
USART_Init();
INTCONbits.GIEL = 1;//enable low level interrupts
INTCONbits.GIEH = 1;//enable all interrupts ( ei();)
while(true)
{
if(!timer10ms)
{
cnt++;
USART_BufferTransmit_P("Frame count: ");
USART_IntegerTransmit(cnt);
USART_BufferTransmit_P("\r\n");
USART_BufferTransmit_P("*PIC18F4550 fully interrupt driven USART *\r\n");
USART_BufferTransmit_P("* Connection params: 19200 8N1 *\r\n");
USART_BufferTransmit_P("* High priority interrupt used! *\r\n");
USART_BufferTransmit_P("* *\r\n");
timer10ms = 100;
}
}
}
void TIMER0_Init(void)
{
T0CON = (_T0CON_TMR0ON_MASK|_T0CON_T08BIT_MASK|_T0CON_T0PS2_MASK|
_T0CON_T0PS1_MASK|_T0CON_T0PS0_MASK);
INTCON2 &= ~_INTCON2_TMR0IP_MASK;//low priority for TIMER 0
RCON |= _RCON_IPEN_MASK;//interrupt priorities enabled
INTCON |= _INTCON_TMR0IE_MASK;//enable tmr0 interrupt
}
void low_priority interrupt lowISR(void)
{
if(INTCONbits.TMR0IE)
{
if(INTCONbits.TMR0IF)
{
TMR0 = TMR0_RELOAD;//100Hz reload
if(timer10ms) timer10ms--;
INTCONbits.TMR0IF = 0;//flag reset
}
}
}
void high_priority interrupt highISR(void)
{
if(PIE1bits.RC1IE && PIR1bits.RC1IF)
{
USART_Rx();
}
else if(PIE1bits.TX1IE && PIR1bits.TX1IF)
{
USART_Tx();
}
}
Oraz kompletny projekt:
Pozdrawiam.