先上圖:stm32f303晶元,72m的主頻
可以看到gpio的達到了14.4m的翻轉速率,
再來上**:
rcc_ahbperiphclockcmd(rcc_ahbperiph_gpioc, enable);
gpioc->moder |= 0x55555555;
gpioc->ospeedr |= 0xfffffff;
gpioc->pupdr |= 0x55555555;
u32 gpio_data[4]= ;
dma_inittypedef dma_initstructure;
tim_timebaseinittypedef tim_timebasestructure;
nvic_inittypedef nvic_initstructure;
/* timx clock enable */
rcc_apb1periphclockcmd(rcc_apb1periph_tim4, enable);
/* dmax clock enable */
rcc_ahbperiphclockcmd(rcc_ahbperiph_dma1, enable);
dma_deinit(dma1_channel7);
dma_initstructure.dma_peripheralbaseaddr = (uint32_t)(&(gpioc->bsrr));
dma_initstructure.dma_memorybaseaddr = (uint32_t)gpio_data;
dma_initstructure.dma_dir = dma_dir_peripheraldst;
dma_initstructure.dma_buffersize = 4;
dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable;
dma_initstructure.dma_memoryinc = dma_memoryinc_enable;
dma_initstructure.dma_peripheraldatasize = dma_peripheraldatasize_word;
dma_initstructure.dma_memorydatasize = dma_memorydatasize_word;
dma_initstructure.dma_mode = dma_mode_circular;
dma_initstructure.dma_priority = dma_priority_veryhigh;
dma_initstructure.dma_m2m = dma_m2m_enable;
dma_init(dma1_channel7, &dma_initstructure);
dma1_channel7->ccr |= dma_ccr_en;
用dma記憶體到記憶體的模式,直接把gpio_data的資料迴圈的搬到gpioc的bsrr暫存器上來控制gpioc上電平的翻轉,這樣使得gpio的速度達到了最快,輸出70ns的脈寬,這已經是達到了dma匯流排頻寬的極限,要想再提高速度的話,就得提高stm32晶元的主頻。
再來看用**來實現的話,gpio能達到多快的速度。
先是用庫函式來操作,在main函式的while迴圈來翻轉電平
while(1)
可以看到最快只能輸出320ns的脈寬電平,而且高低電平脈寬還不一樣,那是因為處理while(1)占用了cpu的時間導致的。
再來看用暫存器直接操作gpio
while(1)
可以看到,最小脈寬電平可以達到40ns,直接操作暫存器的速度明顯要到庫函式操作要快好多,低電平的時間要比高電平的時間長很多,同樣也是因為處理while的原因。
用cpu操作暫存器可以達到最快的電平翻轉,但是這樣cpu的資源全用在這上面,不能再做其實的操作。如果用dma的話,完全可以不占用cpu資源來達到更高速率的gpio翻轉速度。假如我們要根據自己的需求來產生我們所需要的時序,那要怎樣做。其實也很簡單,我們只要用定時器觸發dma搬一次資料到bsrr暫存器,然後再通過調整gpio_data陣列裡的資料,就可以來實現我們所要的時序。
下面的**就是通過這種方式來實現讓gpioc產生1us脈寬的時鐘,
rcc_ahbperiphclockcmd(rcc_ahbperiph_gpioc, enable);
gpioc->moder |= 0x55555555;
gpioc->ospeedr |= 0xfffffff;
gpioc->pupdr |= 0x55555555;
u32 gpio_data[4]= ;
dma_inittypedef dma_initstructure;
tim_timebaseinittypedef tim_timebasestructure;
nvic_inittypedef nvic_initstructure;
/* timx clock enable */
rcc_apb1periphclockcmd(rcc_apb1periph_tim4, enable);
/* dmax clock enable */
rcc_ahbperiphclockcmd(rcc_ahbperiph_dma1, enable);
dma_deinit(dma1_channel7);
dma_initstructure.dma_peripheralbaseaddr = (uint32_t)(&(gpioc->bsrr));
dma_initstructure.dma_memorybaseaddr = (uint32_t)gpio_data;
dma_initstructure.dma_dir = dma_dir_peripheraldst;
dma_initstructure.dma_buffersize = 4;
dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable;
dma_initstructure.dma_memoryinc = dma_memoryinc_enable;
dma_initstructure.dma_peripheraldatasize = dma_peripheraldatasize_word;
dma_initstructure.dma_memorydatasize = dma_memorydatasize_word;
dma_initstructure.dma_mode = dma_mode_circular;
dma_initstructure.dma_priority = dma_priority_veryhigh;
dma_initstructure.dma_m2m = dma_m2m_disable;
dma_init(dma1_channel7, &dma_initstructure);
tim_timebasestructure.tim_period = 72;
tim_timebasestructure.tim_prescaler = 0x0;
tim_timebasestructure.tim_clockdivision = 0x0;
tim_timebasestructure.tim_countermode = tim_countermode_up;
tim_timebaseinit(tim4, &tim_timebasestructure);
tim_dmacmd(tim4, tim_dma_update, enable);
tim_selectoutputtrigger(tim4,tim_trgosource_update);
tim_cmd(tim4, enable);
dma1_channel7->ccr |= dma_ccr_en;
用DMA直接驅動GPIO,實現GPIO最高輸出速率
用dma直接驅動gpio,實現gpio最高輸出速率 先上圖 stm32f303晶元,72m的主頻 可以看到gpio的達到了14.4m的翻轉速率,再來上 rcc ahbperiphclockcmd rcc ahbperiph gpioc,enable gpioc moder 0x55555555 gp...
利用DMA實現取樣資料的直接搬運儲存
嘗試了下stm32的adc取樣,並利用dma實現取樣資料的直接搬運儲存,這樣就不用cpu去參與操作了。我這裡用了3路的adc通道,1路外部變阻器輸入,另外兩路是內部的溫度取樣和vrefint,這樣就能組成連續的取樣,來測試多通道adc自動掃瞄了,adc分規則轉換和注入轉換,其實規則轉換就是按照既定的...
直接用socket實現HTTP協議
直接用socket實現http協議 這個網頁 那麼請求頭的寫法如下 第2行 主機名,格式為 host 主機 在這個例子中是 host www.sina.com.cn 第4行 指定瀏覽器的型別 有些伺服器會根據客戶伺服器種類的不同會增加或減少一些內容,在這個例子中可以這樣寫 user agent mo...