5.2 Описание алгоритмов обработки данных
Алгоритм обработки данных разделяется на три части: функцию инициализации P1, процедуру обработки прерывания ISR1 и процедуру обработки прерывания ISR2 (см. рисунок 5.1).
5.2.1 Функция инициализации PI
Шаг 1. Инициализация универсального асинхронного приемо-передатчика в режиме UART.
Шаг 2. Инициализация универсального коммуникационного интерфейса в режиме UART.
Шаг 2. Инициализация контроллера прямого доступа к памяти.
Шаг 3. Инициализация контроллера прерываний.
Шаг 4. Настройка входов-выходов порта P7 для управления линией арбитража.
Шаг 5. Инициализация обработки прерываний процедурой ISR1.
Шаг 6. Инициализация обработки прерываний процедурой ISR2.
5.2.2 Процедура обработки прерываний ISR1
Шаг 1. Проверка флага готовности обработки принятых данных.
Шаг 2. Передача данных в буфер принятых данных.
Шаг 3. Возврат из прерывания.
5.2.3 Процедура обработки прерываний ISR2
Шаг 1. Проверка флага готовности приемника
Шаг 2. Выставление на линию арбитража сигнала о занятости линии
Шаг 3. Возврат из прерывания.
5.3 Результат работы программы
При запуске программы устройство тут же начинает передачу тестового слова, записав его в буфер передающихся данных msg_out. Первый канал прямого доступа в память перемещает первый символ слова, записав его код в ASCI кодировке, в буфер передатчика UCA0TXBUF.
Затем происходит передача данных через приемо-передатчик L9648.При помощи второго канала прямого доступа в память значение регистра приемника RXBUF1 перемещается в регистр передатчика TXBUF1,отправляясь назад к UCA0RXBUF.
В конечном итоге прерывание ISR1 записывает принятый байт в буфер приема данных msg_in, инкрементируя номер передаваемого бита index. В дальнейшей итерации передачи в буфер передатчика UCA0TXBUF запишется уже следующий символ готовый к передаче.
На рисунках 5 – 6 представлены результаты работы программы.
![]() ![]() |
Заключение
В рамках данной курсовой работы было разработано устройство приема и передачи данных на основе приемопередатчика L9637D013TR и микроконтроллера MSP430FG4618. Были реализованы функции передачи и приема строки символов различной длины.
В ходе написания курсовой работы были изучены:
- архитектура микроконтроллера MSP430FG4618;
- принцип работы приемо-передатчиков с интерфейсом «K-L line»;
- принцип работы контроллера прямого доступа в память;
- принцип работы контроллера прерываний;
- среда программирования Code Composer Studio™;
- среда моделирования CadenceTM Orcad PSpice®.
Список литературы
[1] Интегральная микросхема к1055хв8р - двунаправленный последовательный интерфейс шины «k-line»: [Публикация]. Режим доступа: http://fetmag.mrsu.ru/2009-3/pdf/IC_K1055XB8P.pdf. – Дата обращения: 20.09.2015.
[2] MSP430x461x. Mixed Signal Microcontroller. – Texas Instruments, 2009. – 95 p.
[3] Кеоун, Дж. OrCAD Pspice. Анализ электрических цепей. – М.: ДСК Пресс, 2008. – 629 с.
[4] Семейство микроконтроллеров MSP430x4xx. Руководство пользователя / Пер. с англ. – М. : ЗАО Компел, 2005. – 416 с.
Приложение А
Наладочная программа main.c
#include <msp430.h>
#include <stdio.h>
void main(void) {
static unsigned char TXdat=93;
char RXdat;
RXdat=0;
static unsigned char TX2dat=199;
char RX2dat;
RX2dat=0;
volatile unsigned int go;
go=1;
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
P7SEL|=0x00;
P7DIR |=BIT1;
P4SEL |=0x03; // P4.1,0 => UTXD1, URXD1
ME2 |= UTXE1 + URXE1; // Enable USART (ENABLE RECEIVE AND TRANSMIT)
U1CTL |= CHAR + SWRST; // CHAR = LENGTH OF MESSAGE; SWRST = RESET
U1TCTL |= SSEL0; // SOURCE SELECT
U1BR0 = 24, U1BR1 =4; // RATE CONTROL REGISTER 0,1
U1MCTL = 0x4A; // MODULATION CONTROL
U1CTL &= ~SWRST; // RESET
IE2 |= URXIE1; // ENABLE INTERUPT FOR RECEIVER
P2SEL |=BIT4+BIT5; // P2.4,5 => UTXD1, URXD1
UCA0CTL1 |=UCSWRST;
UCA0CTL1 |= UCSSEL_1; // SOURCE SELECT ACLK
UCA0BR0 = 24, UCA0BR1 =4; // RATE CONTROL REGISTER 0,1
UCA0MCTL = 0x4A; // MODULATION CONTROL
UCA0RXBUF=0;
UCA0CTL1 &=~UCSWRST; // RESET
IE2 |= UCA0RXIE ; // ENABLE INTERUPT FOR RECEIVER
while(go){
P7OUT=1;
while(!(IFG2&UTXIFG1)){
TXBUF1=TXdat;
RXdat = UCA0RXBUF;
}
if(TXBUF1=UCA0RXBUF)
go = 0;
}
go=1;
while(go){
P7OUT=0;
while((IFG2&UCA0TXIFG)){
UCA0TXBUF=TX2dat;
RX2dat = RXBUF1;
}
if(RXBUF1=UCA0TXBUF)
go = 0;
}
}
Приложение B
Программа main.c
#include <msp430.h>
#define SMCLK 1048576UL
void Init_USCI_A0_UART(void)
{
P2DIR |= (1 << 4);
P2DIR &= ~(1 << 5);
P2SEL |= (1 << 4) | (1 << 5);
UCA0CTL1 = UCSWRST;
UCA0CTL1 |= UCSSEL_2;
UCA0CTL0 = 0;
UCA0CTL1 |= UCSSEL_1; // SOURCE SELECT ACLK
UCA0BR0 = 24, UCA0BR1 =4; // RATE CONTROL REGISTER 0,1
UCA0MCTL = 0x4A; // MODULATION CONTROL
UCA0CTL1 &= ~UCSWRST; // Запуск UART
IE2 |= UCA0RXIE; // Разрешить прерывание по приему
}
/*
* Глобальные переменные для использования в обработчике прерывания
*/
volatile char *RX_Buffer;
unsigned int RX_Len;
/*
* Обработчик прерывания
*/
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
static int index = 0;
while (!(IFG2 & UCA0TXIFG));
P7OUT &= ~(1 << 1);
RX_Buffer[index] = UCA0RXBUF;
index++;
if (index >= RX_Len)
index = 0; //Повторение передачи
}
/*
* Инициализация USCI_A0 в режиме UART
*/
void Init_USART1(void)
{
P4DIR |= (1 << 0);
P4DIR &= ~(1 << 1);
P4SEL |= (1 << 0) | (1 << 1);
U1CTL = SWRST;
U1CTL |= CHAR;
U1TCTL |= SSEL0; // SOURCE SELECT
U1BR0 = 24, U1BR1 =4; // RATE CONTROL REGISTER 0,1
U1MCTL = 0x4A; // MODULATION CONTROL
ME2 = UTXE1 | URXE1;
U1CTL &= ~SWRST;
/*
Прерывание по приему должно быть выключено, иначе не будет запущена
DMA передача, т.к. не сработает триггер передачи по флагу
*/
IE2 |= UTXIE1;
P7DIR |= 1 << 1;
P7OUT |= (1 << 1);
}
#pragma vector=USART1TX_VECTOR
__interrupt void USART1TX_ISR (void)
{
if (IFG2 & UTXIFG1) { // Передатчик пуст
P7OUT |= (1 << 1); // Li в 1
}
}
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR (void)
{
switch(__even_in_range(DMAIV, 16)){
case 0:
break;
case 2: // Прерывание DMA канала #0
break;
case 4: // Прерывание DMA канала #1
break;
case 6: // Прерывание DMA канала #2
break;
default: break;
}
}
void Init_DMA_Channel0_Bufffer_to_USCIA0(const char *src_addr, unsigned int length)
{
DMACTL0 = 0x4 << 0; // Запуск от UCA0TXIFG
DMACTL1 = ENNMI; // Разрешение общего прерывания
/*
* Найстройка DMA0CTL
* По умолчанию одиночная передача и постоянный адрес получателя
* (т.к. периферия)
*/
DMA0CTL = 0x00;
DMA0CTL |= (3 << 8); // Разрешение инкрементирования адреса источника (буфер)
DMA0CTL |= (1 << 5); // Триггер по высокому уровню
DMA0CTL |= DMADSTBYTE | DMASRCBYTE; // Размер получателя - байт, размер отправителя - байт
DMA0CTL |= DMADT_5; // Циклическая передача, т.е. по завершении передачи последнего байта DMA продолжит передачу вновь с первого символа
DMA0SZ = length; // Кол-во передаваемых данных
DMA0CTL |= DMAIE;
DMA0SA = (char *)src_addr;
DMA0DA = (unsignedint *)&UCA0TXBUF;
}
void DMA_Channel0_Start(void)
{
DMA0CTL |= DMAEN; // Включение канала DMA
}
void Init_DMA_Channel1_USART1_RX_to_TX(char *dst_addr, unsigned int length)
{
RX_Buffer = dst_addr;
RX_Len = length;
DMACTL0 |= 0x9 << 4; // Запуск от URXIFG1
DMACTL1 |= ENNMI; // Разрешение общего прерывания
/*
* Найстройка DMA1CTL
* По умолчанию одиночная передача, постоянный адрес получателя и
* отправителя (т.к. периферия)
*/
DMA1CTL = 0x00;
DMA1CTL &= ~(1 << 5); // Триггер по переднему фронту, т.е. по приему байта
DMA1CTL |= DMADSTBYTE | DMASRCBYTE; // Размер получателя - байт, размер отправителя - байт
DMA1CTL |= DMAIE; // Разрешение прерывания канала 1
DMA1SA = (unsignedint *)&RXBUF1; // Адрес источника - приемник USART1
DMA1DA = (unsignedint *)&TXBUF1; // Адрес получателя - сдвиговый регистр передатчика USART1
DMA1SZ = 65535; // Передача максимального кол-ва байт
}
void DMA_Channel1_Start(void)
{
DMA1CTL |= DMAEN; // Включает передачу
}
/*******************************************************************************
*
* Глобальные функции
*
*******************************************************************************/
int main(void)
{
const char msg_out[] = {"Hello"}; // Тестовый буфер для передачи сообщения через DMA
char msg_in[sizeof msg_out]; // Буфер для приема через DMA, длина буфера = размеру исходного буфера
WDTCTL = WDTPW + WDTHOLD; // Останов сторожевого таймера
Init_USART1();
Init_USCI_A0_UART();
Init_DMA_Channel0_Bufffer_to_USCIA0(msg_out, sizeof msg_out);
Init_DMA_Channel1_USART1_RX_to_TX(msg_in, sizeof msg_in);
DMA_Channel0_Start();
DMA_Channel1_Start();
__bis_SR_register(GIE | CPUOFF);
while(1) {
__no_operation();
}
}