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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2454|回復: 0
打印 上一主題 下一主題
收起左側

stm32問題匯總

[復制鏈接]
跳轉到指定樓層
樓主
ID:85764 發表于 2015-7-17 00:16 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 niujia 于 2015-7-17 00:18 編輯

1 在flash中跑程序時,能進入中斷,但在ram中跑時,進不了中斷的原因。
看以下的中斷配置函數可以知道,要在ram中調試程序,需要定義VECT_TAB_RAM。
定義方法a:在Project\Options for taget 'xxx'的對話框的c/c++中定義宏VECT_TAB_RAM

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


void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM  

  NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else

  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);   
#endif


  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 函數不能進入。
原先初始化的語句為
SysTick_Config();

修改為以下時可以進入
SysTick_Config();
SysTick_CounterCmd(SysTick_Counter_Enable);

3 如何解決鏈接時錯誤"..\obj\LowCostDA.axf: Error: L6218E: Undefinedsymbol assert_failed (referred from stm32f10x_flash.o)."?
如果所加入的庫是STM32F10xD.LIB(即調試模式庫),則需要在無論什么得放添加函數定義
void assert_failed(u8* file, u32 line)
{
   
  while (1)
  {
  }
}

如果所加入的庫是STM32F10xR.LIB(即發布模式庫),則不會報錯。

4 打開中斷的時機不正確,導致無法進行任務切換。

由于我過早地打開了 SysTick 中斷,而我在SysTickHandler 中有如下語句:

{

...

OS_ENTER_CRITICAL();
   OSIntNesting++;
   OS_EXIT_CRITICAL();

   OSTimeTick();      

   OSIntExit();
...

}

因為打開過早,因此 OSIntNesting++能夠執行,而OSIntExit函數卻沒有把OSIntNesting減1.因此,導致了無法進行任務切換。


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


5 程序中只要使用了printf函數,就會執行到BKTP語句掛掉。

解決方法:Project\Options  Target選項頁中選中 UseMicroLIB

關于 MicroLIB的詳細說明見網友文章



6 參考99的rtc時鐘的使用方法,出現問題并順利解決。

在程序中我修改當前時間是調用的以下函數
void Time_SetUnixTime(time_t t)
{
   RTC_WaitForLastTask();
   RTC_SetCounter((u32)t);
   
   RTC_WaitForLastTask();
   return;
}
但是程序會一直運行在 RTC_WaitForLastTask 中無法出來。

最終順利解決。
99所介紹的程序啟動是配置rtc的函數如下:

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

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

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

#ifdef RTCClockOutput_Enable
   
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR |RCC_APB1Periph_BKP, ENABLE);

   
   PWR_BackupAccessCmd(ENABLE);

   
   BKP_TamperPinCmd(DISABLE);

   
   BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif

   return;
}

要調用Time_SetUnixTime設置時間 應該在if分支里邊。

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


7 關于堆棧對齊的問題
程序中出現了一個奇怪的問題
char g_cpTask2Buffer[200];

void Task2(void *arg)
{
...

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

}

ADCInfoArray[0].m_fVolt是一個float值。

在執行完 sprintf后,無論m_fVolt是多少,始終得到的g_cpTask2Buffer的內容都是"0.000"。

調試了好幾天的匯編終于解決了問題,根源竟然是ucos的堆棧需要以8字節對齊。

Task2是一個ucos的任務,Stack2 是Task2的任務堆棧。

如果是以下形式則出錯:

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

為什么 sprintf在Task2的中,但是執行結果的正確與否卻看起來似乎與Task3的任務堆棧Stack3相關?

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


為什么堆棧必須要8字節對齊?
因為在匯編中有這樣的語句:
BIC     r0,r2,#0x07   

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

該匯編的意思是把r2的最低一個字節的二進制最后3位清零,即把r2變為形如16進制xxxxxxx0或者xxxxxxx8,然后放入r0。

可以看到該地址必然是8字節對齊的。


最根本的原因我仍然沒有找到,但算是解決了問題。


8 外部sram用作堆棧的一個問題

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

OS_STK Stack1[STKSIZE] __at (Bank1_SRAM3_ADDR) ;

但是沒有想到的是,在使用sdio方式操作sd卡時,總是出現SDIO_IT_TXUNDERR 中斷。

沒有好的解決辦法,只能老老實實地把任務堆棧放入片內的sram。

想來,恐怕原因是系統在和SD卡交換數據時用到了任務堆棧區,而任務堆棧區所在的片外的sram速度不夠快導致的問題。

雖然問題湊合解決了,但是問題仍然存在:

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

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


9 鬧鐘中斷的問題(RTCAlarm)

打算在standby模式下使用鬧鐘中斷,但由于standby模式調試不方便,因此在正常運行狀態下先測試鬧鐘中斷。

沒想到遇到了問題:
關掉了RTC_IRQHandler,只打開RTCAlarm_IRQHandler。但是依然能進入RTC_IRQHandler中斷函數,但不是正常狀態下的進,而是不停地進中斷,
而且RTC_GetITStatus(RTC_IT_SEC)得到狀態也確實不是秒中斷發生。

同時,也會進RTCAlarm_IRQHandler中斷,也不是正常狀態下的進,而是不停地進中斷,而且RTC_GetITStatus(RTC_IT_ALR)得到狀態也確實不是鬧鐘中斷發生。

最終找到了問題所在:
一定要在RTCAlarm_IRQHandler函數中有這句:EXTI_ClearITPendingBit(EXTI_Line17);
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产综合av | 国产欧美视频一区二区 | 亚洲视频欧美视频 | 粉嫩粉嫩芽的虎白女18在线视频 | 99av成人精品国语自产拍 | 国产精品久久久久久久久 | 男女免费在线观看视频 | 亚洲一区二区三区久久 | 精品产国自在拍 | 国产精品不卡一区二区三区 | av一区在线观看 | 欧美一区二区网站 | 午夜视频在线 | a级毛片毛片免费观看久潮喷 | 欧美日韩a | 国产色视频网站 | 国产91精品网站 | 成人伊人| 午夜久久av | 成人久久久 | 999国产精品视频 | 美日韩免费 | 亚洲午夜av | 国产av毛片| 亚洲精品一二三区 | 国产免费一区二区 | 蜜桃在线一区二区三区 | 亚洲一区在线观看视频 | 精品一区二区在线观看 | 精品亚洲一区二区三区 | 国产亚洲成av人在线观看导航 | 九九综合 | www.日韩免费 | 人人天天操 | 欧美黑人体内she精在线观看 | 视频精品一区二区三区 | 精品国产色 | 欧洲精品一区 | 欧美久久久久 | 日韩电影中文字幕在线观看 | 久久伊人亚洲 |