اطلاعیه

Collapse
No announcement yet.

هنگ کردن میکرو پس از دریافت از UART

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    هنگ کردن میکرو پس از دریافت از UART

    سلام,

    دوستان یک مشکلی دارم با میکرو. اول یک توضیح کلی راجع به سیستمم بدم.
    این سیستم رو برای کار با یکی از شبکه های داخلی خودرو (شبکه VAN) که در خودرو های نسل قبل پژو استفاده میشد ساختم.
    طرز کار به این صورت هست که میکرو از طریق IC اینترفیس که با پروتکل SPI کار میکنه هرچی که روی شبکه بیاد رو میخونه و به میکرو میده و میکرو هم به UART ارسالش میکنه.
    اگر هم من بخوام چیزی بفرستم روی شبکه میکرو اطلاعات رو از UART میگیره و از طریق چیپ اینترفیس میفرسته روی شبکه.
    تا اینجا همه چیز درسته.

    مشکل اینجاست وقتی میخوام چیزی روی شبکه بفرستم برای مثال میخوام هر 100 میلی ثانیه یک پکت بفرستم پس از ارسال چند پکت میکرو کلا هنگ میکنه و باید ریستش کنم. این که بعد از چند پکت یا بعد از چند ثانیه هنگ کنه هم کاملا متغییر هست.
    هنگ کردن هم به این صورت هست که وقتی از Logic Analyzer اطلاعات رو میبینم اخرین پکتی که از طریق SPI میره به چیپ اشتباه هست اما توابع درست اجرا میشه و الگوریتم ارسال کاملا اجرا میشه. تنها مشکل بخش اطلاعاتی هست که از طریق UART گرفته میشه که داخل میکرو کلا عوض میشه و بعدش میکرو هنگ میکنه و دیگه به هیچ IRQ ای جواب نمیده.

    کد های قسمت UART و SSP رو هم قرار میدم. کد هارو خودم ننوشتم اما تغییرات زیادی دادم توش. میکرو هم LPC2368 هست.

    SSP:

    کد:
    #include <LPC23XX.H> 
    #include "sspn.h"
    
    void SSP0Init(void)
    {
    	int i;
    	int Dummy = Dummy;
    	PINSEL0 |= 0x80000000;
    	PINSEL1 |= 0x00000028;
    	FIO0DIR |= SSP0_SEL;	/* SSEL is output */
     	FIO0SET = SSP0_SEL;
    	SSP0CR0 = 0xC7 | (0x0B << 8); //SPI Mode
    	SSP0CR1 = 0x00000002;
    	
    	for ( i = 0; i < 8; i++ )
     	{
    		Dummy = SSP0DR;		
     	}
    }
    
    void SSP0Send(unsigned int data)
    {
    	int Dummy = Dummy;
    	while (!(SSP0SR & 0x02));
    	
    		SSP0DR = data;
    	
    	while (!(SSP0SR & 0x04));
    	
    		Dummy = SSP0DR;		
    	
    }
    
    int SSP0Receive(void)
    {
    	int Data = Data;
    	while (!(SSP0SR & 0x02));
    	
    	SSP0DR = 0xFF;	
    	while (!(SSP0SR & 0x04));
    	
    	Data = SSP0DR;			
    	return Data;
    }
    
    void SetSS(void)
    {
    	FIO0SET = SSP0_SEL;
    }
    
    void ClrSS(void)
    {
    	FIO0CLR = SSP0_SEL;
    }
    UART:

    کد:
    /*----------------------------------------------------------------------------
     *   Name:  sio.c
     *   Purpose: Serial Communication Routines for Philips LPC2300
     *   Version: V1.0
     *----------------------------------------------------------------------------
     *   This file is part of the uVision/ARM development tools.
     *   This software may only be used under the terms of a valid, current,
     *   end user licence from KEIL for a compatible version of KEIL software
     *   development tools. Nothing else gives you the right to use it.
     *
     *   Copyright (c) 2005-2007 Keil Software.
     *---------------------------------------------------------------------------*/
    
    #include <LPC23XX.H>                 /* LPC23xx definitions */
    #include <string.h>
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "van.h"
    #include "tss463.h"
    #include "sio.h"
    #include "uart.h"
    
    int _tmpu;
    
    void sio_irq (void) __irq {
    	char rec[60] = {0};
     volatile char dummy;
     volatile char IIR;
    	int i;
    	
     /*------------------------------------------------
     Repeat while there is at least one interrupt source.
     ------------------------------------------------*/
     while (((IIR = U0IIR) & 0x01) == 0) {
       switch (IIR & 0x0E) {
        case 0x06: /* Receive Line Status */
         dummy = U0LSR; /* Just clear the interrupt source */
         break;
    
        case 0x04: /* Receive Data Available */
        case 0x0C: /* Character Time-Out */
    				 
    				 
    				 while ((VICIRQStatus << 17));
    				 			 
    				 VICIntEnClr = 1 << 17;
    				 i = 0;
    				 
    				 while (1)
    				 {
    					 while(!( U0LSR & 1));
    					 start:
    					 _tmpu = U0RBR;
    					 U0FCR = 0x02;
    					 if (_tmpu == 0x0A)
    					 {
    						 i++;
    						 rec[i] = '\0';
    						 U0FCR = 0x06;
    						 process(rec);
    						 break;
    					 }
    					 if (_tmpu == 0x0D)
    					 {
    						goto start;
    					 }
    					 rec[i] = _tmpu;
    					 i++;
    				 }
    				 
         break;
    
        case 0x02: /* THRE Interrupt */
    
         break;
    
        default:
         break;
       }
     }
     VICVectAddr = 0; /* Acknowledge Interrupt */
    }
    
    /*------------------------------------------------------------------------------
    ------------------------------------------------------------------------------*/
    void com_initialize (void) {
     volatile char dummy;
     /*------------------------------------------------
     Setup serial port registers.
     ------------------------------------------------*/
     PINSEL0 |= 0x50;
    
     U0LCR = 0x03;      /* 8 bits, no Parity, 1 Stop bit */
     U0IER = 0;        /* Disable UART0 Interrupts */
    
     VICVectAddr6 = (unsigned long)sio_irq;
     VICVectCntl6 = 1;    /* use it for UART0 Interrupt */
     VICIntEnable = 1 << 6;  /* Enable UART0 Interrupt */
    	
     U0LCR |= 0x80;      /* Set DLAB */
     U0DLL = 0x0A;
     U0DLM = 0x00;
     U0FDR = 0x1 | (0x3 << 4);
     U0LCR &= ~0x80; 
    
    
     dummy = U0IIR;  /* Read IrqID - Required to Get Interrupts Started */
     U0IER = 1;    /* Enable UART0 RX */
    }
    
    /*------------------------------------------------------------------------------
    ------------------------------------------------------------------------------*/
    int com_putchar (int c) {
    
    	while (!(U0LSR & 0x20));
     return (U0THR = c);
    
    }
    
    /*------------------------------------------------------------------------------
    ------------------------------------------------------------------------------*/
    int com_getchar (void) {
    return 0;
    }
    
    /*------------------------------------------------------------------------------
    ------------------------------------------------------------------------------*/
    تشکر.

    #2
    پاسخ : هنگ کردن میکرو پس از دریافت از UART

    آقا ما بالأخره نفهمیدیم میکرو موقع دریافت UART هنگ می کنه، یا دریافت SPI؟! یا ارسالِ UART یا ارسال SPI؟!؟!
    به هر حال، طبق تجربه چند تا نکته در مورد هنگ کردن و وقفه و اینا به شما می گم شاید مفید واقع بشه:
    توی توابع وقفه تابعِ دیگری رو فراخوانی نکنید.
    توی توابع وقفه متغیرهای زیاد و حجیم تعریف نکنید.
    حتی الامکان سعی کنید طوری سیستم رو طراحی کنید که وقفه در وقفه نداشته باشید.
    تو وقفه دریافتِ پورت سریال یا هر چیزِ دیگه، فقط بایتِ دریافتی رو بریزید توی یه بافر، و اندیسِ بافر رو اضافه کنید. همین. یک خط کد!
    کد:
    buff[index++]=THR;
    بعدش، توی حلقه اصلی برنامه (توی main) یه حرکتی بزنید و بافر رو پردازش کنید و بسته ها رو مرتب کنید و اطلاعات رو ازش در بیارید.
    هنگ کردن میکرو می تونه به علت سرریزِ پشته باشه، یا رجوع به آدرس نامعتبر از حافظه که بیشتر در مورد کار با آرایه ها در توابع (و وقفه ها) رخ میده. سعی کنید متغیرهاتون رو سراسری تعریف کنید و در مورد اندیس آرایه ها بسیار بسیار دقت کنید.
    فعلاً همینا.
    موفق باشید
    بیایید با Google آشتی کنیم!

    دیدگاه


      #3
      پاسخ : هنگ کردن میکرو پس از دریافت از UART

      سلام دوستان بنظرتون چرا برنامه من پس از دریافت وقفهuart وارد کتابخونه uart میشه و همونجا بلاک میشه :sad:؟محلی که برنامه قفل میشه رو توی این عکس مشخص کردم
      http://uupload.ir/files/mn2_1212.jpg

      دیدگاه


        #4
        پاسخ : هنگ کردن میکرو پس از دریافت از UART

        آیا تو زیربرنامه وقفه اینتراپت رو پاک میکنید؟!

        دیدگاه


          #5
          پاسخ : هنگ کردن میکرو پس از دریافت از UART

          نوشته اصلی توسط reza javahery
          آیا تو زیربرنامه وقفه اینتراپت رو پاک میکنید؟!
          نه چون داخل دستورات cmsis برای uartچنین دستوری وجود نداره
          حالا بازم عکس از زیر روال وقفه گذاشتم
          ممنون
          http://uupload.ir/files/i820_100.jpg

          دیدگاه

          لطفا صبر کنید...
          X