1. 程式人生 > >中科之旅------GD32 /stm32/mpc5604過程中遇到的問題

中科之旅------GD32 /stm32/mpc5604過程中遇到的問題

1.GD32 gpio配置問題,pc7作為timer7_ch1

在GD32F303xx_Datasheet_Rev1.2裡看到

而在GD32F30x_User_Manual_CN_V1.1裡則找不到一點pc7的資料,所以認為,由於這個gpio沒有remap的功能,所以GD32F30x_User_Manual_CN_V1.1裡就不特別說了,而如果要複用哪個功能就得先使能那個功能模組。

 

2.一開始不知道GD32的中斷函式定義在哪,原來在

C:\Users\Administrator\Desktop\ZKSS\GD32系列開發\GD32303C_START_GD32F30x_Firmware_Library_Routine_ANC\GD32303C_START_GD32F30x_Firmware_Library_Routine\Project\2_Systick_LED\MDK-ARM\list\GD32303C_START.map中。

 

3.GD32 DAC如何確定輸出電壓?

如果選擇8位的DAC,那麼最大值就是2的8次,對應3.3v,如果是選擇12位的DAC,那麼最大值就是2的12次,最大電壓同樣是3.3v

4.DAC 和DMA繫結,我用DMA ch1去繫結DAC1,發現不行直到看了這個圖

改用ch3搞定

 

4.用DAC+DMA功能的時候,DMA那邊配置為DMA_PERIPHERAL_WIDTH_32BIT的時候,出現了奇怪的現象,DAC只能8bit有效,哪怕地址是R12的地址,只有用DMA_PERIPHERAL_WIDTH_16BIT的時候才是12位地址有效

6.EEPROM一直讀不出正確值,看了spec發現

This pin must be connected to either VSS or VCC. If tied
to VSS, write operations are enabled. If tied to VCC,
write operations are inhibited but read operations are
not affected
 

5.用ADC自帶的測溫度功能,發現ADC0可以,ADC1不行,查了手冊

然後問了技術支援確認只有ADC0可以

 

6.之前參考example裡的running_led去操作gpio發現不對,看了資料手冊發現

 

原來這裡才是拉高拉低的正確方式

 

7.gd32 f303的can的波特率計算有問題

雖然資料手冊上是

然而最後算下來,其實真正波特率是這個的1/2,。。。。。,而且誤差必須控制在千分之5,比如500k的要求要千分之4左右

 

7.

gd405工程編譯遇到錯誤就把這些檔案拷到這個目錄即可

9.

新增#include <stdio.h>

 

10.

遇到這個問題,就重灌keil到c盤然後把patch也放在keil目錄下安裝,安裝目錄也選擇c盤的keil已經安裝好的目錄即可

 

11.gd32f405設定gpio為output高電平,用他的庫函式

gpio_mode_set(RCU_GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_8);
    gpio_output_options_set(RCU_GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);

    GPIO_BC(RCU_GPIOC) = GPIO_PIN_8;
    GPIO_BOP(RCU_GPIOC) = GPIO_PIN_8;居然連output都設定不了簡直垃圾,提醒大家千萬注意gd的庫錯誤巨多

後來改用

    GPIO_CTL(GPIOC) = 0x10000;
    GPIO_PUD(GPIOC) = 0x20000;
    GPIO_OCTL(GPIOC) = 0x100;直接寫才行了

 

12.配置PLLN的時候務必注意下圖

我之前設定了24結果無效,難怪串列埠的設定的波特率係數和計算的差一倍。然而後續太狗血了,哪怕plln有效,波特率依然要除以2

 

13.在ADC使用DMA功能的時候要注意

void adc_dma_mode_enable(uint32_t adc_periph)
{
    ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
    ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DDM); 一定要使能這個,因為原來的庫函式裡不使能,而且資料手冊很坑爹
}

該死不死寫什麼單次模式,其實掃描模式也要使能

 

14,關於管腳複用

 

15.gd的startup.s中可能會漏中斷

少了64號中斷

導致我的DMA中斷一直卡在default handler中。。。。。因為本來72的中斷向量變成了71.。。。

 

16.之前303的DMA中斷正常,但是405不行,後來發現

405還要設定這個PERIENN。而303不用

 

17.中斷裡用計數迴圈的話變數要定義成全域性變數,這樣會保持之前的值

 

18.keil配置gd405的時候

要選中這個ic才行,不能只選STM32F405這個大類

 

19.讀gpio狀態,雖然預設設定是輸入,但是時鐘一定要開起來

 rcu_periph_clock_enable(RCU_GPIOA);

 

20.i2s開發遇到的問題

首先是時鐘,可以選sysclk分頻,也可以選外接到I2S_CKIN引腳,然後需要在rcu那邊設定一下

