OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4021|回复: 2

STM32F103 跑ucosiii 使用串口1收发数据过一会就进入hardfault

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-8-23
在线时间
2 小时
发表于 2016-8-23 17:22:24 | 显示全部楼层 |阅读模式
6金钱
我用STM32F103跑了UCOS iii 系统,用USART1 DMA空闲中断的方式接收定位模块发来的数据,收到解析后再通过DMA方式发送给定位模块,运行一段时间后就进入hardfault_handler.关闭串口1,程序又运行正常了。已经查了好几天了,还是没有找到原因,哪位大神帮忙看下代码,万分感谢。

Smart_Robot.rar

16.05 MB, 下载次数: 259

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-8-23
在线时间
2 小时
 楼主| 发表于 2016-8-23 17:27:52 | 显示全部楼层
这是USART1初始化和处理
#include "slam_usart1.h"
#include "includes.h"
#include "buffer.h"

#define USART1_DR_Base 0x40013804
#define STATUS_CODE_SYNC 0x00
#define STATUS_CODE_ECHO 0x01
#define STATUS_CODE_ANS  0x02
#define STATUS_CODE_ANS_RXERR  0x03
#define STATUS_CODE_BAD_PKT 0xFF   

#define PKT_ERRORCODE_NULL            0
#define PKT_ERRORCODE_CHECKSUM_FAIL         0x40
#define PKT_ERRORCODE_SIZE_OVERFLOW         0x20
#define PKT_ERRORCODE_NOT_SYNC_PKT          0x10
#define PKT_ERRORCODE_NOT_SUPPORT           0x8000
#define PKT_ERRORCODE_BAD_CMD         0x8001
#define PKT_ERRORCODE_OPERATION_FAIL  0x8002

extern uint8_t RunStatus;
extern __IO uint32_t RightSpeed;
extern __IO uint32_t LeftSpeed;
extern __IO float yaw;
extern __IO float TotalLeftDistance;
extern __IO float TotalRightDistance;
static uint8_t sending;
Buffer *UARTRxBuffer;
Buffer *UARTTxBuffer;
uint8_t MemoryFail = 0;
uint8_t cmd = 0;
float LastSaveAngleVal = 0;
float LastSaveLeftDistance;
float LastSaveRightDistance;
SlamPacket *handlerpacket;
extern u8 InfraredFlag;
extern OS_SEM SlamSem;
base_connect_response_t ans_pkt1;
base_conf_response_t ans_pkt2;
base_status_response_t ans_pkt3;
base_motor_status_response_t ans_pkt4;
base_sensor_data_response_t ans_pkt5;
base_bumper_data_response_t ans_pkt6;
base_set_motor_request_t ans_pkt7;

void SendDataToBuffer(unsigned char cmd ,const char *data,uint16_t size)
{
                uint16_t  PayloadLen;                
                uint8_t checksum;
          const char Sync = 0x50;
          uint16_t i;
                PayloadLen = size + 1;
                if(UARTTxBuffer->length == UARTTxBuffer->offset)
                {
                                UARTTxBuffer->offset = 0;
                                UARTTxBuffer->length = 0;
                }               
                if(UARTTxBuffer->capacity - UARTTxBuffer->length < PayloadLen + 4)
                {
                                BufferExpandWithCapacity(UARTTxBuffer,PayloadLen + 4);
                }
                memcpy(UARTTxBuffer->data + UARTTxBuffer->length,&Sync,sizeof(Sync));
                UARTTxBuffer->length++;
                UARTTxBuffer->data[UARTTxBuffer->length] = (u8)(PayloadLen&0xff);
                UARTTxBuffer->length++;
                UARTTxBuffer->data[UARTTxBuffer->length] = (u8)(PayloadLen >> 8);
                UARTTxBuffer->length++;
                memcpy(UARTTxBuffer->data + UARTTxBuffer->length,&cmd,sizeof(cmd));
                UARTTxBuffer->length++;
               
                memcpy(UARTTxBuffer->data + UARTTxBuffer->length,data,size);
                UARTTxBuffer->length+= size;
                checksum = Sync ^ cmd;       
                for(i = 0 ; i < size ; ++i)
                {
                                checksum ^= ((u8 *)data)[i];
                }
                checksum ^= (u8)(PayloadLen&0xff);
                checksum ^= (u8)(PayloadLen >> 8);
                memcpy(UARTTxBuffer->data + UARTTxBuffer->length,&checksum,sizeof(checksum));
                UARTTxBuffer->length++;
                USART1SendBuffer(UARTTxBuffer);               
}

void send_errorcode(u16 code)
{
                SendDataToBuffer(STATUS_CODE_ANS_RXERR, (const char *)&code, sizeof(code));
}

