久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4723|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

新手玩STM32F1x遇到的常見(jiàn)問(wèn)題及解決措施

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:142045 發(fā)表于 2018-7-6 11:07 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
1 在flash中跑程序時(shí),能進(jìn)入中斷,但在ram中跑時(shí),進(jìn)不了中斷的原因。
看以下的中斷配置函數(shù)可以知道,要在ram中調(diào)試程序,需要定義VECT_TAB_RAM。
定義方法a:在Project\Options for taget 'xxx' 的對(duì)話框的c/c++中定義宏VECT_TAB_RAM

定義方法b:在程序中直接定義


void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM  
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif

  /* Configure and enable ADC interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

2 SysTickHandler 函數(shù)不能進(jìn)入。
原先初始化的語(yǔ)句為
SysTick_Config();

修改為以下時(shí)可以進(jìn)入
SysTick_Config();
SysTick_CounterCmd(SysTick_Counter_Enable);

3 如何解決鏈接時(shí)錯(cuò)誤"..\obj\LowCostDA.axf: Error: L6218E: Undefined symbol assert_failed (referred from stm32f10x_flash.o)."?
如果所加入的庫(kù)是STM32F10xD.LIB(即調(diào)試模式庫(kù)),則需要在無(wú)論什么得放添加函數(shù)定義
void assert_failed(u8* file, u32 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)
  {
  }
}

如果所加入的庫(kù)是STM32F10xR.LIB(即發(fā)布模式庫(kù)),則不會(huì)報(bào)錯(cuò)。

4 打開(kāi)中斷的時(shí)機(jī)不正確,導(dǎo)致無(wú)法進(jìn)行任務(wù)切換。

由于我過(guò)早地打開(kāi)了 SysTick 中斷,而我在SysTickHandler 中有如下語(yǔ)句:

{

...

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();  
...

}

因?yàn)榇蜷_(kāi)過(guò)早,因此 OSIntNesting++ 能夠執(zhí)行,而OSIntExit函數(shù)卻沒(méi)有把OSIntNesting減1.因此,導(dǎo)致了無(wú)法進(jìn)行任務(wù)切換。


注意2點(diǎn)可以避免該情況:
a 同時(shí)使用 OSIntExit(); 和OSIntEnter(); 而不是像我這樣使用OSIntNesting++ 和OSIntExit()。
b 開(kāi)中斷要在操作系統(tǒng)初始化后完成,即在OSStart之后。

5 程序中只要使用了printf函數(shù),就會(huì)執(zhí)行到BKTP語(yǔ)句掛掉。

解決方法:Project\Options  Target選項(xiàng)頁(yè)中選中 Use MicroLIB

關(guān)于 MicroLIB的詳細(xì)說(shuō)明見(jiàn)網(wǎng)友文章


6 參考99的rtc時(shí)鐘的使用方法,出現(xiàn)問(wèn)題并順利解決。

在程序中我修改當(dāng)前時(shí)間是調(diào)用的以下函數(shù)
void Time_SetUnixTime(time_t t)
{
    RTC_WaitForLastTask();
    RTC_SetCounter((u32)t);
   
    RTC_WaitForLastTask();
    return;
}
但是程序會(huì)一直運(yùn)行在 RTC_WaitForLastTask 中無(wú)法出來(lái)。

最終順利解決。
99所介紹的程序啟動(dòng)是配置rtc的函數(shù)如下:

void RTC_Config(void)
{
    //我們?cè)贐KP的后備寄存器1中,存了一個(gè)特殊字符0xA5A5
    //第一次上電或后備電源掉電后,該寄存器數(shù)據(jù)丟失,
    //表明RTC數(shù)據(jù)丟失,需要重新配置
    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
    {
        //重新配置RTC
        RTC_Configuration();
        //配置完成后,向后備寄存器中寫(xiě)特殊字符0xA5A5
        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
    }
    else
    {
        //若后備寄存器沒(méi)有掉電,則無(wú)需重新配置RTC
        //這里我們可以利用RCC_GetFlagStatus()函數(shù)查看本次復(fù)位類(lèi)型
        if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
        {
            //這是上電復(fù)位
        }
        else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
        {
            //這是外部RST管腳復(fù)位
        }
        //清除RCC中復(fù)位標(biāo)志
        RCC_ClearFlag();

        //雖然RTC模塊不需要重新配置,且掉電后依靠后備電池依然運(yùn)行
        //但是每次上電后,還是要使能RTCCLK???????
        //RCC_RTCCLKCmd(ENABLE);
        //等待RTC時(shí)鐘與APB1時(shí)鐘同步
        //RTC_WaitForSynchro();

        //使能秒中斷
        RTC_ITConfig(RTC_IT_SEC, ENABLE);
        //等待操作完成
        RTC_WaitForLastTask();
    }

#ifdef RTCClockOutput_Enable
    /* Enable PWR and BKP clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* Allow access to BKP Domain */
    PWR_BackupAccessCmd(ENABLE);

    /* Disable the Tamper Pin */
    BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
                                 functionality must be disabled */

    /* Enable RTC Clock Output on Tamper Pin */
    BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif

    return;
}

要調(diào)用Time_SetUnixTime設(shè)置時(shí)間 應(yīng)該在if分支里邊。

而不是在else分支里邊。
我正好是犯了這樣的錯(cuò)誤。


7 關(guān)于堆棧對(duì)齊的問(wèn)題
程序中出現(xiàn)了一個(gè)奇怪的問(wèn)題
char g_cpTask2Buffer[200];

void Task2(void *arg)
{
...

sprintf(g_cpTask2Buffer,"%.3f", ADCInfoArray[0].m_fVolt);
...

}

