打印

在UCOS上加了DS18B20,运行之后进入HardFault_Handler

[复制链接]
7997|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pangfuhua|  楼主 | 2012-1-1 15:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "stm32f10x.h"
#include "uctsk_DS18B20.h"
#include <includes.h>


//#define EnableINT()
//#define DisableINT()

#define DS_PORT   GPIOA
#define DS_DQIO   GPIO_Pin_1
#define DS_RCC_PORT  RCC_APB2Periph_GPIOA
#define DS_PRECISION 0x7f   //精度配置寄存器 1f=9位; 3f=10位; 5f=11位; 7f=12位;
#define DS_AlarmTH  0x64
#define DS_AlarmTL  0x8a
#define DS_CONVERT_TICK 1000

#define ResetDQ() GPIO_ResetBits(DS_PORT,DS_DQIO)
#define SetDQ()  GPIO_SetBits(DS_PORT,DS_DQIO)
#define GetDQ()  GPIO_ReadInputDataBit(DS_PORT,DS_DQIO)
OS_CPU_SR cpu_sr;
static  OS_STK         App_TaskDS18B20Stk[APP_TASK_DS18B20_STK_SIZE];

static void uctsk_DS18B20(void)
{  //OS_ENTER_CRITICAL();
   ds18b20_start();
   ds18b20_read();
   //OS_EXIT_CRITICAL();
   OSTimeDlyHMSM(0, 0, 0, 500);
}

void  App_DS18B20TaskCreate (void)
{
    CPU_INT08U  os_err;

        os_err = os_err; /* prevent warning... */

        os_err = OSTaskCreate((void (*)(void *)) uctsk_DS18B20,                               
                          (void          * ) 0,                                                       
                          (OS_STK        * )&App_TaskDS18B20Stk[APP_TASK_DS18B20_STK_SIZE - 1],               
                          (INT8U           ) APP_TASK_DS18B20_PRIO  );                                                       

        #if OS_TASK_NAME_EN > 0
            OSTaskNameSet(APP_TASK_DS18B20_PRIO, "Task DS18B20", &os_err);
        #endif
}

static unsigned char TempX_TAB[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};


//void Delay_us(u32 Nus)
/****************************************************************************
* 函  数:Delay(uint16_t Nus);
* 功  能:延时
* 参  数:uint8_t Nus
* 返回值:无
* 更  新:无
* 备  注:Delay(8)大概是1US
****************************************************************************/
void Delay_us(uint16_t Nus)
{
while(Nus--){}
}



unsigned char ResetDS18B20(void)
{
unsigned char resport=0;
SetDQ();
Delay_us(400);

ResetDQ();
Delay_us(4000);  //500us (该时间的时间范围可以从480到960微秒)
SetDQ();
Delay_us(320);  //40us
resport = GetDQ();
//while(GetDQ());
Delay_us(4000);  //500us
SetDQ();
return resport;
}

void DS18B20WriteByte(unsigned char Dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
   ResetDQ();     //在15u内送数到数据线上,DS18B20在15-60u读数
  Delay_us(40);    //5us
  if(Dat & 0x01)
   SetDQ();
  else
   ResetDQ();
  Delay_us(520);    //65us
  SetDQ();
  Delay_us(16);    //连续两位间应大于1us
  Dat >>= 1;
}
}


unsigned char DS18B20ReadByte(void)
{
unsigned char i=0,Dat=0;
SetDQ();
Delay_us(40);
for(i=8;i>0;i--)
{
   Dat >>= 1;
    ResetDQ();     //从读时序开始到采样信号线必须在15u内,且采样尽量安排在15u的最后
  Delay_us(40);   //5us
  SetDQ();
  Delay_us(40);   //5us
  if(GetDQ())
    Dat|=0x80;
  else
   Dat&=0x7f;  
  Delay_us(520);   //65us
  SetDQ();
}
return Dat;
}


void ReadRom(unsigned char *Read_Addr)
{
unsigned char i=0;

DS18B20WriteByte(ReadROM);
  
for(i=8;i>0;i--)
{
  *Read_Addr=DS18B20ReadByte();
  Read_Addr++;
}
}


