搜索
bottom↓
回复: 11

ucos 中中断程序的应用问题

[复制链接]

出0入0汤圆

发表于 2009-8-26 15:48:29 | 显示全部楼层 |阅读模式
各位大哥,小弟刚学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); }         

unsigned  static   char    UartSend_ToHGTemp    [9];
unsigned  static   char    UartSend_ToHG1           [9];
unsigned  static   char    *Uart_send_ptr = UartSend_ToHG1 ;
unsigned  static   char      UART_i=0x00;
//*****************************************************************************
// Variablen
OS_STK        Task1Stack[OS_TASK_DEF_STK_SIZE];                // startup task stack
OS_STK        Task2Stack[OS_TASK_DEF_STK_SIZE];       

//*****************************************************************************
// Prototypes
void Task1(void *data);
void uart0_init(void);
void   uart_collect (void)
   {
       unsigned  char  *UartToHG_ptr_1=0x00;
             unsigned  char  *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[OS_TASK_DEF_STK_SIZE-1],
                                TaskStartPrio);
       
        //OSTaskCreate(Task3,
                                //(void *)(int)'b',
                                //&Task2Stack[OS_TASK_DEF_STK_SIZE-1],
                                //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
//...............................................................
  #pragma  interrupt_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;
               
                        //store  global registers
                                             
    }
但是程序通过串口调试,只是05 不停的发,其他字节发不出,请问高手们是什么原因造成的呀?中断不可以用C直接写么?应该
注意些什么呢?谢谢。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-8-26 16:57:56 | 显示全部楼层
UC中可以用C直接写!

出0入0汤圆

 楼主| 发表于 2009-8-26 17:06:19 | 显示全部楼层
谢谢LS,那我上面的程序是什么问题呀?

出0入0汤圆

发表于 2009-8-26 17:17:16 | 显示全部楼层
不是中断的问题!可能是指针的问题!

出0入0汤圆

 楼主| 发表于 2009-8-26 17:20:25 | 显示全部楼层
指针在UC中和在前后台中还有什么不同的地方么,谢谢

出0入0汤圆

发表于 2009-8-26 17:22:06 | 显示全部楼层
总中断打开没!

出0入0汤圆

 楼主| 发表于 2009-8-26 17:25:22 | 显示全部楼层
我试了,while(!(UCSR0A&0x20));
UCSR0B|=(1<<TXEN0);
PORTE|=(1<<2);
UCSR0B|=(1<<UDRIE0);
//SEI();
SEI()屏蔽与不屏蔽一样

出0入0汤圆

发表于 2009-8-26 20:50:04 | 显示全部楼层
那你试一试在main函数中打开~

出0入0汤圆

 楼主| 发表于 2009-8-27 08:23:22 | 显示全部楼层
试了试一样的不行,谢谢你的好心

出0入0汤圆

 楼主| 发表于 2009-8-27 11:06:56 | 显示全部楼层
莫非一定也要用环形缓冲区否?我现在为了方便只是编了个简单的,是否?

出0入0汤圆

 楼主| 发表于 2009-8-27 13:51:51 | 显示全部楼层
啊,我现在觉得应该必须用上信号量,因为程序时刻都在调度TASK,容易引起错误,是否正确?

出0入0汤圆

 楼主| 发表于 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;        //The  serial  send semp
unsigned  static   char    UartSend_ToHGTemp    [9];
unsigned  static   char    UartSend_ToHG1           [9];

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

typedef struct
{
   unsigned  char Ring[TXBUFSIZE];
   unsigned  char tail;  // index to last read entry
   unsigned  char 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 send  ringbuffer
// 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[TxBuf.head]=c;
    }
}
// ----------------------------------------------------------------
// returns next character from  Send Ringbuffer
// if buffer is empty, the last send  character 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[TxBuf.tail];
  // ES = 1;
  OS_EXIT_CRITICAL() ;
   return c;
}
  

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

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

//*****************************************************************************
// Prototypes
void Task1(void *data);
void uart0_init(void);
void   uart_collect (void)
   {
       unsigned  volatile  char  *UartToHG_ptr_1=0x00;
             unsigned  volatile 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 char  i;
       
        OSInit();                // OS init
   
        OSTaskCreate(Task1,
                                                                (void *)(0),
                                &Task1Stack[OS_TASK_DEF_STK_SIZE-1],
                                TaskStartPrio);
        Pevent_SerialSend= OSSemCreate  (1);  
               
        uart0_init();
        TC2_Init();       
          uart_collect ();
          
                OSStart();                // start multitasking

}

//*****************************************************************************
void Task1(void *data)
  {
//        char c = (int)data;
     unsigned char  i;
        // 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时正确,一次也不发。恳求高手指点,谢谢。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 11:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表