void HandlerSlamPacket(SlamPacket *packet)
{  
                switch(packet->cmd)
                {
                                case SLAMWARECORECB_CMD_CONNECT_BASE:
                                {   
                                                cmd = SLAMWARECORECB_CMD_CONNECT_BASE;                                       
                                                memcpy(&ans_pkt1.model, "virt_base", 12);
                                                ans_pkt1.firmware_version = 0x1;
                                                ans_pkt1.hardware_version = 0x1;
                                                memcpy((char *)&ans_pkt1.serial_number, "736c616d3031", 12);
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt1,sizeof(ans_pkt1));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_GET_BASE_CONF:
                                {
                                                cmd = SLAMWARECORECB_CMD_GET_BASE_CONF;                                       
                                                ans_pkt2.base_type = CIRCLE;
                                                ans_pkt2.base_radius_q8 = (u32)(125*256);
                                                ans_pkt2.base_motor_type = TWO_WHEEL;
                                                ans_pkt2.base_sensor_num = 0;
                                                memset((char *)&ans_pkt2.base_sensors, 0, sizeof(base_pos_t)*8);
                                                ans_pkt2.base_bumper_num = 3;
                                                memset((char *)&ans_pkt2.base_bumpers, 0, sizeof(base_pos_t)*8);       
            // base_bumpers
            ans_pkt2.base_bumpers[0].x_to_center_mm_q8 = (s32)(75*256);
            ans_pkt2.base_bumpers[0].y_to_center_mm_q8 = (s32)(104*256);
            ans_pkt2.base_bumpers[0].z_to_center_mm_q8 = (s32)(23*256);
            ans_pkt2.base_bumpers[0].clockwise_angle_to_center_degree_q8 = (u32)(54*256);
         
            ans_pkt2.base_bumpers[1].x_to_center_mm_q8 = (s32)(-75*256);
            ans_pkt2.base_bumpers[1].y_to_center_mm_q8 = (s32)(104*256);
            ans_pkt2.base_bumpers[1].z_to_center_mm_q8 = (s32)(23*256);
            ans_pkt2.base_bumpers[1].clockwise_angle_to_center_degree_q8 = (u32)(126*256);               

            ans_pkt2.base_bumpers[2].x_to_center_mm_q8 = (s32)(0*256);
            ans_pkt2.base_bumpers[2].y_to_center_mm_q8 = (s32)(130*256);
            ans_pkt2.base_bumpers[2].z_to_center_mm_q8 = (s32)(23*256);
            ans_pkt2.base_bumpers[2].clockwise_angle_to_center_degree_q8 = (u32)(90*256);                                               
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt2,sizeof(ans_pkt2));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_GET_BASE_STATUS:
                                {                                       
                                                ans_pkt3.battery_is_charging = 0;
                                                ans_pkt3.battery_percentage = 90;
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt3,sizeof(ans_pkt3));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_GET_BASE_MOTOR_DATA:
                                {
                                                s32 angle,val;
                                                angle = yaw - LastSaveAngleVal;
                                                if(angle < 0)
                                                {
                                                                angle += 360;
                                                }                                                                       
                                                val = (s32)(((TotalRightDistance - LastSaveRightDistance) + (TotalLeftDistance - LastSaveLeftDistance))/2);       
            LastSaveAngleVal = yaw;                                               
                                                LastSaveRightDistance = TotalRightDistance;
                                                LastSaveLeftDistance = TotalLeftDistance;
                                               
                                                ans_pkt4.base_dx_mm_q16 = (s32)(val * cos(angle)*65536);
                                                ans_pkt4.base_dy_mm_q16 = (s32)(val * sin(angle)*65536);
                                                ans_pkt4.base_dtheta_degree_q16 = (s32)((angle)*65536);                                                               
                                                ans_pkt4.motor_cumulate_dist_mm_q16[0] = (s32)(TotalLeftDistance*65536);//If you need to get the actual motor distance data,(_s32)virtualmotor_get_distance(0) can be used.
                                                ans_pkt4.motor_cumulate_dist_mm_q16[1] = (s32)(TotalRightDistance*65536);//If you need to get the actual motor distance data,(_s32)virtualmotor_get_distance(1) can be used.
                                                ans_pkt4.motor_cumulate_dist_mm_q16[2] = (s32)0;
                                                ans_pkt4.motor_cumulate_dist_mm_q16[3] = (s32)0;                               
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt4,sizeof(ans_pkt4));                                               
                                                break;
                                }
                                case SLAMWARECORECB_CMD_GET_BASE_SENSOR_DATA:
                                {
                                                cmd = SLAMWARECORECB_CMD_GET_BASE_SENSOR_DATA;                                                                                       
                                                ans_pkt5.sensor_data_mm_q16[0] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[1] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[2] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[3] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[4] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[5] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[6] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[7] = (u32)(0);                                               
                                                ans_pkt5.sensor_data_mm_q16[8] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[9] = (u32)(0);
                                                ans_pkt5.sensor_data_mm_q16[10] = (u32)(0);
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt5,sizeof(ans_pkt5));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_GET_BASE_BUMPER_DATA:
                                {
                                                cmd = SLAMWARECORECB_CMD_GET_BASE_BUMPER_DATA;                               
                                                ans_pkt6.bumper_data = InfraredFlag;
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt6,sizeof(ans_pkt6));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_SET_BASE_MOTOR:
                                {
                                          
                                                cmd = SLAMWARECORECB_CMD_SET_BASE_MOTOR;       
                                                memset((char *)&ans_pkt7, 0, sizeof(ans_pkt7));
                                                if(RunStatus != NOSTRAIGHTCTRL)
                                                {
                                                                ans_pkt7.motor_speed_mm[0] = (s32)(LeftSpeed * 2.2);
                                                                ans_pkt7.motor_speed_mm[1] = (s32)(RightSpeed * 2.2);
                                                                ans_pkt7.motor_speed_mm[2] = (s32)0;
                                                                ans_pkt7.motor_speed_mm[3] = (s32)0;
                                                }
                                                SendDataToBuffer(STATUS_CODE_ANS,(const char *)&ans_pkt7,sizeof(ans_pkt7));
                                                break;
                                }
                                case SLAMWARECORECB_CMD_POLL_BASE_ANS_CMD:
                                {
                                                cmd = SLAMWARECORECB_CMD_POLL_BASE_ANS_CMD;
                                                SendDataToBuffer(STATUS_CODE_ANS,NULL,0);
                                                break;
                                }
                                case SLAMWARECORECB_CMD_SEND_EVENT:
                                {
                                                cmd = SLAMWARECORECB_CMD_SEND_EVENT;
                                                SendDataToBuffer(STATUS_CODE_ANS,NULL,0);
                                                break;
                                }
                                default:
                                         goto on_error;
                }
                return ;
    on_error:
           send_errorcode(PKT_ERRORCODE_NOT_SUPPORT);
}