void DS18B20Init(unsigned char Precision,unsigned char AlarmTH,unsigned char AlarmTL)
{
//DisableINT();
//OS_ENTER_CRITICAL();
ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteByte(WriteScratchpad);
DS18B20WriteByte(AlarmTL);
DS18B20WriteByte(AlarmTH);
DS18B20WriteByte(Precision);

ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteByte(CopyScratchpad);
//EnableINT();

while(!GetDQ());  //等待复制完成 ///////////
// OS_EXIT_CRITICAL();
}


void DS18B20StartConvert(void)
{
//DisableINT();
//OS_ENTER_CRITICAL();
ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteByte(StartConvert);
//EnableINT();
//OS_EXIT_CRITICAL();
}

void DS18B20_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(DS_RCC_PORT, ENABLE);

GPIO_InitStructure.GPIO_Pin = DS_DQIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //2M时钟速度
GPIO_Init(DS_PORT, &GPIO_InitStructure);
}


void ds18b20_start(void)
{
DS18B20_Configuration();
DS18B20Init(DS_PRECISION, DS_AlarmTH, DS_AlarmTL);
DS18B20StartConvert();
}


unsigned short ds18b20_read(void)
{
unsigned char TemperatureL=0,TemperatureH=0;
unsigned int  Temperature=0;

//DisableINT();
// OS_ENTER_CRITICAL();
  ResetDS18B20();
DS18B20WriteByte(SkipROM);
DS18B20WriteByte(ReadScratchpad);
TemperatureL=DS18B20ReadByte();
TemperatureH=DS18B20ReadByte();
ResetDS18B20();
//EnableINT();

if(TemperatureH & 0x80)
  {
  TemperatureH=(~TemperatureH) | 0x08;
  TemperatureL=~TemperatureL+1;
  if(TemperatureL==0)
   TemperatureH+=1;
  }

TemperatureH=(TemperatureH<<4)+((TemperatureL&0xf0)>>4);
TemperatureL=TempX_TAB[TemperatureL&0x0f];

//bit0-bit7为小数位,bit8-bit14为整数位,bit15为正负位
Temperature=TemperatureH;
Temperature=(Temperature<<8) | TemperatureL;
// OS_EXIT_CRITICAL();
DS18B20StartConvert();

return  Temperature;

}
沙发
李富贵| | 2012-1-1 16:58 | 只看该作者
从uctsk_DS18B20函数退出的时候引发hardfault。
记住任何一个ucos任务都必须是死循环。

使用特权

评论回复
板凳
pangfuhua|  楼主 | 2012-1-2 16:41 | 只看该作者
2# 李富贵

请问是不是在uctsk_DS18B20开始的时候加while(1)之类的?谢谢!!

使用特权

评论回复
地板
pangfuhua|  楼主 | 2012-1-2 16:51 | 只看该作者
3# pangfuhua
这个问题貌似解决了,但是现在全速运行后任务只执行一次就进OS_TaskIdle出不来了。我的main代码如下:
#include <includes.h>

static  OS_STK         App_TaskStartStk[APP_TASK_START_STK_SIZE];

static  void  App_TaskCreate                  (void);
static  void  App_TaskStart                          (void                *p_arg);  
extern  void  App_BlinkTaskCreate     (void);
extern  void  App_DS18B20TaskCreate   (void);
static  void  GPIO_Configuration      (void);

#define DS_PORT   GPIOA
#define DS_DQIO   GPIO_Pin_1
#define DS_RCC_PORT  RCC_APB2Periph_GPIOA

INT32S main (void)
{
    CPU_INT08U  os_err;
        os_err = os_err; /* prevent warning... */

        /* Note:  由于使用UCOS, 在OS运行之前运行,注意别使能任何中断. */
        CPU_IntDis();                    /* Disable all ints until we are ready to accept them.  */

    OSInit();                        /* Initialize "uC/OS-II, The Real-Time Kernel".         */
       

        os_err = OSTaskCreateExt((void (*)(void *)) App_TaskStart,  /* Create the start task.                               */
                             (void          * ) 0,
                             (OS_STK        * )&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
                             (INT8U           ) APP_TASK_START_PRIO,
                             (INT16U          ) APP_TASK_START_PRIO,
                             (OS_STK        * )&App_TaskStartStk[0],
                             (INT32U          ) APP_TASK_START_STK_SIZE,
                             (void          * )0,
                             (INT16U          )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK));
       
