Chinaunix首页 | 论坛 | 博客
  • 博客访问: 421773
  • 博文数量: 55
  • 博客积分: 167
  • 博客等级: 入伍新兵
  • 技术积分: 1167
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-28 10:20
个人简介

一个算是正常的中国码农!

文章分类

全部博文(55)

文章存档

2014年(1)

2013年(31)

2012年(23)

我的朋友

分类:

2012-12-13 16:10:04

原文地址:ucos ii综合测试程序 作者:number007cool

在网上看到的ucos的示例程序,很多都是点灯之类的。参考的价值不是很大。
近阶段在stm32上研究uc,写了个程序如下。
程序功能:
(1)通过串口中断接收命令,模拟键盘效果。
(2)通过触发事件使串口对外发送数据
(3)can接收中断触发消息发送,最终触发串口对外发送数据
(4)定时器4中断计数,串口对外发送计数值。
#include "STM32Lib\\stm32f10x.h"
#include "hal.h"
#include "UCOSII\\ucos_ii.h"
#include "stm32f10x_it_my.h"
#include "stdio.h"
#include "string.h"
extern unsigned int count;
extern volatile bool ADC_Ok;
extern u16 ADCCov[16];
extern void DMAReConfig(void);
/******************************
** 任务堆栈
*******************************/
OS_STK   Task0Stk[128];
OS_STK   task1_stk[128];
OS_STK   task2_stk[128];
OS_STK   task_key_stk[128];
OS_STK   task3_stk[128];
OS_STK   task4_stk[128];
OS_STK   task5_stk[128];
OS_STK   task6_stk[128];
OS_STK   task_can_rx_stk[128];
OS_STK   task_uart_tx_stk[128];
/******************************
 任务函数
******************************/
void  Task0(void *prg);
void  task_key(void *prg);
void  my_task1(void *prg);
void  my_task2(void *prg);
void  my_task3(void *prg);
void  my_task4(void *prg);
void  my_task5(void *prg);
void  my_task6(void *prg);