void HandlerSlamData(void)
{
          OS_ERR err;
                while(UARTRxBuffer->length - UARTRxBuffer->offset >= 3)
                {
                                if((UARTRxBuffer->data[UARTRxBuffer->offset] == 0x10) && (UARTRxBuffer->data[UARTRxBuffer->offset+2] == 0xF8))
                                {
                                                uint8_t len = UARTRxBuffer->data[UARTRxBuffer->offset+1];
                                                if(UARTRxBuffer->length - UARTRxBuffer->offset >= len + 3)
                                                {
                                                                handlerpacket = (SlamPacket *)UARTRxBuffer->data + UARTRxBuffer->offset + 3;                                                       
                                                                BufferClear(UARTRxBuffer);
                                                                USART1_RX_DMA_DeConfig();
                                                          OSSemPost(&SlamSem,OS_OPT_POST_1,&err);                                //·
                                                }
                                                else
                                                {
                                                                break;
                                                }
                                }
                                else if(UARTRxBuffer->data[UARTRxBuffer->offset] == 0x50)
                                {
                                                if((UARTRxBuffer->length - UARTRxBuffer->offset)>= 4 && (UARTRxBuffer->data[UARTRxBuffer->offset+3] == 0xF8))
                                                {
                                                                uint16_t len = (uint16_t)UARTRxBuffer->data[UARTRxBuffer->offset+1] << 8 | UARTRxBuffer->data[UARTRxBuffer->offset+2];
                                                                if(UARTRxBuffer->length - UARTRxBuffer->offset >= len + 4)
                                                                {
                                                                                handlerpacket = (SlamPacket *)UARTRxBuffer->data + UARTRxBuffer->offset + 4;                                                               
                                                                                BufferClear(UARTRxBuffer);
                                                                                USART1_RX_DMA_DeConfig();
                                                                          OSSemPost(&SlamSem,OS_OPT_POST_1,&err);                                //·
                                                                }
                                                                else
                                                                {
                                                                                break;
                                                                }
                                                }
                                                else
                                                {
                                                                UARTRxBuffer->offset++;
                                                }
                                }
                                else
                                {
                                                UARTRxBuffer->offset++;
                                }
                }
}

