Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
//uart0.c
#include < LPC22xx.H >
#include "bit_defines.h"
#include "settings.h"
#include "pins.h"
#include "timer0.h"//--------------------------------------------------------------------------------------------------------
// Constants to determine the ISR source
#define SOURCE_THRE 0x02
#define SOURCE_RX_TIMEOUT 0x0C
#define SOURCE_ERROR 0x06
#define SOURCE_RX 0x04
#define INTERRUPT_SOURCE_MASK 0x0F//Флаги
#define UART0_FLAG_TX_IN_PROGRESS 0x00
#define UART0_FLAG_TX_COMPLETE 0x01
#define UART0_FLAG_ERR 0x02//************************************
//Переменные
//************************************
volatile struct uart0_data
{
unsigned char rx_buf[UART0_RX_BUFFER_SIZE];
unsigned char tx_buf[UART0_TX_BUFFER_SIZE];
unsigned char rx_head;
unsigned char rx_tail;
unsigned char tx_head;
unsigned char tx_tail;
unsigned char flags;
}uart0;
//************************************
//Prototypes
//************************************
void UART0_Open(unsigned long baud);
void UART0_Buf_Clr(void);
void UART0_DisableReciveIRQ(void);
void UART0_EnableReciveIRQ(void);
unsigned char UART0_Receive(void);
void UART0_Transmit(unsigned char data);
void UART0_Sendstr(char *strbuf);
unsigned char UART0_DataInReceiveBuffer(void);
void UART0_Transmit_On(void);
void UART0_Transmit_Off(void);
unsigned char UART0_Check_Shift_Reg_Emty(void);
static void UART0_Handler(void) __irq;//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Инициализация UART0
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Open(unsigned long baud)
{
IO0CLR |= (1 << GL_BUS_DIR); //Включим RS485 на прием
IO0DIR |= (1 << GL_BUS_DIR);
// set port pins
PINSEL0 &= ~(3 << PINSEL0_P0_0);
PINSEL0 |= (PINSEL_FUNC_01 << PINSEL0_P0_0);PINSEL0 &= ~(3 << PINSEL0_P0_1);
PINSEL0 |= (PINSEL_FUNC_01 << PINSEL0_P0_1);// initialize the interrupt vector
VICIntSelect &= ~(1 << VIC_UART0);
VICVectAddr1 = (unsigned long)UART0_Handler;
VICVectCntl1 = (1 << VIC_CHNL_ENABLE_BIT) | VIC_UART0;
VICIntEnable |= (1 << VIC_UART0);
U0FCR = (1 << U0FCR_FIFO_Enable_BIT) | (1 << U0FCR_Tx_FIFO_Reset_BIT) | (1 << U0FCR_Rx_FIFO_Reset_BIT);// set the number of characters and other
U0LCR = (0x03 << U0LCR_Word_Length_Select_BIT);// set the baudrate
U0LCR |= (1 << U0LCR_Divisor_Latch_Access_Bit_BIT);
U0DLL = ((unsigned char)(PCLK/(baud*16)) & 0xff);
U0DLM = ((unsigned char)((PCLK/(baud*16)) >> 8)) & 0xff;
U0LCR &= ~(1 << U0LCR_Divisor_Latch_Access_Bit_BIT);
uart0.rx_tail = 0;
uart0.tx_tail = 0;
uart0.rx_head = 0;
uart0.tx_head = 0;//enable transive interrupt
U0IER |= (1 << U0IER_THRE_Interrupt_Enable_BIT) | (1<} //::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Очистка
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Buf_Clr(void)
{
uart0.rx_tail = 0;
uart0.tx_tail = 0;
uart0.rx_head = 0;
uart0.tx_head = 0;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Запрет приема
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_DisableReciveIRQ(void)
{
U0IER &= ~(1 << U0IER_RBR_Interrupt_Enable_BIT);
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Разрешение приема
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_EnableReciveIRQ(void)
{
unsigned char temp;
temp = U0LSR;
U0FCR = (1 << U0FCR_FIFO_Enable_BIT) | (1 << U0FCR_Tx_FIFO_Reset_BIT) | (1 << U0FCR_Rx_FIFO_Reset_BIT);
U0IER |= (1 << U0IER_RBR_Interrupt_Enable_BIT);
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Прием байта
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
unsigned char UART0_Receive(void)
{
unsigned char tmptail;
tmptail = uart0.rx_tail;
while (uart0.rx_head == tmptail);
tmptail = (uart0.rx_tail + 1) & UART0_RX_BUFFER_MASK;
uart0.rx_tail = tmptail;return uart0.rx_buf[tmptail];
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Передача байта
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Transmit(unsigned char data)
{
unsigned char tmphead;tmphead = (uart0.tx_head + 1) & UART0_TX_BUFFER_MASK;
while (tmphead == uart0.tx_tail);uart0.tx_buf[tmphead] = data;
uart0.tx_head = tmphead;
if((uart0.flags & (1 << UART0_FLAG_TX_IN_PROGRESS)) == 0)
{
uart0.flags |= (1 << UART0_FLAG_TX_IN_PROGRESS);
uart0.flags &= ~(1 << UART0_FLAG_TX_COMPLETE);
UART0_Transmit_On();
U0THR = uart0.tx_buf[++uart0.tx_tail];
}
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Передача строки
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Sendstr(char *strbuf)
{
while (*strbuf != 0) UART0_Transmit(*strbuf++);
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Старт передачи
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Transmit_On(void)
{
UART0_DisableReciveIRQ();
IO0SET |= (1 << GL_BUS_DIR); //Включим передатчик RS485
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Стоп передачи
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void UART0_Transmit_Off(void)
{
IO0CLR |= (1 << GL_BUS_DIR); //Отключим передатчик RS485
UART0_EnableReciveIRQ(); //Разрешим прием
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Проверка буфера
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
unsigned char UART0_DataInReceiveBuffer(void)
{
unsigned char tmptail;
tmptail = uart0.rx_tail;
return (uart0.rx_head != tmptail);
}//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Проверим - не опустел ли сдвиговый регистр
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
unsigned char UART0_Check_Shift_Reg_Emty(void)
{
if((uart0.flags & (1 << UART0_FLAG_TX_COMPLETE)) != 0)
{
if(U0LSR & (1 << U0LSR_TEMT_BIT))
{
uart0.flags &= ~(1 << UART0_FLAG_TX_COMPLETE);
return 1;
}
}
return 0;
}
//******************************************************************************************
//Обработчик прерывания UART0
//******************************************************************** **********************
static void UART0_Handler(void) __irq
{
volatile unsigned char data;
volatile unsigned char tmphead;
volatile unsigned char tmptail;switch((data = U0IIR) & INTERRUPT_SOURCE_MASK)
{
//Прием
case SOURCE_RX:
data = U0RBR;
if((uart0.flags & (1 << UART0_FLAG_TX_IN_PROGRESS)) == 0)
{
tmphead = (uart0.rx_head + 1) & UART0_RX_BUFFER_MASK;
uart0.rx_head = tmphead;
if(tmphead == uart0.rx_tail)
{
//ERROR! Receive buffer overflow
uart0.flags |= (1 << UART0_FLAG_ERR);
}
uart0.rx_buf[tmphead] = data;
// if((IO1PIN & (1 << SYS_GREEN_LED) == 0))SYS_GREEN_LED_OFF;
// else SYS_GREEN_LED_ON;
}
break;
//Прередача
case SOURCE_THRE:
tmptail = uart0.tx_tail;
if(uart0.tx_head != tmptail)
{
tmptail = (uart0.tx_tail + 1) & UART0_TX_BUFFER_MASK;
uart0.tx_tail = tmptail;
U0THR = uart0.tx_buf[tmptail];
// if((IO1PIN & (1 << SYS_GREEN_LED) == 0))SYS_GREEN_LED_OFF;
// else SYS_GREEN_LED_ON;
}
else
{
uart0.flags &= ~(1 << UART0_FLAG_TX_IN_PROGRESS);
uart0.flags |= (1 << UART0_FLAG_TX_COMPLETE);
//SYS_GREEN_LED_OFF;
}
break;//Таймаут приема
case SOURCE_RX_TIMEOUT:
data = U0RBR;
break;//Ошибка
case SOURCE_ERROR:
data = U0LSR;
break;//Хрень какая-то
default:
data = U0LSR;
data = U0RBR;
}VICVectAddr = 0;
}
//--------------------------------------------------------------------------------------------------------