Перейти к содержанию
    

Microblaze+UART

Добрый день уважаемые форумчане. В моем проекте два UARTа. Один работает по прерыванию с внешним модулем, второй только в режиме передачи выводит информацию на терминал ноута. Внешний модуль ESP8266. Я передаю ему команду "AT" и должен получить в ответ "OK". А я получаю ту же команду, что отправляю. Хотя ESP точно не может отправить обратно ту же команду. Получается, что в приемный буфер попадают данные из передающего. Проект собран в ISE. Код привожу ниже:

#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;
}

Помогите кто чем может).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения. Сам дурак. Не те символы в ASCII отправлял. Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится.

Изменено пользователем shumerok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения. Сам дурак. Не те символы в ASCII отправлял. Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится.

 

Принимать по одному байту, складывать в буфер, выходить из прерывания, ждать следующего прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня выход из прерывания не происходит, пока буфер не заполнится

Я уже давно с микробом не возился, могу не помнить что-то, но где в RecvHandler сброс флага прерывания? Вроде это руками надо делать, разве нет? Или оно прям виснет в этом обработчике? Так оно и должно там сидеть пока все 6 байт не скушает. Надо по 1 принимать, как правильно выше написали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Принимать по одному байту, складывать в буфер, выходить из прерывания, ждать следующего прерывания.
Спасибо попробую так.

 

Я уже давно с микробом не возился, могу не помнить что-то, но где в RecvHandler сброс флага прерывания? Вроде это руками надо делать, разве нет? Или оно прям виснет в этом обработчике? Так оно и должно там сидеть пока все 6 байт не скушает. Надо по 1 принимать, как правильно выше написали.

Виснет пока не вычитает буфер. Если принимать по одному, то действительно надо сбрасывать флаг.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Побайтный прием организовал. Но вылезла другая проблема. В дебаге и через RUN все работает. Зашиваю релиз - не работает. Процессор в релизе крутится, но данные не принимает. Новый код:

/*
* 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;
}

Подозреваю, что есть разница в скорости работы проца в дебаге и релизе. Может кто сталкивался с подобным? Буду благодарен за любую помощь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть дополнительный вопрос: как в режиме прерывания принимать произвольное кол-во байт (неизвестно заранее кол-во). У меня выход из прерывания не происходит, пока буфер не заполнится.

Еще добавлю, что можно почитать про "кольцевой буфер"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...