| 
 
| 本帖最后由 V一舟 于 2013-9-11 16:35 编辑 
 各位大神,小弟初次接触ucos,遇到了一个棘手的问题,还请各位相助。
 我若吧ADC采样的转换模式换成连续转换模式,整个系统都不能正常运行;若换为单次转换模式,那么系统可以运行,但采集不到AD的值,或许是因为制转换一次。
 adc初始化源码
 #include "includes.h"
 
 
 //初始化ADC,开启通道CH-0
 void  Adc_Init(void)
 {
 ADC_InitTypeDef ADC_InitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;
 DMA_InitTypeDef DMA_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );          //使能ADC1通道时钟
 /* Enable DMA clock */
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
 
 //PA0 作为模拟通道输入引脚
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 /* DMA channel1 configuration ----------------------------------------------*/
 //使能DMA
 DMA_DeInit(DMA1_Channel1);
 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;                                    //DMA通道1的地址
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;                    //DMA传送地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                                    //外设作为数据传输的来源
 DMA_InitStructure.DMA_BufferSize = 100;                                                                            //传送内存大小,100个16位
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                                 //外设地址寄存器不递增
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                            //传送内存地址递增
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;                //ADC1转换的数据是16位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                                //传送的目的地址是16位宽度
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                                        //循环
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                                                //设置DMA通道优先级高
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 
 /* 允许DMA1通道1传输结束中断 */
 DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);
 
 //使能DMA通道1
 DMA_Cmd(DMA1_Channel1, ENABLE);
 
 ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值
 
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                           //ADC工作模式:ADC1工作在独立模式
 ADC_InitStructure.ADC_ScanConvMode = DISABLE;                              //模数转换工作在单通道模式
 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                         //模数转换工作在连续转换模式(就是这个配置,若改为单次转换模式,则可以                                                                                                                            工作)
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                    //ADC数据右对齐
 ADC_InitStructure.ADC_NbrOfChannel = 1;                                   //顺序进行规则转换的ADC通道的数目
 ADC_Init(ADC1, &ADC_InitStructure);                                      //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
 
 //配置ADC时钟 ,72M/8=9,ADC最大时间不能超过14M
 RCC_ADCCLKConfig(RCC_PCLK2_Div6);
 //ADC1 规则通道配置
 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);          //通道0采样时间 55.5周期
 
 ADC_DMACmd(ADC1,ENABLE); //使能ADC1_DMA
 
 ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1
 
 ADC_ResetCalibration(ADC1);        //重置指定的ADC1的校准寄存器
 
 while(ADC_GetResetCalibrationStatus(ADC1));        //获取ADC1重置校准寄存器的状态,设置状态则等待
 
 ADC_StartCalibration(ADC1);                //开始指定ADC1的校准状态
 
 while(ADC_GetCalibrationStatus(ADC1));                //获取指定ADC1的校准程序,设置状态则等待
 
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能
 
 }
 app.c中程序
 #define GLOBALS
 
 #include "includes.h"
 
 //数据变量定义
 float ADC_ConvertedValueLocal;
 
 //建立信号量
 OS_EVENT* Com1_SEM;
 OS_EVENT* Com1_MBOX;
 OS_EVENT* ADC_SEM;
 
 
 static  OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];
 static  OS_STK Task_Com1Stk[Task_Com1_STK_SIZE];
 static  OS_STK Task_LedStk[Task_Led_STK_SIZE];
 static  OS_STK Task_ADCStk[Task_ADC_STK_SIZE];
 /*
 *********************************************************************************************************
 *                                      LOCAL FUNCTION PROTOTYPES
 *********************************************************************************************************
 */
 
 static  void APP_TaskCreate(void);
 static  void APP_TaskStart(void* p_arg);
 static  void Task_Com1(void* p_arg);
 static  void Task_Led(void* p_arg);
 static  void Task_ADC(void* p_arg);
 
 extern char *itoa(int value, char *string, int radix);
 
 
 
 /*主函数*/
 /*
 *********************************************************************************************************
 *                                                main()
 *
 * Description : This is the standard entry point for C code.  It is assumed that your code will call
 *               main() once you have performed all necessary initialization.
 *
 * Argument : none.
 *
 * Return   : none.
 *********************************************************************************************************
 */
 
 int main(void)
 {
 
 //禁止CPU中断
 //CPU_IntDis();
 
 //UCOS 初始化
 OSInit();                                                   /* Initialize "uC/OS-II, The Real-Time Kernel".         */
 
 //硬件平台初始化
 BSP_Init();                                                 /* Initialize BSP functions.  */
 
 
 /*向串口1发送开机字符*/
 /*
 USART_OUT(USART1,"*********RTOS系统测试程序************\r\n");
 USART_OUT(USART1,"*                                   *\r\n");
 USART_OUT(USART1,"*          串口测试                 *\r\n");
 USART_OUT(USART1,"*                                   *\r\n");
 USART_OUT(USART1,"*       基于 uCOSII2.86             *\r\n");
 USART_OUT(USART1,"*                                   *\r\n");
 USART_OUT(USART1,"*************************************\r\n");
 USART_OUT(USART1,"\r\n");
 USART_OUT(USART1,"\r\n");
 */
 //建立主任务, 优先级最高  建立这个任务另外一个用途是为了以后使用统计任务
 OSTaskCreate( (void (*) (void *)) APP_TaskStart,                                                         //指向任务代码的指针
 (void *) 0,                                                                                              //任务开始执行时,传递给任务的参数的指针
 (OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],            //分配给任务的堆栈的栈顶指针   从顶向下递减
 (INT8U) APP_TASK_START_PRIO);                                                                    //分配给任务的优先级
 
 
 //ucos的节拍计数器清0    节拍计数器是0-4294967295    对于节拍频率100hz时, 每隔497天就重新计数
 OSTimeSet(0);
 OSStart();                                                  /* Start multitasking (i.e. give control to uC/OS-II).  */
 /* Start multitasking (i.e. give control to uC/OS-II).  */
 return (0);
 }
 
 
 
 /*建立系统任务*/
 static void APP_TaskStart(void *p_arg)
 {
 (void)p_arg;                 // 'p_arg' 并没有用到,防止编译器提示警告
 
 /*使能ucos的统计任务*/
 #if(OS_TASK_STAT_EN>0)
 OSStatInit();             //统计任务初始化函数
 #endif
 
 /*调用其他任务建立的函数*/
 APP_TaskCreate();
 
 while(1)
 {
 
 /*1秒1次循环*/
 OSTimeDlyHMSM(0, 0,1,0);
 
 }
 }
 
 
 /*建立其他任务的函数集合*/
 static void APP_TaskCreate(void)
 {
 
 ADC_SEM=OSSemCreate(0);                                 //建立ADC采样信号量,在中断函数里同步
 
 Com1_SEM=OSSemCreate(1);                                //建立串口1中断的信号量
 Com1_MBOX=OSMboxCreate((void *) 0);                     //建立串口1中断的消息邮箱
 
 
 //串口1接收及发送任务---------------------------------------------------------
 OSTaskCreateExt( Task_Com1,                                                                          //指向任务代码的指针
 (void *)0,                                                                          //任务开始执行时,传递给任务的参数的指针
 (OS_STK *)&Task_Com1Stk[Task_Com1_STK_SIZE-1],//分配给任务的堆栈的栈顶指针   从顶向下递减
 Task_Com1_PRIO,                                                                  //分配给任务的优先级
 Task_Com1_PRIO,                                                                  //预备给以后版本的特殊标识符,在现行版本同任务优先级
 (OS_STK *)&Task_Com1Stk[0],                                          //指向任务堆栈栈底的指针,用于堆栈的检验
 Task_Com1_STK_SIZE,                                                          //指定堆栈的容量,用于堆栈的检验
 (void *)0,                                                                          //指向用户附加的数据域的指针,用来扩展任务的任务控制块
 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);          //选项,指定是否允许堆栈检验,是否将堆栈清0,任务是否要进行浮点运算等等。
 //LED1 闪烁任务------------------------------------------------------
 OSTaskCreateExt( Task_Led,
 (void *)0,
 (OS_STK *)&Task_LedStk[Task_Led_STK_SIZE-1],
 Task_Led_PRIO,
 Task_Led_PRIO,
 (OS_STK *)&Task_LedStk[0],
 Task_Led_STK_SIZE,
 (void *)0,
 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
 //ADC采集任务------------------------------------------------------
 OSTaskCreateExt( Task_ADC,
 (void *)0,
 (OS_STK *)&Task_ADCStk[Task_ADC_STK_SIZE-1],
 Task_ADC_PRIO,
 Task_ADC_PRIO,
 (OS_STK *)&Task_ADCStk[0],
 Task_ADC_STK_SIZE,
 (void *)0,
 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
 
 }
 
 /*建立子任务函数*/
 
 //LED1闪烁任务----------------------------------------
 static  void Task_Led(void* p_arg)
 {
 (void) p_arg;
 while (1)
 {
 
 LED1_ON;
 OSTimeDlyHMSM(0, 0, 0, 500);
 LED1_OFF;
 OSTimeDlyHMSM(0, 0, 0, 500);
 
 USART_OUT(USART1,"\r\n LED任务运行正常! \r\n");
 
 OSTimeDly(1);
 }
 }
 
 
 //ADC数据采集与转换任务·
 static void Task_ADC(void* p_arg)
 {
 INT8U err;
 
 (void) p_arg;
 
 while(1)
 {
 OSSemPend(ADC_SEM,0,&err);
 
 if(ADC_TIMEOUT>1000)
 {
 //1秒采样一次
 ADC_TIMEOUT=0;
 
 ADC_ConvertedValueLocal=(float)ADC_ConvertedValue/4096*3.3;
 
 USART_OUT(USART1,"\r\n ADC1 通道1的值: ");
 printf("%d",ADC_ConvertedValue );
 USART_OUT(USART1,"\r\n ADC1 电压的值: ");
 printf("%f",ADC_ConvertedValueLocal );
 USART_OUT(USART1,"\r\n");
 USART_OUT(USART1,"\r\n");
 
 }
 OSTimeDly(1);
 }
 }
 
 //串口任务
 //++++++++++++COM1处理任务++++++++++++++++++++++++++
 static  void Task_Com1(void *p_arg)
 {
 INT8U err;
 
 unsigned char * msg;
 
 (void)p_arg;
 
 while(1)
 {
 //OSSemPend(Com1_SEM,0,&err);                                           //等待串口接收指令成功的信号量(方法1)
 
 msg=(unsigned char *)OSMboxPend(Com1_MBOX,0,&err);                   //等待串口接收指令成功的邮箱信息(方法2)
 //USART_OUT(USART1,&TxBuffer1[0]);
 if(msg[0]=='L'&&msg[1]=='M')
 {
 USART_OUT(USART1,"\r\n 串口任务正常! \r\n");
 }
 }
 }
 中断中程序
 
 /*******************************************************************************
 * Function Name  : DMA1_Channel1_IRQHandler
 * Description    : This function handles DMA1 Channel 1 interrupt request.
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
 extern OS_EVENT* ADC_SEM;
 void DMA1_Channel1_IRQHandler(void)
 {
 
 OS_CPU_SR  cpu_sr;
 
 OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断
 OSIntNesting++;                     //中断嵌套
 OS_EXIT_CRITICAL();          //恢复全局中断标志
 
 if(DMA_GetITStatus(DMA1_IT_TC1))                  //转换完成
 {
 ADC_TIMEOUT++;
 
 OSSemPost(ADC_SEM);
 
 USART_OUT(USART1,"\r\n 进入DMA中断 \r\n ");
 
 DMA_ClearITPendingBit(DMA1_IT_GL1);      //清除中断标志
 }
 OSIntExit();                                 //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
 }
 
 
 
 | 
 |