haihai 发表于 2009-8-26 15:48:29

ucos 中中断程序的应用问题

各位大哥,小弟刚学UC,移植正确,编了一段简单的串口程序,如下:

#define Test1_GLOBALS
#include "D:\d\kaifabu\iccavr\ucos2_application\INCLUDES.H"


//******************************************************************************
// Constants
#define TaskStartPrio        10               
// Task-Prioritaeten
#define   UART_SENDENABLE()   { UCSR0B&=~(1<<RXEN0);UCSR0B&=~(1<<RXCIE0); UCSR0B|=(1<<TXEN0); UCSR0B|=(1<<TXCIE0); UCSR0B|=(1<<UDRIE0);PORTE|=(1<<2);}        
#define   UART_RECEIVERENABLE() { UCSR0B&=~(1<<TXEN0);UCSR0B|=(1<<RXEN0);UCSR0B|=(1<<RXCIE0); PORTE&=~(1<<2); }       

unsignedstatic   char    UartSend_ToHGTemp    ;
unsignedstatic   char    UartSend_ToHG1           ;
unsignedstatic   char    *Uart_send_ptr = UartSend_ToHG1 ;
unsignedstatic   char      UART_i=0x00;
//*****************************************************************************
// Variablen
OS_STK        Task1Stack;                // startup task stack
OS_STK        Task2Stack;       

//*****************************************************************************
// Prototypes
void Task1(void *data);
void uart0_init(void);
void   uart_collect (void)
   {
       unsignedchar*UartToHG_ptr_1=0x00;
           unsignedchar*UartToHG_ptr_k=UartSend_ToHG1;
          
          
          
           OS_ENTER_CRITICAL();
          UartToHG_ptr_1=UartToHG_ptr_k;
           *UartToHG_ptr_k=0x05; UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x01; UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x03 ;UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x00 ; UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x01 ; UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x00 ; UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x03 ; UartToHG_ptr_k++;
       
          
          OS_EXIT_CRITICAL() ;
        }
void main(void){
        OSInit();                // OS init

        OSTaskCreate(Task1,
                                //(void *)((unsigned char *)Uart_send_ptr),
                                (void *)(0),
                                &Task1Stack,
                                TaskStartPrio);
       
        //OSTaskCreate(Task3,
                                //(void *)(int)'b',
                                //&Task2Stack,
                                //TaskStartPrio+1);
        // init und start tick
       
        uart0_init();
        TC2_Init();       
        //DDRG |= 0x18; PORTG &=~(1<<PG3); PORTG &=~(1<<PG4);       
        //UART_SENDENABLE();
        OSStart();                // start multitasking

}

//*****************************************************************************
void Task1(void *data)
{
//        char c = (int)data;

          
        // Timer/Counter#2 Overflow and Comp init
          uart_collect ();
                for (;;)
                {
                data=data;
//            putchar(c);
                while(!(UCSR0A&0x20));
                UCSR0B|=(1<<TXEN0);
                PORTE|=(1<<2);
                UCSR0B|=(1<<UDRIE0);
                //SEI();
                // UCSR0A|=(1<<UDRE0);
                //UDR0 = *((unsigned char *)((void *)data));
//                PORTA = ~PORTA;
//                DDRA = 0xff;
                OSTimeDly (5);

        }
}
//void Task3(void *data){
//        char c = (int)data;
        //for (;;){
//            putchar(c);
                //while(!(UCSR0A&0x20));
                //UDR0 = 'b';
//                PORTA = ~PORTA;
//                DDRA = 0xff;
                //OSTimeDly (5);

        //}
//}

//..............................................................
//if the data register is empty ,load the data
//...............................................................
#pragmainterrupt_handler   dataD_empty:20
   void   dataD_empty(void)
       {
          
       
               OSIntEnter();
               
               
                UDR0 = *Uart_send_ptr;
                Uart_send_ptr++;
                UART_i++;
                if (UART_i>6)
                {
               UART_i=0;
               Uart_send_ptr = UartSend_ToHG1 ;
               }
               
                OSIntExit();
               
                return;
               
                        //storeglobal registers
                                             
    }