void task_uart_tx(void * prg);
OS_EVENT *mysem[10];
OS_EVENT *sem;
OS_EVENT *mybox;
//串口输出重定向,使printf输出重定向
int fputc(int ch, FILE *f) 

 //USART_SendData(USART1, (u8) ch); 
 
 USART1->DR = (u8) ch; 
 
 /* Loop until the end of transmission */ 
 
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)   
 {   
 }   
 return ch; 
}
/**************************************************************
** 函数名:DigitFilter
** 功能:软件滤波
** 注意事项:取NO的2/5作为头尾忽略值,注意N要大于5,否则不会去头尾
***************************************************************/
u16 DigitFilter(u16* buf,u8 no)
{
 u8 i,j;
 u16 tmp;
 u8 cut_no=0;
 //排序
 for(i=0;i {
  for(j=0;j  { 
   
   if(buf[j]>buf[j+1])
   { 
   tmp=buf[j];
   buf[j]=buf[j+1];
   buf[j+1]=tmp;
   }
  }
 }
 if(no>5)
 {
  cut_no=no/5;
 }
 //平均
 tmp=0;
 for(i=cut_no;i  tmp+=buf[i];
 return(tmp/(no-2*cut_no));
}
int main(void)
{
 u8 os_err;
 os_err=os_err;
 //由于使用UCOS,一下的初始化虽然可以在OS运行之前运行,但注意别使能任何中断.
 ChipHalInit();   //片内硬件初始化
 ChipOutHalInit();  //片外硬件初始化
 CAN_Interrupt();
 OSInit();    //UCOS INIT~
 
 os_err = OSTaskCreate( Task0,          //第一个任务0
                          (void          * ) 0,       //不带参数
                          (OS_STK        * )&Task0Stk[128 - 1],   //堆栈指针
                          (INT8U           ) 5       //优先级
                         );
 OSStart();
 
 while(1);
}
//任务1主要用来创建各个实现子功能的任务快
void Task0(void *p_arg)
{
 u8 os_err;
 os_err=os_err;
// char DATA_1[]="TASK1_ON\r\n";
 
 
 OS_CPU_SysTickInit(); //使能SYSTICK中断
 
#if (OS_TASK_STAT_EN > 0)
    OSStatInit();                                               /*这东西可以测量CPU使用量 */
#endif

 os_err= OSTaskCreate( my_task1,
        (void *)0,
        (OS_STK   *)&task1_stk[128-1],
        (INT8U         )19
         );
 os_err= OSTaskCreate( my_task2,
        (void *)0,
        (OS_STK   *)&task2_stk[128-1],
        (INT8U         )9
         );
   os_err= OSTaskCreate( task_key,
        (void *)0,
        (OS_STK   *)&task_key_stk[128-1],
        (INT8U         )7
         );
   os_err= OSTaskCreate( my_task4,
          (void *)0,
       (OS_STK        *)&task4_stk[128-1],
       (INT8U          )29       
        );
   os_err= OSTaskCreate( my_task5,
       (void *)0,
       (OS_STK         *)&task5_stk[128-1],
       (INT8U           )44
      );
   os_err= OSTaskCreate( task_uart_tx,
       (void *)0,
       (OS_STK         *)&task_uart_tx_stk[128-1],
       (INT8U           )6
         );
   os_err=OSTaskCreate(my_task6,
           ( void *) 0,
           (OS_STK *)&task6_stk[128-1],
           (INT8U        )45
          );
 for(;;)
 {
   OSTimeDly(OS_TICKS_PER_SEC/10);
 }
}
//接收到can中断服务子函数发送的消息,通过串口对外发送CAN RECEIVED
void task_uart_tx(void * prg)
{
 INT8U err;
 box_can_rx=OSMboxCreate((void *)0);
 while(1)
 {
 OSMboxPend(box_can_rx,0,&err);
 USART1_Puts("CAN RECEIVED!\r\n");//(char *)uart_buff
 OSTimeDly(OS_TICKS_PER_SEC/10);
 }
}
//通过串口接收中断模拟键盘的功能
void task_key(void *prg)
{
   INT8U baud='4';
   INT8U os_err;
   os_err=os_err;
   mysem[1]=OSSemCreate(0);//创建信号量
   mysem[2]=OSSemCreate(0);//创建信号量
   sem=OSSemCreate(0);
   mybox=OSMboxCreate((void *)0);
   while(1)
   {
   switch(uart_cmd_buf)
   {
    case '1':
  {
     //发送信号量
     OSSemPost(mysem[1]);
  }break;
  case '2':
  {
   OSSemPost(mysem[2]);
  }break;
  case '3':
  { 
    os_err=OSTaskCreate( my_task3,
      (void * )0,
      (OS_STK        * )&task3_stk[128 - 1],   //堆栈指针
                     (INT8U           ) 8       //优先级
       );
  }break;
  case '4':
  {  
    
   OSMboxPost(mybox,&baud);
  }break;
  case '5':
  {
       os_err= OSTaskCreate( my_task5,
       (void *)0,
       (OS_STK         *)&task5_stk[128-1],
       (INT8U           )18
      );
  }break;
   }
   uart_cmd_buf=0;
   OSTimeDly(OS_TICKS_PER_SEC/10);
   }
}
//任务1和任务2进行双向同步,在串口接收到‘1’或者‘2’,任务1和任务2开始运行起来
void my_task1(void *prg)
{
  INT8U err;
  while(1)
  {
  OSSemPend(mysem[1],0,&err);
  USART1_Puts("m1\r\n");
  OSSemPost(mysem[2]); 
  OSTimeDly(OS_TICKS_PER_SEC/10);
  
  }
 
}
void my_task2(void *prg)
{
   INT8U err;
   while(1)
   {
    OSSemPend(mysem[2],0,&err);
 USART1_Puts("m2\r\n");
 //printf("%dp\r\n",OSCPUUsage);
 OSSemPost(mysem[1]);
    OSTimeDly(OS_TICKS_PER_SEC/10);
   }
}
//对外发送“m3”
void my_task3(void *prg)
{
 //INT8U err;
 while(1)
 {
 USART1_Puts("m3\r\n");
 OSTimeDly(OS_TICKS_PER_SEC/10);
 }
}
//接收到消息后,对外发送baud,即‘4’
void my_task4(void *prg)
{
 INT8U err;
 char baud;
 err=err; 
 prg=prg;
 while(1)
 {
  baud=*(char *)OSMboxPend(mybox,0,&err);
  printf("%s\r\n",&baud);
  OSTimeDly(OS_TICKS_PER_SEC/10);
  
 }
}
//AD转换任务,将ad值串口发送出去
void my_task5(void *prg)
{
   u16 adc;
 while(1)
 {
//  printf("cnt is %d\r\n",count);  
  /* 人工打开ADC转换.*/
     ADC_SoftwareStartConvCmd(ADC1, ENABLE);        
  if(ADC_Ok==TRUE)
  {
   ADC_Ok=FALSE;
   adc=DigitFilter(ADCCov,16); //滤波
   DMAReConfig();//重新启动DMA
   adc=(1.42 - adc*3.3/4096)*1000/4.35 + 25;//转换为温度值,实际应用中,可考虑用毫伏为单位,避免浮点运算
   ADC_SoftwareStartConvCmd(ADC1, DISABLE);
   printf("当前温度是:%d\r\n",adc);
  }  
              
  OSTimeDly(OS_TICKS_PER_SEC/10);
 }
}
//将CPU的利用率串口输出
void my_task6(void *prg)
{
 while(1)
 {
  printf("cpu usage is: %d\r\n",OSCPUUsage);
  //printf("%d p\r\n",OSCPUUsage);
  //USART1_Puts("%d p\r\n");
  OSTimeDly(OS_TICKS_PER_SEC/10);
 }
}
需要说明的是,由于板子上只有uart和can,所以一切的任务都是基于这两个通信接口。

阅读(882) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~