问题:在程序执行过程中 BuleToothParaTest 函数中所有已大红字体引用的函数必须打断点,否则程序运行异常,单步执行程序正常。能否帮忙解答一下 //结构体定义部分 typedef struct ParamSend { uint8_t byte1;// 0x01 定值 uint8_t byte2_readWriteFlag;//read :0x29 write :0x27 uint8_t byte3;//0xfc 定值 uint8_t byte4_dataLen;//这个字节以后总的数据长度 uint8_t byte5_addrH; uint8_t byte6_addrL; uint8_t byte7_paramLen; /*以下字节是write 命令时需要的,read 不用管*/ uint8_t paramValue[16]; uint8_t actualLen;//实际发送的数据总长度 }ParamSendData, *pParamSendData; typedef struct ParamRece { uint8_t byte1;//0x04 定值 uint8_t byte2;//0x0e 定值 uint8_t byte3_dataLen;//这个字节以后总的数据长度 uint8_t byte4;//0x01 定值 uint8_t byte5;//read :0x29 write :0x27 uint8_t byte6;//0xfc 定值 uint8_t byte7_succesFlag;//写命令 回复到这个字节 /*以下两个字节是读命令时需要的*/ uint8_t byte8_addrH;//把这个写成分开的,是发送和接收都不用缓存区了,直接使用结构体地址进行缓存即可 uint8_t byte9_addrL; uint8_t byte10_paramLen; uint8_t paramValue[16];//read fail no this data uint8_t actualLen;//实际发送的数据总长度 } ParamRece_Data, *pParamReceData; //以下是变量定义部分 uint8_t blueTooth_Versionflag =0;//读取版本正确,这个标志位 置1 uint8_t paramReadFlag = 0;//配置模式下,读取蓝牙名称和写入的蓝牙名称一样 paramReadFlag=1,不同为0 char * name="MC2sfc_TEST";//写入新的蓝牙名称 //配置模式下 发送缓存的结构体 ParamSendData SendParamData = { 0x01, 0x29, }; //配置模式下 接收缓存的结构体 ParamRece_Data ReceParamData = { 0x04, 0x0e, }; //函数体部分 [url=]/**@content[/url]: 在配置模式下使用的函数 设置串口1的发送dma 和接收dma 通道号是固定的 **@arg TbufferAddr:发送缓冲区地址;TbufferAddr:发送长度;Tdatalen:接收缓冲区地址RbufferAddr :接收长度Rdatalen **@arg dir :方向位 0:先发送后接收; 1:先接收后发送 **@return:no **/ uint8_t Usart_DmaBufferConfig(uint32_t TbufferAddr, uint16_t Tdatalen, uint32_t RbufferAddr, uint16_t Rdatalen) { uint8_t reValue =0; DMA_InitTypeDef Dma_init; DMA_Cmd(DMA1_Channel5, DISABLE); //disable rx 重新设置前 必须先禁止模块,不然计数器无法设置 //rx Dma_init.DMA_DIR = DMA_DIR_PeripheralSRC; Dma_init.DMA_Priority = DMA_Priority_Low ; Dma_init.DMA_BufferSize =Rdatalen ; Dma_init.DMA_MemoryBaseAddr = RbufferAddr; Dma_init.DMA_PeripheralBaseAddr =(uint32_t)&USART1->DR; Dma_init.DMA_M2M = DMA_M2M_Disable; Dma_init.DMA_Mode = DMA_Mode_Normal; Dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable; Dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable; Dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; Dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // DMA_Init(DMA1_Channel5, &Dma_init); //tx DMA_Cmd(DMA1_Channel4, DISABLE); //disable tx 重新设置前 必须先禁止模块,不然计数器无法设置 Dma_init.DMA_DIR = DMA_DIR_PeripheralDST;//从存储器读 发送 读存储器的数据到串口的DR reg 中 Dma_init.DMA_Priority = DMA_Priority_Low; Dma_init.DMA_BufferSize =Tdatalen; Dma_init.DMA_MemoryBaseAddr = TbufferAddr; DMA_Init(DMA1_Channel4, &Dma_init); DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); USART_DMACmd(USART1,USART_DMAReq_Tx | USART_DMAReq_Rx,ENABLE); //使能串口1的DMA发送 接收 DMA_Cmd(DMA1_Channel5, ENABLE); //enable rx DMA_Cmd(DMA1_Channel4, ENABLE); //enable tx while( !DMA_GetFlagStatus(DMA1_FLAG_TC5)){}; DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_HT5 |DMA1_FLAG_TE5); DMA_ClearFlag(DMA1_FLAG_TC4 |DMA1_FLAG_GL4 |DMA1_FLAG_HT4); reValue =1; return reValue; } [url=]/**@content[/url]: 发送缓冲区read配置函数, **@arg paramLen :参数长度 ;startAddr:发送地址 ; SendData:发送缓冲区地址指针 **@return:no **/ void McuReadConfigParam(uint8_t paramLen, uint16_t startAddr, pParamSendData SendData ) { SendData ->byte1 = 0x01; SendData ->byte2_readWriteFlag = 0x29;//dir=read SendData ->byte3 =0xFC; SendData ->byte4_dataLen = 3; SendData ->byte5_addrH = startAddr >> 8 & 0xFF; SendData ->byte6_addrL = startAddr & 0xFF; SendData ->byte7_paramLen = paramLen; SendData -> actualLen = 7; // ParamSendDataConfig(SendData,&SendData -> actualLen, ReadBuffer); } [url=]/**@content[/url]: 发送缓冲区 write 配置函数, **@arg paramLen :参数长度 ;startAddr:发送地址 ;paramValue :写入的数据 SendData:发送缓冲区地址指针 **@return:no **/ void McuWriteConfigParam( uint8_t paramLen, uint16_t startAddr, char * paramValue, pParamSendData SendData ) { uint8_t i=0; SendData -> byte1 = 0x01; SendData -> byte2_readWriteFlag = 0x27;//dir=write SendData -> byte3 =0xFC; SendData -> byte4_dataLen = 3 + paramLen; SendData -> byte5_addrH = startAddr >> 8 & 0xFF; SendData -> byte6_addrL = startAddr & 0xFF; SendData -> byte7_paramLen = paramLen; for(i=0;i< paramLen; i++) SendData -> paramValue = *(paramValue + i); SendData -> actualLen = 7 + paramLen; // ParamSendDataConfig(SendData,&SendData -> actualLen , ReadBuffer); } [url=]/**@content[/url]: 波特率115200 全双工 1位停止位,无校验位 **@arg no **@return:no **/ void usart1_init(void) { USART_InitTypeDef usart1_init; usart1_init.USART_BaudRate =115200; usart1_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usart1_init.USART_Mode= USART_Mode_Rx|USART_Mode_Tx; usart1_init.USART_Parity = USART_Parity_No; usart1_init.USART_StopBits = USART_StopBits_1; usart1_init.USART_WordLength = USART_WordLength_8b; USART_Init(USART1, &usart1_init); USART_Cmd(USART1, ENABLE); //使能串口1 Gpio_Set_Do_TE(ST_GPIOA, 8, ST_DO_PP);//blue_tooth rst Gpio_Write_TE(ST_GPIOA, 8, 1); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); } [url=]/**@content[/url]: Crc_Calc_SUM 计算这个dataAddr 开始的dataLen字节长度的校验和 **@arg no **@return:no **/ static uint16_t Crc_Calc_SUM(uint8_t *dataAddr, uint16_t dataLen) { uint8_t tmp = 0; uint16_t value = 0; uint16_t i = 0; for(i=GL_VAL_ZERO; i<dataLen; i++) tmp += dataAddr; value = Type_U8_To_U16_TE(tmp); return value; } [url=]/**@content[/url]: BufferSetZero 设置buffer 地址 len 个地址的数据为0 **@arg no **@return:no **/ void BufferSetZero(uint8_t *buffer, uint8_t len) { uint8_t i = 0; for(; i < len ; i++) *(buffer + i) = 0; } [url=]/**@content[/url]: ChangeDmaLen 改变DMA发送或者接收 的字节长度 **@arg sentLen :USArt1 发送的字节长度; receLen :USArt1 接收的字节长度 **@return:no **/ void ChangeDmaLen(uint8_t sentLen, uint8_t receLen) { DMA_Cmd(DMA1_Channel4, DISABLE ); //关闭USART1 TX DMA1 所指示的通道 DMA_SetCurrDataCounter(DMA1_Channel4,sentLen);//DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel5, DISABLE ); //关闭USART1rX DMA1 所指示的通道 DMA_SetCurrDataCounter(DMA1_Channel5,receLen);//DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel4, ENABLE); //使能USART1 TX DMA1 所指示的通道 while( !DMA_GetFlagStatus(DMA1_FLAG_TC4)){}; DMA_Cmd(DMA1_Channel5, ENABLE); //使能USART1 rX DMA1 所指示的通道 DMA_ClearFlag(DMA1_FLAG_TC4 |DMA1_FLAG_GL4 |DMA1_FLAG_HT4); while( !DMA_GetFlagStatus(DMA1_FLAG_TC5)){}; DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_HT5 |DMA1_FLAG_TE5); } // 验证,在main函数中 main() { usart1_init(); BuleToothParaTest() } void BuleToothParaTest(void) { char * para = NULL; // //read version 0xAF, 0x43, 0x6F, 0x6E,\\ 0x66, 0x69, 0x67, 0x05 SendParamData.byte1 = 0xAF; SendParamData.byte2_readWriteFlag = 0x43; SendParamData.byte3 = 0x6f; SendParamData.byte4_dataLen = 0x6E; SendParamData.byte5_addrH = 0x66; SendParamData.byte6_addrL = 0x69; SendParamData.byte7_paramLen = 0x67; SendParamData.paramValue[0] = 0x05; SendParamData.actualLen =8; ReceParamData.actualLen =8; while(! Usart_DmaBufferConfig((uint32_t)&SendParamData, SendParamData.actualLen, (uint32_t)&ReceParamData, ReceParamData.actualLen)); if(Crc_Calc_SUM((uint8_t *)&ReceParamData, 7) == ReceParamData.byte8_addrH) { if((ReceParamData.byte4 << 24 | ReceParamData.byte5 << 16 | ReceParamData.byte6 << 8 | ReceParamData.byte7_succesFlag) == 0x34303130) { blueTooth_Versionflag = 1;//blueTooth_Versionflag 版本正确的标志位 } } //write1 McuWriteConfigParam( 11, 0x000B, name, &SendParamData); BufferSetZero((uint8_t *)&ReceParamData.byte1,26);//接收缓存区清0 ChangeDmaLen(7+11, 7);//开始 写 //read1 McuReadConfigParam(16, 0x000B, &SendParamData); BufferSetZero((uint8_t *)&ReceParamData.paramValue,16);//接收缓存区清0 ChangeDmaLen(7, 10+11); if(ReceParamData.byte7_succesFlag ==0) { para =(uint8_t *) &ReceParamData.paramValue; } if(strcmp(name,para) == 0) { McuWriteConfigParam( 11, 0x000B, name, &SendParamData); BufferSetZero((uint8_t *)&ReceParamData.byte1,26);//接收缓存区清0 ChangeDmaLen(7+11, 7);//开始 写 if(ReceParamData.byte7_succesFlag ==0) { BufferSetZero((uint8_t *)&ReceParamData.paramValue,26);//接收缓存区清0 McuReadConfigParam(11, 0x000B, &SendParamData); ChangeDmaLen(7, 10+11);//开始 read if(ReceParamData.byte7_succesFlag ==0) { if(strcmp(name,para) == 0) paramReadFlag = 1;//write new name success } } }else { //reset } } |
没见过在while(1)里不断把DMA初始化的用法,呵呵 |
问题已经解决了。 |