Jump to content

    

Recommended Posts

Добрый день уважаемые форумчане. В моем проекте два 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;
}

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

Share this post


Link to post
Share on other sites

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

Edited by shumerok

Share this post


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

 

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

Share this post


Link to post
Share on other sites
У меня выход из прерывания не происходит, пока буфер не заполнится

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

Share this post


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

 

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

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

Share this post


Link to post
Share on other sites

Побайтный прием организовал. Но вылезла другая проблема. В дебаге и через 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;
}

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

Share this post


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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this