但是程序通过串口调试,只是05 不停的发,其他字节发不出,请问高手们是什么原因造成的呀?中断不可以用C直接写么?应该
注意些什么呢?谢谢。

mion 发表于 2009-8-26 16:57:56

UC中可以用C直接写!

haihai 发表于 2009-8-26 17:06:19

谢谢LS,那我上面的程序是什么问题呀?

mion 发表于 2009-8-26 17:17:16

不是中断的问题!可能是指针的问题!

haihai 发表于 2009-8-26 17:20:25

指针在UC中和在前后台中还有什么不同的地方么,谢谢

mion 发表于 2009-8-26 17:22:06

总中断打开没!

haihai 发表于 2009-8-26 17:25:22

我试了,while(!(UCSR0A&0x20));
UCSR0B|=(1<<TXEN0);
PORTE|=(1<<2);
UCSR0B|=(1<<UDRIE0);
//SEI();
SEI()屏蔽与不屏蔽一样

mion 发表于 2009-8-26 20:50:04

那你试一试在main函数中打开~

haihai 发表于 2009-8-27 08:23:22

试了试一样的不行,谢谢你的好心

haihai 发表于 2009-8-27 11:06:56

莫非一定也要用环形缓冲区否?我现在为了方便只是编了个简单的,是否?

haihai 发表于 2009-8-27 13:51:51

啊,我现在觉得应该必须用上信号量,因为程序时刻都在调度TASK,容易引起错误,是否正确?

haihai 发表于 2009-8-31 10:33:01

#define Test1_GLOBALS
#include "D:\d\kaifabu\iccavr\ucos2_application\INCLUDES.H"
#include <iom128v.h>
#include <macros.h>

//******************************************************************************
// Constants
#define TaskStartPrio        10               
// Task-Prioritaeten
#define   UART_SENDENABLE()   { UCSR0B&=~(1<<RXEN0);UCSR0B&=~(1<<RXCIE0); UCSR0B|=(1<<TXEN0); UCSR0B|=(1<<TXCIE0); UCSR0B|=(1<<UDRIE0);PORTE|=(1<<2);}        
#define   UART_RECEIVERENABLE() { UCSR0B&=~(1<<TXEN0);UCSR0B|=(1<<RXEN0);UCSR0B|=(1<<RXCIE0); PORTE&=~(1<<2); }       
OS_EVENT*Pevent_SerialSend;      //Theserialsend semp
unsignedstatic   char    UartSend_ToHGTemp    ;
unsignedstatic   char    UartSend_ToHG1           ;

//unsignedvolatile static   char    *Uart_send_ptr_2 = UartSend_ToHG1 ;
unsignedstatic   char      UART_i=0x00;
INT8U   Perr;
INT8U   Ptemp;
INT8U    err;
#define    TXBUFSIZE       54
unsigned staticchar   BUF_Serial_ctr ;

typedef struct
{
   unsignedchar Ring;
   unsignedchar tail;// index to last read entry
   unsignedchar head;// index to first valid entry
} TxBufType;
static volatile TxBufType TxBuf={{0}};
//.................................................................
//----------------------------------------------------------
// returns 0 if characters are present in ringbuffer
// returns 1 if buffer is empty
// ---------------------------------------------------------
unsigned char TxBufEmpty(void)
{
    unsigned char retval;
   // ES = 0;
    OS_ENTER_CRITICAL();
    retval = (TxBuf.head == TxBuf.tail) ? 1 : 0;
   // ES = 1;
           OS_EXIT_CRITICAL() ;
    return(retval);
}
//.............................................................
//----------------------------------------------------------
// adds next character to sendringbuffer
// if buffer is full, the character is lost
//----------------------------------------------------------
static void TxBufAddChar(unsigned char c)
{
    unsigned char pos = TxBuf.head;
        TxBuf.head++;
    if (TxBuf.head >= TXBUFSIZE) TxBuf.head = 0;
    if (TxBuf.head == TxBuf.tail)   // full?
    {
       TxBuf.head = pos;
    }
    else
    {
       TxBuf.Ring=c;
    }
}
// ----------------------------------------------------------------
// returns next character fromSend Ringbuffer
// if buffer is empty, the last sendcharacter is returned
// ----------------------------------------------------------------
unsigned char TxBufGetChar(void)
{
   unsigned volatile char c;
   //ES = 0;
    OS_ENTER_CRITICAL();
   c = 0x55;

   if(TxBuf.head == TxBuf.tail) return c; // empty--> don't change indices, just return last character
   TxBuf.tail++;
   if (TxBuf.tail >= TXBUFSIZE) TxBuf.tail = 0;
   c = TxBuf.Ring;
// ES = 1;
OS_EXIT_CRITICAL() ;
   return c;
}