ADCInfoArray[0].m_fVolt是一個(gè)float值。

在執(zhí)行完 sprintf 后,無(wú)論m_fVolt是多少,始終得到的g_cpTask2Buffer的內(nèi)容都是"0.000"。

調(diào)試了好幾天的匯編終于解決了問(wèn)題,根源竟然是ucos的堆棧需要以8字節(jié)對(duì)齊。

Task2是一個(gè)ucos的任務(wù),Stack2 是Task2的任務(wù)堆棧。

如果是以下形式則出錯(cuò):

Stack2                                   0x200084ac   Data         804  main.o(.bss)
Stack3                                   0x200087d0   Data         800  main.o(.bss)
如果是以下形式則不出錯(cuò):
Stack2                                   0x200084ac   Data         800  main.o(.bss)
Stack3                                   0x200087cc   Data         800  main.o(.bss)

為什么 sprintf在Task2 的中,但是執(zhí)行結(jié)果的正確與否卻看起來(lái)似乎與Task3的任務(wù)堆棧Stack3相關(guān)?

原因是,任務(wù) Task2 的堆棧頂實(shí)際上位于Stack2 + (Stack2STKSIZE - 1),該值正好與Stack3
相連。


為什么堆棧必須要8字節(jié)對(duì)齊?
因?yàn)樵趨R編中有這樣的語(yǔ)句:
BIC      r0,r2,#0x07   

該句得到double型值(在處理過(guò)程中,m_fVolt先從float被轉(zhuǎn)換為double型) 的存儲(chǔ)地址。

該匯編的意思是把r2的最低一個(gè)字節(jié)的二進(jìn)制最后3位清零,即把r2變?yōu)樾稳?6進(jìn)制xxxxxxx0或者xxxxxxx8,然后放入r0。

可以看到該地址必然是8字節(jié)對(duì)齊的。


最根本的原因我仍然沒(méi)有找到,但算是解決了問(wèn)題。

8 外部sram用作堆棧的一個(gè)問(wèn)題

系統(tǒng)中使用了ucos,由于任務(wù)堆棧的空間需要的比較多,因此把其放到了外部sram中,使用這樣的語(yǔ)句:

OS_STK Stack1[STKSIZE] __at (Bank1_SRAM3_ADDR) ;

但是沒(méi)有想到的是,在使用sdio方式操作sd卡時(shí),總是出現(xiàn)SDIO_IT_TXUNDERR 中斷。

沒(méi)有好的解決辦法,只能老老實(shí)實(shí)地把任務(wù)堆棧放入片內(nèi)的sram。

想來(lái),恐怕原因是系統(tǒng)在和SD卡交換數(shù)據(jù)時(shí)用到了任務(wù)堆棧區(qū),而任務(wù)堆棧區(qū)所在的片外的sram速度不夠快導(dǎo)致的問(wèn)題。

雖然問(wèn)題湊合解決了,但是問(wèn)題仍然存在:

外部sram到底能怎么用? 如果外部sram能和片內(nèi)的sram一樣方便地使用就好了。

看到這篇博客的朋友,有沒(méi)有什么好的解決辦法?


9 鬧鐘中斷的問(wèn)題(RTCAlarm)

打算在standby模式下使用鬧鐘中斷,但由于standby模式調(diào)試不方便 ,因此在正常運(yùn)行狀態(tài)下先測(cè)試鬧鐘中斷。

沒(méi)想到遇到了問(wèn)題:
關(guān)掉了RTC_IRQHandler,只打開(kāi)RTCAlarm_IRQHandler。但是依然能進(jìn)入RTC_IRQHandler中斷函數(shù),但不是正常狀態(tài)下的進(jìn),而是不停地進(jìn)中斷,
而且RTC_GetITStatus(RTC_IT_SEC)得到狀態(tài)也確實(shí)不是秒中斷發(fā)生。

同時(shí),也會(huì)進(jìn)RTCAlarm_IRQHandler中斷,也不是正常狀態(tài)下的進(jìn),而是不停地進(jìn)中斷,而且RTC_GetITStatus(RTC_IT_ALR)得到狀態(tài)也確實(shí)不是鬧鐘中斷發(fā)生。

最終找到了問(wèn)題所在:
一定要在RTCAlarm_IRQHandler函數(shù)中有這句:EXTI_ClearITPendingBit(EXTI_Line17);

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日本高清中文字幕 | 国产视频福利在线观看 | 欧美一区二区三区四区在线 | 成人精品视频 | 国产精品欧美一区喷水 | av官网在线 | 国产精品久久久久无码av | 精品国产一二三区 | 91成人在线| 国产精品亚洲欧美日韩一区在线 | 亚洲精品久久久久久一区二区 | 欧美二级| 亚洲aⅴ | 精品国产一区二区 | 欧美一级欧美三级在线观看 | 99伊人 | 亚洲视频在线免费观看 | 99这里只有精品 | 91久久久久 | 黄色毛片黄色毛片 | 国产精品99久久久久久久久 | 日韩第一区 | 在线视频 中文字幕 | 国产一区二区三区免费 | 国产精品毛片无码 | 国产区高清 | 日本国产欧美 | 国产在线一区二区 | 在线播放中文字幕 | 色婷婷狠狠 | 中文字幕av网站 | 一级全黄少妇性色生活免费看 | 中文字幕乱码亚洲精品一区 | 国产成人精品一区二区 | 亚洲人成在线播放 | 亚洲国产一区在线 | 中文字幕亚洲视频 | 久久一区二区三区四区 | 欧美13videosex性极品 | 日本精品久久 | 免费精品 |