#if OS_TASK_NAME_EN > 0
    OSTaskNameSet(APP_TASK_START_PRIO, (CPU_INT08U *)"Start Task", &os_err);
#endif

        OSStart();                                                  /* Start multitasking (i.e. give control to uC/OS-II).  */

        return (0);
}

static  void  App_TaskStart (void *p_arg)
{   
        (void)p_arg;
       
        /***************  Init hardware ***************/

        GPIO_Configuration();

    OS_CPU_SysTickInit();                                    /* Initialize the SysTick.                              */

#if (OS_TASK_STAT_EN > 0)
    OSStatInit();                                            /* Determine CPU capacity.                              */
#endif

    App_TaskCreate();                                        /* Create application tasks.                            */
//        OSTaskSuspend(OS_PRIO_SELF);
        for(;;)
           {

              OSTimeDlyHMSM(0, 1, 0, 0);                                                         /* Delay One minute */
    }       
}

static  void  App_TaskCreate (void)
{               
        App_BlinkTaskCreate();
        App_DS18B20TaskCreate();       

}


void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOF , ENABLE);                                                  
  /**
  *  LED1 -> PF7 , LED4 -> PF10
  */                       
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

  RCC_APB2PeriphClockCmd(DS_RCC_PORT, ENABLE);

GPIO_InitStructure.GPIO_Pin = DS_DQIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //2M时钟速度
GPIO_Init(DS_PORT, &GPIO_InitStructure);
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/

使用特权

评论回复
5
李富贵| | 2012-1-3 19:31 | 只看该作者
加上死循环以后什么结果?

使用特权

评论回复
6
pangfuhua|  楼主 | 2012-1-6 11:55 | 只看该作者
5# 李富贵
貌似解决了~~分别在两个任务里设断点,可以轮流进。我还有一个问题:在加了串口后,却进不了串口中断,这是什么情况?我的中断函数如下~~
/**
  ******************************************************************************
  * @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c
  * @author  MCD Application Team
  * @version V3.4.0
  * @date    10/15/2010
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and
  *          peripherals interrupt service routine.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2>
© COPYRIGHT 2010 STMicroelectronics
</h2>
  */

/* Includes ------------------------------------------------------------------*/
#include <includes.h>
extern u8 gRecieveBuffer[256];
extern u8 Gprs_Receive_Count;

//#if ( OS_VIEW_MODULE == DEF_ENABLED )
//extern void OSView_RxTxISRHandler(void);
//#endif


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief   This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}



/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
//void SysTick_Handler(void)
//{
// CPU_SR         cpu_sr;
// OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */
//    OSIntNesting++;
//    OS_EXIT_CRITICAL();

//    OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */

//    OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR          */
//}


/*******************************************************************************
* Function Name  : USART1_IRQHandler
* Description    : This function handles USART1 global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void USART1_IRQHandler(void)
{
OS_CPU_SR  cpu_sr;
    OS_ENTER_CRITICAL();                                      
    OSIntNesting++;
   
  if (SET == USART_GetFlagStatus(USART1, USART_FLAG_RXNE))         // 是接收中断
  {
   if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) //清 ORE 标志,防止过载
   {
        USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR其实就是清除标志
        USART_ReceiveData(USART1);    //读DR

   }
     gRecieveBuffer[Gprs_Receive_Count++]= USART_ReceiveData(USART1);
if(Gprs_Receive_Count>255)
Gprs_Receive_Count=0;
   USART_ClearFlag(USART1,USART_FLAG_RXNE);
   //USART_ClearFlag(USART1,USART_FLAG_TC);
  }
   OSIntExit();
  OS_EXIT_CRITICAL();
}


/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/

/**
  * @}
  */


/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

使用特权

评论回复
7
李富贵| | 2012-1-7 21:29 | 只看该作者
根据你在东莞骗子莫金明那里贴的代码看,AFIO的时钟没打开

使用特权

评论回复
8
pangfuhua|  楼主 | 2012-1-8 09:23 | 只看该作者
7# 李富贵
那我为什么裸跑串口是可以的?

使用特权

评论回复
9
winloop| | 2012-1-8 13:18 | 只看该作者
加18B20,最好再加个8S103F2之类的,然后通过串口给主机传达数据,成本也很低廉

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

5

帖子

1

粉丝