//.................................................................
//UART0Init process
//....................................................................
voiduart0_init(void)
{
   
   OS_ENTER_CRITICAL();
   UCSR0B = 0x00;                                                   //disable while setting baud rate
   UBRR0H=0;
   UBRR0L=51;                              //设置波特率为9600b
   UCSR0C=0x06;
                         //设置桢格式,8个数据位,一个停止位
// UCSR0B|=(1<<UCSZ02);                                           //9bitdata frame
                         /* 接收器使能,接收结束中断使能,*/
   UCSR0B|=(1<<RXEN0);


   OS_EXIT_CRITICAL() ;
   }
//*****************************************************************************
// Variablen
OS_STK        Task1Stack;                // startup task stack
OS_STK        Task2Stack;       

//*****************************************************************************
// Prototypes
void Task1(void *data);
void uart0_init(void);
void   uart_collect (void)
   {
       unsignedvolatilechar*UartToHG_ptr_1=0x00;
           unsignedvolatile char*UartToHG_ptr_k=UartSend_ToHG1;
          
          
          
           OS_ENTER_CRITICAL();
          UartToHG_ptr_1=UartToHG_ptr_k;
           *UartToHG_ptr_k=0x23;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x01;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x03 ;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x00 ;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x01 ;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x00 ;
           UartToHG_ptr_k++;
           *UartToHG_ptr_k=0x03 ;
           UartToHG_ptr_k++;
       
          
          OS_EXIT_CRITICAL() ;
        }
void main(void)
{
    unsigned chari;
       
        OSInit();                // OS init
   
        OSTaskCreate(Task1,
                                                                (void *)(0),
                                &Task1Stack,
                                TaskStartPrio);
        Pevent_SerialSend= OSSemCreate(1);
               
        uart0_init();
        TC2_Init();       
          uart_collect ();
          
                OSStart();                // start multitasking

}

//*****************************************************************************
void Task1(void *data)
{
//        char c = (int)data;
   unsigned chari;
        // unsigned char temp;   
        // Timer/Counter#2 Overflow and Comp init
       unsigned   char    *Uart_send_ptr = UartSend_ToHG1 ;
       
                for (;;)
                {
                data= data;
                //OS_ENTER_CRITICAL();

                OSSemPend(Pevent_SerialSend,0,&err);
               
               
                  
               
                  for (i=0x07;i>0;i--)
                   {
                  
                       TxBufAddChar( *Uart_send_ptr);
                     Uart_send_ptr++;
                        }
                        if ( Uart_send_ptr>=UartSend_ToHG1+0x06)
                           {Uart_send_ptr=UartSend_ToHG1;}
                             
       
                   UDR0 =TxBufGetChar();
                   UCSR0B|=(1<<TXEN0);
                   PORTE|=(1<<2);
               
                       
                  
               
               
       
               


                OSTimeDly (15);

          }
          // OS_EXIT_CRITICAL() ;
   }


现在我编了一个信号量和缓冲区的,为什么我的程序会不停的发,Pevent_SerialSend= OSSemCreate(1);我建立的信号量的初值是
1,当调用OSSemPend(Pevent_SerialSend,0,&err); 时,信号量减一,下次进行任务调度时应该任务挂起呀?也就是发一次就停呀,可现在会不停的发,当我把Pevent_SerialSend= OSSemCreate(0);初始化为0时正确,一次也不发。恳求高手指点,谢谢。
页: [1]
查看完整版本: ucos 中中断程序的应用问题