還有個問題就是DMA和i2s直通,由於我配置的不是i2s1_add而是spi1,所以DMA這邊通道要選

通道4的功能0而不是功能2

還有spi那邊要把

傳送緩衝區DMA使能


21.如果要把jtdi複用成spi cs,先改複用暫存器,然後改成output模式即可

 

22.如果想要把一個char型別的陣列轉換成浮點數

typedef union 
{
int m;
float f;
}fnum;

    d.m = 0x3e800000;
    

d.f就是浮點數但是直接給d.f 0x3e800000賦值則不行。

 

23.如果想要獲取DMA2stream2的完成中斷

void DMA2_Stream2_IRQHandler(void)  
{
  if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_TCIF2)) //一定要注意DMA_IT_TCIF2這個要和stream對應上
      {
     for(i = 0; i < 4; i++)
                    {
                    tmp = ad_buff_a[i]*gain[i];
                    ad_buff_a[i] = tmp;
                    }

               //printf("%d\n",ad_buff_a[0]);
               set_dac1_out(ad_buff_a[0]);;
               set_dac2_out(ad_buff_a[1]);
               set_compare(1,ad_buff_a[2]);
               set_compare(2,ad_buff_a[3]);
               set_adc_finish = 1;
        
         DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2);
      }
}

24.DAC如果輸出幅值和預期相比較小的話,是因為outputbuffer沒有使能的緣故

 

25.ADC的RCC reset要注意

 

注意這個是所有ADC共用的,所以只要reset一次,千萬要注意不要重複reset

 

26.如果要從上位機往下傳資料,由於串列埠的資料型別是char,但是下位機需要float型別,那麼用這個辦法也不錯

假設我將uart的資料存在data指向的陣列中,那麼我的freq_data是一個包含float型別資料的結構體

struct freq_struct
{
    float  H_threshold;
    float  L_threshold;
   struct   para_conf_t freq_single[6];
};那麼直接copy進去即可,當然要注意資料的大小端問題

memcpy((unsigned char*)(&freq_data) + num_para,data,len);

 

27.今天用DMA+DAC傳送一個float型別的陣列,結果發現始終出現方波,照理我的資料全部大於零,應該是一條曲線才對,後來看了一下dma才發現

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; 
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; 

一開始我的size選的是半word,但是我的float型別的陣列單個長度是一個word,而float中的資料其實只有半個字的長度也就是前半個字是0,後半個字有效,這樣一來就出現了方波,這個問題也算自己想到了。

但是後續發現如果直接給DMA float型別的陣列的話,會出現傳輸錯誤    TEIFx:資料流 x 傳輸錯誤中斷標誌
 資料流 x 上發生傳輸錯誤,但是int就可以,可能我的float型別溢位了,因為DAC那邊顯示的錯誤是

DAC 1 通道發生 DMA 下溢錯誤狀況(當前所選觸發源以高於 DMA 服務能力的頻率驅動
DAC 1 通道轉換)
但是其實不是頻率而是資料格式問題。多大的資料用多大的size就對了

 

28.在搞mpc5604的gpio的時候發現一個問題

很多人很喜歡寫這樣的程式

void init_pin(void)
{
    SIU.PCR[18].R = 0x0600;  
    SIU.PCR[19].R = 0x0100;    

}這是uart的管腳配置

由於5604是大端模式,所以RX19管腳很好理解,因為

Alternate functions are chosen by setting the values of the PCR.PA bitfields inside the SIUL module.
PCR.PA = 00  AF0; PCR.PA = 01  AF1; PCR.PA = 10  AF2; PCR.PA = 11  AF3. This is intended to select
the output functions; to use one of the input functions, the PCR.IBE bit must be written to ‘1’, regardless of the
values selected in the PCR.PA bitfields. For this reason, the value corresponding to an input only function is
reported as “—”.
設成input的時候無所謂管腳複用,但是18管腳作為TX就有點奇怪了,為啥要射OBE為1呢,要知道

For output pads:
— Select the appropriate alternate function in Pad Config Register (PCR)
— OBE is not required for functions other than GPIO
所以其實OBE也是無所謂的

 

29.今天用一個stm32 的demo工程的時候,發現有句賦值語句 a = b始終無法被打斷點,後來才知道由於

這個Optimization是代表編譯優化等級,正常是0,但是那個demo是3,而我這個a沒有在別的地方用到,所以導致被優化而無法打斷點。

 

30.keil安裝的時候遇到了

Keil μVision Setup --Cannot create destination file. 'D:\Keil5\ARM\ARMCLANG\bin\ucrtbase.dll' System Error Code:  "拒絕訪問" 

 

 

原來是360的關係,退出360即可

 

31.如果遇到除錯的時候斷點打不上去,先檢查變數是否有重複定義

 

32.stm32下載一定要選