|
|
  |
Microblaze+UART |
|
|
|
Apr 28 2018, 08:09
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 13-11-09
Пользователь №: 53 601

|
Добрый день уважаемые форумчане. В моем проекте два UARTа. Один работает по прерыванию с внешним модулем, второй только в режиме передачи выводит информацию на терминал ноута. Внешний модуль ESP8266. Я передаю ему команду "AT" и должен получить в ответ "OK". А я получаю ту же команду, что отправляю. Хотя ESP точно не может отправить обратно ту же команду. Получается, что в приемный буфер попадают данные из передающего. Проект собран в ISE. Код привожу ниже: CODE #include <stdio.h> #include "xparameters.h" #include "xil_cache.h" #include "xbasic_types.h" #include "xgpio.h" #include "xil_printf.h" #include "xuartlite.h" #include "xintc.h" #include "xil_exception.h" #include "xtmrctr.h"
#define UART_ESP XPAR_UARTLITE_1_DEVICE_ID #define UART_RS232 XPAR_UARTLITE_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define UARTLITE_INT_IRQ_ID XPAR_INTC_0_UARTLITE_1_VEC_ID #define LED_ID XPAR_GPIO_0_DEVICE_ID #define TMR_ID XPAR_TMRCTR_0_DEVICE_ID
#define TEST_BUFFER_SIZE 6 // Function prototypes
void SendHandler(void *CallBackRef, unsigned int EventData); void RecvHandler(void *CallBackRef, unsigned int EventData); int SetupInterruptSystem(XUartLite *UartLitePtr); void delay_us(Xuint32 Vremay); void delay_ms(Xuint32 Vremay);
XUartLite UartLiteESP; XUartLite UartLiteRS; XIntc InterruptController; XGpio LedTest; XTmrCtr Time;
u8 SendBuffer[6] = {65, 84, 92, 114, 92, 110}; u8 ReceiveBuffer[TEST_BUFFER_SIZE];
u8 TotalReceivedCount; u8 TotalSentCount;
int main() { int Status; int Index;
XTmrCtr_Initialize(&Time, TMR_ID); XTmrCtr_SetOptions(&Time, 0, XTC_DOWN_COUNT_OPTION);
delay_ms(1000); delay_ms(1000);
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
ReceiveBuffer[Index] = 0; }
Status = XUartLite_Initialize(&UartLiteESP,UART_ESP); if(Status != XST_SUCCESS){ return XST_FAILURE; } Status = XUartLite_Initialize(&UartLiteRS,UART_RS232); if(Status == XST_SUCCESS) { print("UART Init OK\r\n"); }
Status = XGpio_Initialize(&LedTest, LED_ID); if (Status == XST_SUCCESS) { print(" Initialize GPIO OK\r\n"); }
Status = SetupInterruptSystem(&UartLiteESP); if (Status == XST_SUCCESS) { print("Setup INT OK\r\n"); } XUartLite_SetSendHandler(&UartLiteESP, SendHandler, &UartLiteESP); XUartLite_SetRecvHandler(&UartLiteESP, RecvHandler, &UartLiteESP); //XUartLite_ResetFifos(&UartLiteESP); XUartLite_Recv(&UartLiteESP, ReceiveBuffer, TEST_BUFFER_SIZE); XUartLite_EnableInterrupt(&UartLiteESP); XUartLite_Send(&UartLiteESP, SendBuffer, 6); delay_ms(1); if (TotalSentCount == 6){ TotalSentCount = 0; print("Send OK\r\n"); }
while(1){
if (TotalReceivedCount != 0) { print("Recive"); for (Index = 0; Index < TotalReceivedCount; Index++) {
xil_printf(" %c", ReceiveBuffer[Index]); } TotalReceivedCount = 0; } }
return(0); }
void SendHandler(void *CallBackRef, unsigned int EventData) { TotalSentCount = EventData; XUartLite_ResetFifos(&UartLiteESP); }
void RecvHandler(void *CallBackRef, unsigned int EventData) { TotalReceivedCount = EventData; XUartLite_Recv(&UartLiteESP, ReceiveBuffer, TEST_BUFFER_SIZE);
}
void delay_ms(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50000); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); }
void delay_us(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); }
int SetupInterruptSystem(XUartLite *UartLitePtr) {
int Status;
/* * Initialize the interrupt controller driver so that it is ready to * use. */ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Connect a device driver handler that will be called when an interrupt * for the device occurs, the device driver handler performs the * specific interrupt processing for the device. */ Status = XIntc_Connect(&InterruptController, UARTLITE_INT_IRQ_ID, (XInterruptHandler)XUartLite_InterruptHandler, (void*)UartLitePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Start the interrupt controller such that interrupts are enabled for * all devices that cause interrupts, specific real mode so that * the UartLite can cause interrupts through the interrupt controller. */ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Enable the interrupt for the UartLite device. */ XIntc_Enable(&InterruptController, UARTLITE_INT_IRQ_ID);
/* * Initialize the exception table. */ Xil_ExceptionInit();
/* * Register the interrupt controller handler with the exception table. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &InterruptController);
/* * Enable exceptions. */ Xil_ExceptionEnable();
return XST_SUCCESS; }
Помогите кто чем может).
|
|
|
|
|
Apr 28 2018, 10:12
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 13-11-09
Пользователь №: 53 601

