本篇內(nèi)容介紹了“c#代碼Bug怎么解決”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專注于企業(yè)營(yíng)銷型網(wǎng)站、網(wǎng)站重做改版、通州網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為通州等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
這是一個(gè)比較常見(jiàn)也比較容易忽略的問(wèn)題,從學(xué)習(xí)C語(yǔ)言數(shù)組開(kāi)始,我們就被告知數(shù)組的下標(biāo)從0開(kāi)始,但是我們?cè)趯?shí)際的案例應(yīng)用中,序號(hào)一般都是從1開(kāi)始。在一次實(shí)際的應(yīng)用中,采集板采集通道1-通道6的數(shù)值,主控板也對(duì)應(yīng)的定義了一個(gè)大小為6的數(shù)據(jù)緩沖區(qū),index從0到5,采集板采集完六個(gè)通道的數(shù)據(jù),將數(shù)據(jù)按照幀首、通道號(hào)、采樣值、幀尾的格式進(jìn)行打包,然后發(fā)送給主控板,主控則對(duì)應(yīng)的根據(jù)通道號(hào)將采樣值存儲(chǔ)到緩沖區(qū),因?yàn)槭韬鼍幋a時(shí)采集板的通道號(hào)是從1到6寫(xiě)入數(shù)據(jù)幀的,所以當(dāng)主控板接收到通道號(hào)為6的數(shù)據(jù)幀就出現(xiàn)了數(shù)組越界存儲(chǔ)了,此時(shí)軟件就進(jìn)入HardFault死循環(huán)里面了。
void HardFault_Handler(void){ /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } }
//Righthost_control_slave[2] = (gRtcDate&0xFF0000) >> 16; host_control_slave[3] = (gRtcDate&0xFF00) >> 8; host_control_slave[4] = gRtcDate & 0xFF;//Errorhost_control_slave[2] = gRtcDate & 0xFF0000 >> 16; host_control_slave[3] = gRtcDate & 0xFF00 >> 8; host_control_slave[4] = gRtcDate & 0xFF;
左右移運(yùn)算符和按位與或運(yùn)算符的結(jié)合性都是自左向右,前者的優(yōu)先級(jí)高于后者,所以上面兩段代碼塊會(huì)得出不同的結(jié)果,后面一段代碼會(huì)先進(jìn)行右移運(yùn)算,再進(jìn)行按位與的運(yùn)算。我比較懶,一般不怎么去記優(yōu)先級(jí)順序表,一般都是用()來(lái)框起來(lái),這樣也有一定的弊端,就是太多括弧看起來(lái)也很費(fèi)勁,所以還是建議常用的一些運(yùn)算符優(yōu)先級(jí)順序還是要記一下。
void GpioConfigInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //設(shè)置GPIOC_12為推挽輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設(shè)置GPIOC_13為上拉輸入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); }
在實(shí)際的嵌入式項(xiàng)目中,操作GPIO是比較普遍的,但是也隱藏了一些潛在的坑,上面的初始化函數(shù)在配置完GPIOC_12和GPIO_13之后,GPIOC_12的推挽輸出其實(shí)是沒(méi)有配置成功的,因?yàn)榇撕瘮?shù)中在最后進(jìn)行了一次結(jié)構(gòu)體初始化的操作,相當(dāng)于只是把GPIOC_13的模式寫(xiě)入了結(jié)構(gòu)體參數(shù),所以此時(shí)兩個(gè)IO口的模式均為上拉輸入,具體我們來(lái)分析下GPIO這個(gè)結(jié)構(gòu)體的成員參數(shù):
/** * @brief GPIO Init structure definition */typedef struct{ uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This parameter can be any value of @ref GPIO_pins_define */ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. This parameter can be a value of @ref GPIOSpeed_TypeDef */ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. This parameter can be a value of @ref GPIOMode_TypeDef */}GPIO_InitTypeDef;/** * @brief Initializes the GPIOx peripheral according to the specified * parameters in the GPIO_InitStruct. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that * contains the configuration information for the specified GPIO peripheral. * @retval None */void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct){ uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00; uint32_t tmpreg = 0x00, pinmask = 0x00; /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); /*---------------------------- GPIO Mode Configuration -----------------------*/ currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) { /* Check the parameters */ assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); /* Output mode */ currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; }/*---------------------------- GPIO CRL Configuration ------------------------*/ /* Configure the eight low port pins */ if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) { tmpreg = GPIOx->CRL; for (pinpos = 0x00; pinpos < 0x08; pinpos++) { pos = ((uint32_t)0x01) << pinpos; /* Get the port pins position */ currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; if (currentpin == pos) { pos = pinpos << 2; /* Clear the corresponding low control register bits */ pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { GPIOx->BRR = (((uint32_t)0x01) << pinpos); } else { /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << pinpos); } } } } GPIOx->CRL = tmpreg; }/*---------------------------- GPIO CRH Configuration ------------------------*/ /* Configure the eight high port pins */ if (GPIO_InitStruct->GPIO_Pin > 0x00FF) { tmpreg = GPIOx->CRH; for (pinpos = 0x00; pinpos < 0x08; pinpos++) { pos = (((uint32_t)0x01) << (pinpos + 0x08)); /* Get the port pins position */ currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); if (currentpin == pos) { pos = pinpos << 2; /* Clear the corresponding high control register bits */ pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); } /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); } } } GPIOx->CRH = tmpreg; } }
上述的函數(shù)會(huì)把GPIO的引腳、速度、模式,寫(xiě)入到相關(guān)的寄存器中去,在GpioConfigInit()函數(shù)中如果只寫(xiě)入一次引腳、速度、模式等參數(shù),那么只會(huì)以最后一次的參數(shù)為準(zhǔn),因?yàn)檫@里定義的結(jié)構(gòu)體變量為局部變量,在配置GPIOC_13時(shí)又重新被賦值,然后再被寫(xiě)入,所以就會(huì)出現(xiàn)GPIOC_12模式配置失敗的問(wèn)題,正確的配置函數(shù)為:
void GpioConfigInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //設(shè)置GPIOC_12為推挽輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); //設(shè)置GPIOC_13為上拉輸入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); }
提高觸摸屏的刷新頻率主要是為了提高用戶體驗(yàn)感,讓用戶用起來(lái)感覺(jué)更加流暢,但是也不是越快越好,最好要參考觸摸屏廠商提供的推薦刷新頻率來(lái)設(shè)置,如下為某款觸摸屏的推薦參數(shù):
MCU不要頻繁向串口屏發(fā)送數(shù)據(jù),否則串口屏的內(nèi)部緩存區(qū)會(huì)滿,從而導(dǎo)致數(shù)據(jù)丟失(緩沖區(qū)大小:標(biāo)準(zhǔn)型8K,基本型4.7K) |
---|
1) 一般情況下,控制MCU向串口屏發(fā)送數(shù)據(jù)的周期大于100ms,就可以避免數(shù)據(jù)丟失的問(wèn)題; |
2) 如果仍然有數(shù)據(jù)丟失的問(wèn)題,請(qǐng)判斷串口屏的BUSY引腳,為高時(shí)不能發(fā)送數(shù)據(jù)給串口屏。 |
我之前試過(guò)10ms來(lái)刷新一些參數(shù),然后發(fā)現(xiàn)觸摸屏的其他一些操作就非??D,因?yàn)橛|摸屏自帶的MCU一直在不斷的進(jìn)入數(shù)據(jù)接收中斷并需要不斷的處理,有時(shí)候還會(huì)出現(xiàn)數(shù)據(jù)亂碼,其原因也就是內(nèi)部的一級(jí)緩沖區(qū)產(chǎn)生了溢出。
在編程過(guò)程中,我一般將指針數(shù)組用來(lái)存放字符串信息,如下代碼塊:
const char *ErrInf[5] = { "光子計(jì)數(shù)器故障!", "空杯測(cè)試故障!", "溫控儀通訊故障!", "打印機(jī)缺紙!", "過(guò)溫或欠溫!"};
那我們看下這些字符串信息如何在內(nèi)存中存儲(chǔ):
/*! * \brief 文本框更新 * \param screen_id 畫(huà)面ID * \param control_id 控件ID */void WriteTextValue(uint16 screen_id, uint16 control_id, uint8 *pData, uint16 nDataLen){ BEGIN_CMD(); TX_8(0xB1); TX_8(0x10); TX_16(screen_id); TX_16(control_id); SendNU8(pData, nDataLen); END_CMD(); }
如果需要更新上面的第一個(gè)字符串信息,就該按照如下來(lái)調(diào)用文本框更新函數(shù):
//RightWriteTextValue(0x01, 0x01, (uint8*)ErrInf[0], strlen(ErrInf[0]));//ErrorWriteTextValue(0x01, 0x01, (uint8*)&ErrInf[0], strlen(ErrInf[0]));
因?yàn)榈谝粋€(gè)字符串存儲(chǔ)的首地址為ErrInf[0],而非&ErrInf[0],&ErrInf[0]是ErrInf[0]的地址,這兩個(gè)地址是有區(qū)別的,所以千萬(wàn)不要加取地址符&。
typedef struct{ char *HybDenName; u8 SetHybDenTemp[2]; u32 SetHybDenTime[2]; }HybDenPrgPara_TypeDef;typedef struct{ u8 HybDenRow; u8 HybRow; u8 MulRow; u8 HybDenCol; u8 MulCol; }PrgFlowIndex_TypeDef; HybDenPrgPara_TypeDef HybDenFlowPara[PRG_FLOW_NUM_MAX] = { {"DenHyb01", 0, 0, 0, 0}, {"DenHyb02", 0, 0, 0, 0}, {"DenHyb03", 0, 0, 0, 0}, {"DenHyb04", 0, 0, 0, 0}, {"DenHyb05", 0, 0, 0, 0}, {"DenHyb06", 0, 0, 0, 0}, {"DenHyb07", 0, 0, 0, 0}, {"DenHyb08", 0, 0, 0, 0}, {"DenHyb09", 0, 0, 0, 0}, {"DenHyb10", 0, 0, 0, 0}, }; PrgFlowIndex_TypeDef PrgFlowIndex = {0x00, 0x00, 0x00, 0x00, 0x00};//code blockcase LoadPgUp: { if(0x00 == PrgFlowIndex.HybDenRow) { PrgFlowIndex.HybDenRow = PRG_FLOW_NUM_MAX-0x01; } else { PrgFlowIndex.HybDenRow--; } //在程序加載界面、運(yùn)行界面、名稱編輯寫(xiě)入新的程序名稱 SetTextValue(HybDenLoad, LoadName, (u8*)HybDenFlowPara[PrgFlowIndex.HybDenRow].HybDenName); SetTextValue(HybDenRun, LoadName, (u8*)HybDenFlowPara[PrgFlowIndex.HybDenRow].HybDenName); SetTextValue(HybDenNameEdit, LoadName, (u8*)HybDenFlowPara[PrgFlowIndex.HybDenRow].HybDenName); break; }
如果將PrgFlowIndex.HybDenRow--放置到if-else之前會(huì)引發(fā)什么問(wèn)題?當(dāng)PrgFlowIndex.HybDenRow等于0時(shí),再自減1,其值就變成了255,下面的SetTextValue()函數(shù)在寫(xiě)入結(jié)構(gòu)體數(shù)組參數(shù)時(shí)就會(huì)寫(xiě)入到非法的內(nèi)存中去,也會(huì)造成HardFault錯(cuò)誤。
“c#代碼Bug怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
本文名稱:c#代碼Bug怎么解決
網(wǎng)頁(yè)鏈接:http://sd-ha.com/article18/jsjigp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開(kāi)發(fā)、自適應(yīng)網(wǎng)站、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站收錄、小程序開(kāi)發(fā)、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)