void Slam_USART1_Config(void)
{
                GPIO_InitTypeDef GPIO_InitStructure;
                USART_InitTypeDef USART_InitStructure;
          NVIC_InitTypeDef NVIC_InitStructure;
       
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
          
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_Init(GPIOA,&GPIO_InitStructure);

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
                GPIO_Init(GPIOA,&GPIO_InitStructure);
       
          USART_InitStructure.USART_BaudRate = 115200;
          USART_InitStructure.USART_WordLength = USART_WordLength_8b;
          USART_InitStructure.USART_StopBits = USART_StopBits_1;
          USART_InitStructure.USART_Parity = USART_Parity_No ;                                                
                USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
                USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
          USART_Init(USART1,&USART_InitStructure);
               
                NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   
                NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                NVIC_Init(&NVIC_InitStructure);

                USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
               
                UARTRxBuffer = BufferCreate(512);
                UARTTxBuffer = BufferCreate(512);
               
                USART1_TX_DMA_Config();
                USART1_RX_DMA_Config();
               
                USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
                USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
                //USART_Cmd(USART1,ENABLE);
}

void USART1_RX_DMA_DeConfig(void)
{
                DMA_SetCurrDataCounter(DMA1_Channel5,512);
                DMA1_Channel5->CMAR = (u32)UARTRxBuffer->data;
}

void USART1_TX_DMA_Config(void)
{
                DMA_InitTypeDef DMA_InitStructure;
                NVIC_InitTypeDef NVIC_InitStructure;
               
                DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;        /*èDMAèù·*/
                DMA_InitStructure.DMA_MemoryBaseAddr = (u32)UARTTxBuffer->data;   /*·¨±*/
                DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                /*è*/
                DMA_InitStructure.DMA_BufferSize = 0;                             /*·ó*/
                DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  /*è·*/               
                DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;           /*·×*/
                DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
                DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
                DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;       
                DMA_InitStructure.DMA_Priority = DMA_Priority_High;             /**/       
                DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                      /*        */                          
                DMA_Init(DMA1_Channel4, &DMA_InitStructure);                      /*DMA14¨*/               
                NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
                NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                NVIC_Init(&NVIC_InitStructure);               
                DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);                     //DMA·êóúú
}

void USART1_RX_DMA_Config(void)
{       
                DMA_InitTypeDef DMA_InitStructure;               
               
                DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;       /*èDMAèù·*/
                DMA_InitStructure.DMA_MemoryBaseAddr = (u32)UARTRxBuffer->data;  /*·¨±*/       
                DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;               /*è*/       
                DMA_InitStructure.DMA_BufferSize = 512;                         /*ó*/
                DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*è·*/       
                DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;          /*·×*/
          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
                DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
                DMA_InitStructure.DMA_Priority = DMA_Priority_High;  /**/                       
                DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;           /*        */                  
                DMA_Init(DMA1_Channel5, &DMA_InitStructure);           /*DMA15¨*/
                DMA_Cmd (DMA1_Channel5,ENABLE);                                                       //DMA
}

int USART1SendBuffer(Buffer *buffer)
{
                if(sending == 1)
                {
                         return 0;
                }
          DMA_Cmd(DMA1_Channel4,DISABLE);
                DMA_SetCurrDataCounter(DMA1_Channel4,buffer->length - buffer->offset);
                DMA1_Channel4->CMAR = (u32)(buffer->data + buffer->offset);
                buffer->offset += (buffer->length - buffer->offset);
                sending = 1;
                DMA_Cmd(DMA1_Channel4,ENABLE);                                        //DMA
                return 0;
}

void DMA1_Channel4_IRQHandler(void)
{
          OSIntEnter();
                if(DMA_GetFlagStatus(DMA1_FLAG_TC4) == SET) //·ê,·íó
                {                                                                                                                                                                               
                                DMA_ClearFlag(DMA1_FLAG_TC4);           //±ê
                                BufferRebase(UARTTxBuffer);
                                sending = 0;
                                if(!BufferIsEmpty(UARTTxBuffer))
                                {
                                                USART1SendBuffer(UARTTxBuffer);
                                }
                                else
                                {
                                                DMA_Cmd(DMA1_Channel4,DISABLE);
                                }
                }
                OSIntExit();
}       

void USART1_IRQHandler(void)
{
                uint8_t dat;
          OSIntEnter();
                if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
                {                  
                          DMA_Cmd(DMA1_Channel5, DISABLE);
                                UARTRxBuffer->length = (512 - DMA_GetCurrDataCounter(DMA1_Channel5));
                          if(UARTRxBuffer->length - UARTRxBuffer->offset >= 3)
                                {
                                         HandlerSlamData();
                                }
                                DMA_Cmd(DMA1_Channel5, ENABLE);
                                USART_ClearITPendingBit(USART1, USART_IT_IDLE);
                                dat = USART1->SR;  //í
        dat = USART1->DR;                   
                }
                OSIntExit();
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-8-24 21:04:26 | 显示全部楼层
八成是内存地址乱飞了。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 17:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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