|
Прошу прощения. Сам дурак. Не те символы в ASCII отправлял. Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится.
Сообщение отредактировал shumerok - Apr 28 2018, 10:20
|
|
|
|
|
Apr 28 2018, 11:32
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 13-11-09
Пользователь №: 53 601

|
Цитата(alexadmin @ Apr 28 2018, 14:11)  Принимать по одному байту, складывать в буфер, выходить из прерывания, ждать следующего прерывания. Спасибо попробую так. Цитата(AVR @ Apr 28 2018, 14:15)  Я уже давно с микробом не возился, могу не помнить что-то, но где в RecvHandler сброс флага прерывания? Вроде это руками надо делать, разве нет? Или оно прям виснет в этом обработчике? Так оно и должно там сидеть пока все 6 байт не скушает. Надо по 1 принимать, как правильно выше написали. Виснет пока не вычитает буфер. Если принимать по одному, то действительно надо сбрасывать флаг.
|
|
|
|
|
May 4 2018, 12:01
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 13-11-09
Пользователь №: 53 601

|
Побайтный прием организовал. Но вылезла другая проблема. В дебаге и через RUN все работает. Зашиваю релиз - не работает. Процессор в релизе крутится, но данные не принимает. Новый код: CODE /* * code.c * * Created on: 04.12.2017 * Author: shumer */
#include <stdio.h> #include "xparameters.h" #include "xil_cache.h" #include "xbasic_types.h"
#include "xtmrctr.h" #include "xuartlite.h" #include "xintc.h" #include "xil_exception.h"
#define UARTRS_ID XPAR_UARTLITE_1_DEVICE_ID #define UARTRS_ESP XPAR_UARTLITE_2_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define UARTLITE_INT_IRQ_ID XPAR_INTC_0_UARTLITE_2_VEC_ID #define TMR_ID XPAR_TMRCTR_0_DEVICE_ID
#define A 65 #define T 84 #define PLUS 43 #define C 67 #define I 73 #define P 80 #define M 77 #define U 85 #define X 88 #define S 83 #define E 69 #define R 82 #define V 86 #define RAVNO 61 #define ZPT 44
#define TEST_BUFFER_SIZE 1 // Function prototypes
void SendHandler(void *CallBackRef, unsigned int EventData);
void RecvHandler(void *CallBackRef, unsigned int EventData);
int SetupInterruptSystem(XUartLite *UartLitePtr);
void delay_us(Xuint32 Vremay); void delay_ms(Xuint32 Vremay);
XUartLite UartLiteESP; XUartLite UartLiteRS; XIntc InterruptController;
XTmrCtr Time;
u8 SendBuffer[4] = {A,T,13,10}; u8 ReceiveBuffer[TEST_BUFFER_SIZE] = {0}; u8 SendBufferRS[6] = {S,E,R,V,13,10};
static volatile int TotalReceivedCount; static volatile int TotalSentCount; int flag = 0; unsigned int RecvByte; unsigned int SendByte; int Count = 0;
int main() { int Status; int Index; int flagSend = 0;
XTmrCtr_Initialize(&Time, TMR_ID); XTmrCtr_SetOptions(&Time, 0, XTC_DOWN_COUNT_OPTION);
Status = XUartLite_Initialize(&UartLiteESP,UARTRS_ESP); if(Status != XST_SUCCESS){ return XST_FAILURE; }
Status = XUartLite_Initialize(&UartLiteRS,UARTRS_ID); if(Status != XST_SUCCESS){ return XST_FAILURE; }
Status = SetupInterruptSystem(&UartLiteESP); if (Status != XST_SUCCESS) { return XST_FAILURE; }
XUartLite_SetSendHandler(&UartLiteESP, SendHandler, &UartLiteESP); XUartLite_SetRecvHandler(&UartLiteESP, RecvHandler, &UartLiteESP); XUartLite_EnableInterrupt(&UartLiteESP); delay_ms(1000); XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID);
Index = 0;
XUartLite_Send(&UartLiteESP, SendBuffer, 4);
while(1){
if(flag == 1){
SendBufferRS[0] = ReceiveBuffer[0]; XUartLite_Send(&UartLiteRS, SendBufferRS, 1);
/*if(flagSend != 1){ ++Index; } else{ Index = 0; flagSend = 0; }*/ TotalReceivedCount = 0; flag = 0;
}
}
return(0); }
void SendHandler(void *CallBackRef, unsigned int EventData) { TotalSentCount = EventData; XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID);
}
void RecvHandler(void *CallBackRef, unsigned int EventData) { TotalReceivedCount = EventData; flag = 1; //++Count; XUartLite_Recv(&UartLiteESP, ReceiveBuffer, 1); XIntc_Acknowledge(&InterruptController, UARTLITE_INT_IRQ_ID);
}
void delay_ms(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50000); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); }
void delay_us(Xuint32 Vremay) { XTmrCtr_SetResetValue(&Time, 0, Vremay * 50); XTmrCtr_Start(&Time, 0); while(!(XTmrCtr_IsExpired(&Time, 0))){} XTmrCtr_Stop(&Time, 0); }
int SetupInterruptSystem(XUartLite *UartLitePtr) {
int Status;
/* * Initialize the interrupt controller driver so that it is ready to * use. */ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Connect a device driver handler that will be called when an interrupt * for the device occurs, the device driver handler performs the * specific interrupt processing for the device. */ Status = XIntc_Connect(&InterruptController, UARTLITE_INT_IRQ_ID, (XInterruptHandler)XUartLite_InterruptHandler, (void*)UartLitePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Start the interrupt controller such that interrupts are enabled for * all devices that cause interrupts, specific real mode so that * the UartLite can cause interrupts through the interrupt controller. */ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE); if (Status != XST_SUCCESS) { return XST_FAILURE; }
/* * Enable the interrupt for the UartLite device. */ XIntc_Enable(&InterruptController, UARTLITE_INT_IRQ_ID);
/* * Initialize the exception table. */ Xil_ExceptionInit();
/* * Register the interrupt controller handler with the exception table. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &InterruptController);
/* * Enable exceptions. */ Xil_ExceptionEnable();
return XST_SUCCESS; }
Подозреваю, что есть разница в скорости работы проца в дебаге и релизе. Может кто сталкивался с подобным? Буду благодарен за любую помощь.
|
|
|
|
|
May 17 2018, 13:04
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 13-11-09
Пользователь №: 53 601

|
Проблема решилась вводом задержки в 1мкс в цикле опроса флага прерывания.
|
|
|
|
|
May 23 2018, 11:03
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 28-08-13
Из: SPb
Пользователь №: 78 086

|
Цитата(shumerok @ Apr 28 2018, 13:12)  Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится. Еще добавлю, что можно почитать про "кольцевой буфер"
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|