娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

STM32 DMA

發(fā)布者:EternalWhisper最新更新時間:2024-10-14 來源: cnblogs關(guān)鍵字:STM32  DMA  直接存儲器訪問 手機(jī)看文章 掃描二維碼
隨時隨地手機(jī)看文章

DMA,全稱為:Direct Memory Access,即直接存儲器訪問,DMA  傳輸將數(shù)據(jù)從一個地址空間復(fù)制到另外一個地址空間。當(dāng)  CPU  初始化這個傳輸動作,傳輸動作本身是由DMA  控制器  來實行和完成。典型的例子就是移動一個外部內(nèi)存的區(qū)塊到芯片內(nèi)部更快的內(nèi)存區(qū)。像是這樣的操作并沒有讓處理器工作拖延,反而可以被重新排程去處理其他的工作。

DMA  傳輸對于高效能嵌入式系統(tǒng)算法和網(wǎng)絡(luò)是很重要的。DMA 傳輸方式無需 CPU 直接控制傳輸,也沒有中斷處理方式那樣保留現(xiàn)場和恢復(fù)現(xiàn)場的過程,通過硬件為 RAM 與 I/O 設(shè)備開辟一條直接傳送數(shù)據(jù)的通路,能使 CPU 的效率大為提高。DMA 是個非常好的功能,它不但能減輕 CPU 負(fù)擔(dān),還能提高數(shù)據(jù)傳輸速度

STM32 最多有 2 個 DMA 控制器(DMA2 僅存在大容量產(chǎn)品中),DMA1 有 7 個通道。DMA2 有 5個通道。每個通道專門用來管理來自于一個或多個外設(shè)對存儲器訪問的請求。還有一個仲裁起來協(xié)調(diào)各個 DMA 請求的優(yōu)先權(quán)。


STM32 的 DMA 有以下一些特性: 

●每個通道都直接連接專用的硬件 DMA 請求,每個通道都同樣支持軟件觸發(fā)。這些功能通過軟件來配置。 

●在七個請求間的優(yōu)先權(quán)可以通過軟件編程設(shè)置(共有四級:很高、高、中等和低),假如在相等優(yōu)先權(quán)時由硬件決定(請求 0 優(yōu)先于請求 1,依此類推)  。 

●獨立的源和目標(biāo)數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字),模擬打包和拆包的過程。源和目標(biāo)地址必須按數(shù)據(jù)傳輸寬度對齊。 

●支持循環(huán)的緩沖器管理 

●每個通道都有 3 個事件標(biāo)志(DMA  半傳輸,DMA 傳輸完成和 DMA 傳輸出錯),這 3 個事件標(biāo)志邏輯或成為一個單獨的中斷請求。 

●存儲器和存儲器間的傳輸 

●外設(shè)和存儲器,存儲器和外設(shè)的傳輸 

●閃存、SRAM、外設(shè)的 SRAM、APB1 APB2 和 AHB 外設(shè)均可作為訪問的源和目標(biāo)。 

●可編程的數(shù)據(jù)傳輸數(shù)目:最大為 65536

庫函數(shù)下 DMA1 通道 4 的配置步驟

1)使能 DMA 時鐘

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能 DMA 時鐘

2)初始化 DMA 通道 4 參數(shù) 

DMA 通道配置參數(shù)種類比較繁多,包括內(nèi)存地址,外設(shè)地址,傳輸數(shù)據(jù)長度,數(shù)據(jù)寬度,通道優(yōu)先級等等。這些參數(shù)的配置在庫函數(shù)中都是在函數(shù) DMA_Init 中完成,下面我們看看函數(shù)定義:

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)

函數(shù)的第一個參數(shù)是指定初始化的 DMA 通道號,這個很容易理解,下面我們主要看看第二個參數(shù)。跟其他外設(shè)一樣,同樣是通過初始化結(jié)構(gòu)體成員變量值來達(dá)到初始化的目的,下面我們來看看 DMA_InitTypeDef 結(jié)構(gòu)體的定義:

    typedef struct

{

uint32_t DMA_PeripheralBaseAddr;

uint32_t DMA_MemoryBaseAddr; 

uint32_t DMA_DIR; 

uint32_t DMA_BufferSize; 

uint32_t DMA_PeripheralInc; 

uint32_t DMA_MemoryInc; 

uint32_t DMA_PeripheralDataSize;

uint32_t DMA_MemoryDataSize; 

uint32_t DMA_Mode; 

uint32_t DMA_Priority; 

uint32_t DMA_M2M; 

}DMA_InitTypeDef;

第一個參數(shù) DMA_PeripheralBaseAddr 用來設(shè)置 DMA 傳輸?shù)耐庠O(shè)基地址,比如要進(jìn)行串口DMA 傳輸,那么外設(shè)基地址為串口接受發(fā)送數(shù)據(jù)存儲器 USART1->DR 的地址,表示方法為&USART1->DR。

第二個參數(shù) DMA_MemoryBaseAddr 為內(nèi)存基地址,也就是我們存放 DMA 傳輸數(shù)據(jù)的內(nèi)存地址。

第三個參數(shù) DMA_DIR 設(shè)置數(shù)據(jù)傳輸方向,決定是從外設(shè)讀取數(shù)據(jù)到內(nèi)存還送從內(nèi)存讀取數(shù)據(jù)發(fā)送到外設(shè),也就是外設(shè)是源地還是目的地,這里我們設(shè)置為從內(nèi)存讀取數(shù)據(jù)發(fā)送到串口,所以外設(shè)自然就是目的地了,所以選擇值為 DMA_DIR_PeripheralDST。

第四個參數(shù) DMA_BufferSize 設(shè)置一次傳輸數(shù)據(jù)量的大小

第五個參數(shù) DMA_PeripheralInc 設(shè)置傳輸數(shù)據(jù)的時候外設(shè)地址是不變還是遞增。如果設(shè)置為遞增,那么下一次傳輸?shù)臅r候地址加 1,這里因為我們是一直往固定外設(shè)地址&USART1->DR發(fā)送數(shù)據(jù),所以地址不遞增,值為 DMA_PeripheralInc_Disable;

第六個參 數(shù) DMA_MemoryInc 設(shè)置傳輸數(shù)據(jù)時候內(nèi)存地址是否遞增。 這個參數(shù) 和DMA_PeripheralInc 意思接近,只不過針對的是內(nèi)存。這里我們的場景是將內(nèi)存中連續(xù)存儲單元的數(shù)據(jù)發(fā)送到串口,毫無疑問內(nèi)存地址是需要遞增的,所以值為 DMA_MemoryInc_Enable。

第七個參數(shù) DMA_PeripheralDataSize 用來設(shè)置外設(shè)的數(shù)據(jù)長度是為字節(jié)傳輸(8bits) ,半字傳輸 (16bits) 還 是 字 傳 輸 (32bits) , 這 里 我 們 是 8 位 字 節(jié) 傳 輸 , 所 以 值 設(shè) 置 為DMA_PeripheralDataSize_Byte。

第八個參數(shù) DMA_MemoryDataSize 是用來設(shè)置內(nèi)存的數(shù)據(jù)長度,和第七個參數(shù)意思接近,這里我們同樣設(shè)置為字節(jié)傳輸 DMA_MemoryDataSize_Byte。

第九個參數(shù) DMA_Mode 用來設(shè)置 DMA 模式是否循環(huán)采集,也就是說,比如我們要從內(nèi)存中采集 64 個字節(jié)發(fā)送到串口,如果設(shè)置為重復(fù)采集,那么它會在 64 個字節(jié)采集完成之后繼續(xù)從內(nèi)存的第一個地址采集,如此循環(huán)。這里我們設(shè)置為一次連續(xù)采集完成之后不循環(huán)。所以設(shè)置值為 DMA_Mode_Normal。在我們下面的實驗中,如果設(shè)置此參數(shù)為循環(huán)采集,那么你會看到串口不停的打印數(shù)據(jù),不會中斷,大家在實驗中可以修改這個參數(shù)測試一下。

第十個參數(shù)是設(shè)置 DMA 通道的優(yōu)先級,有低,中,高,超高三種模式,這里我們設(shè)置優(yōu)先級別為中級,所以值為 DMA_Priority_Medium。如果要開啟多個通道,那么這個值就非常有意義。

第 十 一 個 參 數(shù) DMA_M2M 設(shè) 置 是 否 是 存 儲 器 到 存 儲 器 模 式 傳 輸 , 這 里 我 們 選 擇DMA_M2M_Disable。

實例代碼:

DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_PeripheralBaseAddr = &USART1->DR;   //DMA 外設(shè) ADC 基地址

DMA_InitStructure.DMA_MemoryBaseAddr = cmar;   //DMA 內(nèi)存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;   //從內(nèi)存讀取發(fā)送到外設(shè)

DMA_InitStructure.DMA_BufferSize = 64;   //DMA 通道的 DMA 緩存的大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設(shè)地址不變

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;   //內(nèi)存地址遞增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //8 位

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 8 位

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;   //工作在正常緩存模式

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA 通道  x 擁有中優(yōu)先級 

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   //非內(nèi)存到內(nèi)存?zhèn)鬏?p>DMA_Init(DMA_CHx, &DMA_InitStructure);   //根據(jù)指定的參數(shù)初始化

3)使能串口 DMA 發(fā)送

進(jìn)行 DMA 配置之后,我們就要開啟串口的 DMA 發(fā)送功能,使用的函數(shù)是:

USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);

如果是要使能串口 DMA 接受,那么第二個參數(shù)修改為 USART_DMAReq_Rx 即可。

4)使能 DMA1 通道 4,啟動傳輸。

使能串口 DMA 發(fā)送之后,我們接著就要使能 DMA 傳輸通道:

DMA_Cmd(DMA_CHx, ENABLE);

通過以上 3 步設(shè)置,我們就可以啟動一次 USART1 的 DMA 傳輸了。

5)查詢 DMA 傳輸狀態(tài)

在 DMA 傳輸過程中,我們要查詢 DMA 傳輸通道的狀態(tài),使用的函數(shù)是:

FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)

比如我們要查詢 DMA 通道 4 傳輸是否完成,方法是:

DMA_GetFlagStatus(DMA2_FLAG_TC4);

這里還有一個比較重要的函數(shù)就是獲取當(dāng)前剩余數(shù)據(jù)量大小的函數(shù):

uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)

比如我們要獲取 DMA 通道 4 還有多少個數(shù)據(jù)沒有傳輸,方法是:

DMA_GetCurrDataCounter(DMA1_Channel4);

點擊(此處)折疊或打開

  1. DMA_InitTypeDef DMA_InitStructure;


  2. u16 DMA1_MEM_LEN;//保存DMA每次數(shù)據(jù)傳送的長度     

  3. //DMA1的各通道配置

  4. //這里的傳輸形式是固定的,這點要根據(jù)不同的情況來修改

  5. //從存儲器->外設(shè)模式/8位數(shù)據(jù)寬度/存儲器增量模式

  6. //DMA_CHx:DMA通道CHx

  7. //cpar:外設(shè)地址

  8. //cmar:存儲器地址

  9. //cndtr:數(shù)據(jù)傳輸量


  10. void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)

  11. {

  12.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //使能DMA傳輸

  13.     DMA_DeInit(DMA_CHx); //將DMA的通道1寄存器重設(shè)為缺省值

  14.     DMA1_MEM_LEN=cndtr;

  15.     

  16.     DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外設(shè)ADC基地址

  17.     DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA內(nèi)存基地址

  18.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //數(shù)據(jù)傳輸方向,從內(nèi)存讀取發(fā)送到外設(shè)

  19.     DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA緩存的大小

  20.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)地址寄存器不變

  21.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存地址寄存器遞增

  22.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //數(shù)據(jù)寬度為8位

  23.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數(shù)據(jù)寬度為8位

  24.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常緩存模式

  25.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x擁有中優(yōu)先級

  26.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?br/>

  27.     DMA_Init(DMA_CHx, &DMA_InitStructure); //根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道USART1_Tx_DMA_Channel所標(biāo)識的寄存器

  28. }


  29. //開啟一次DMA傳輸

  30. void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)

  31. {

  32.     DMA_Cmd(DMA_CHx, DISABLE ); //關(guān)閉USART1 TX DMA1 所指示的通道

  33.      DMA_SetCurrDataCounter(DMA1_Channel4,DMA1_MEM_LEN);//DMA通道的DMA緩存的大小

  34.      DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道

  35. }


  1. u8 SendBuff[5200];

  2. MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,5168);//DMA1通道4,外設(shè)為串口1,存儲器為SendBuff,長度5168.


  3. USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA發(fā)送

  4.     

  5.     MYDMA_Enable(DMA1_Channel4);//開始一次DMA傳輸!    

  6.     if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)    //判斷通道4傳輸完成

  7.         {

  8.             DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4傳輸完成標(biāo)志

  9.             break;

  10.         }

  11.         pro=DMA_GetCurrDataCounter(DMA1_Channel4);


關(guān)鍵字:STM32  DMA  直接存儲器訪問 引用地址:STM32 DMA

上一篇:STM32 ADC
下一篇:STM32建立IAR開發(fā)環(huán)境

推薦閱讀最新更新時間:2025-06-07 23:45

STM32 HAL庫利用DMA實現(xiàn)串口不定長度接收方法
我這里使用的芯片是 F1 系列的,主要是利用 DMA 數(shù)據(jù)傳輸方式實現(xiàn)的,在配置工程的時候要注意配置好 DMA,并開啟中斷。 如果出現(xiàn)數(shù)據(jù)長度對,可是數(shù)據(jù)接收不完整,把Memory勾選即可: 1、利用STM32 cubemx 建立一個工程,工程建立請參考我以前的文章:https://www.cnblogs.com/xingboy/p/9597464.html 2、利用STM32 cubemx 生成代碼后,我們先定義一些變量來使用 /* 自己添加代碼部分 */ volatile uint8_t rx_len=0; //接收數(shù)據(jù)長度 volatile uint8_t recv_end_fl
[單片機(jī)]
<font color='red'>STM32</font> HAL庫利用<font color='red'>DMA</font>實現(xiàn)串口不定長度接收方法
STM32串口中斷 DMA接收的幾點注意地方
今天寫點大家常問,也是常見的關(guān)于UART串口的內(nèi)容。這幾點內(nèi)容或許曾經(jīng)也困惑了你很久。 1UART串口中斷接收 使能UART串口中斷之后,有接收到UART數(shù)據(jù),進(jìn)入中斷,此時要清除RXNE接收標(biāo)志位: 1.通過軟件向該RXNE標(biāo)志位寫入零來清零; 2.通過對 USART_DR 寄存器執(zhí)行讀入操作將該位清零。 這里可以查看對應(yīng)《參考手冊》,一般我們選擇第2種,通過讀取UART串口數(shù)據(jù)來清零。 1.中斷接收數(shù)據(jù)丟失 在UART串口中斷函數(shù)中,或者更高優(yōu)先級中斷函數(shù)中長時間執(zhí)行,導(dǎo)致接收丟失,所以,請勿在中斷函數(shù)中長時間執(zhí)行。 特別有些人,還在中斷函數(shù)添加延時函數(shù)。實際應(yīng)用中,只要不是特殊情況,比如測試某個功能可以添加延時函數(shù),都不建議
[單片機(jī)]
<font color='red'>STM32</font>串口中斷 <font color='red'>DMA</font>接收的幾點注意地方
什么是DMA? STM32如何配置DMA
一、DMA簡介 1、DMA簡介 DMA(Direct Memory Access:直接內(nèi)存存取)是一種可以大大減輕CPU工作量的數(shù)據(jù)轉(zhuǎn)移方式。 CPU有轉(zhuǎn)移數(shù)據(jù)、計算、控制程序轉(zhuǎn)移等很多功能,但其實轉(zhuǎn)移數(shù)據(jù)(尤其是轉(zhuǎn)移大量數(shù)據(jù))是 可以不需要CPU參與 。比如希望外設(shè)A的數(shù)據(jù)拷貝到外設(shè)B,只要給兩種外設(shè)提供一條數(shù)據(jù)通路,再加上一些控制轉(zhuǎn)移的部件就可以完成數(shù)據(jù)的拷貝。 DMA就是基于以上設(shè)想設(shè)計的,它的作用就是解決大量數(shù)據(jù)轉(zhuǎn)移過度消耗CPU資源的問題。有了DMA使CPU更專注于更加實用的操作--計算、控制等。 2、DMA的工作原理 DMA的作用就是實現(xiàn)數(shù)據(jù)的直接傳輸,而去掉了傳統(tǒng)數(shù)據(jù)傳輸需要CPU寄存器參與的環(huán)節(jié) ,主要涉及
[單片機(jī)]
STM32輸入捕獲模式設(shè)置并用DMA接收數(shù)據(jù)
環(huán)境: 主機(jī):WIN7 開發(fā)環(huán)境:MDK4.72 MCU:STM32F103 說明: 項目中需要進(jìn)行紅外學(xué)習(xí),于是采用輸入捕獲取得電平變化時間.并將數(shù)據(jù)放在DMA中.這樣可以避免頻繁中斷消耗CPU資源. 采用的是PB1腳,對應(yīng)TIM3的通道4. 源代碼: /********************************************************************* * 接口函數(shù):初始化紅外學(xué)習(xí)模塊 **********************************************************************/ voi
[單片機(jī)]
stm32 ADC全解(單次,連續(xù)DMA傳輸)
學(xué)習(xí)STM32的ADC轉(zhuǎn)換,在開發(fā)板上寫程序調(diào)試。 四個任務(wù): 四個任務(wù): 1.AD以中斷方式(單次)采集一路 2.AD以中斷方式連續(xù)采集四路 3.ADC多路采集,DMA傳輸,DMA深度為一級 4.ADC以DMA方式采集四路,每路DMA深度為28級,并濾波,說明濾波原理 總結(jié): 第一個任務(wù) :ADC以中斷方式采集一路ADC,通過配置ADC_InitStructure結(jié)構(gòu)體中的ADC_ScanConvMode,它規(guī)定模數(shù)轉(zhuǎn)換工作在掃描模式(多通道)還是單次模式(單通道), ADC_InitStructure.ADC_ScanConvMode=DISABLE,為單通道單次模式。 ADC_ContinuousConvMode,定轉(zhuǎn)
[單片機(jī)]
關(guān)于STM32 ADC DMA 使用心得(2)
(二)ADC循環(huán)采集六路電壓,使用DMA. 這次實驗真的很郁悶,對DMA的不了解讓我深陷誤區(qū),明白之后,讓我更加佩服DMA的強(qiáng)大。 誤區(qū)就是:從實驗的目標(biāo)我們知道這次是用DMA把ADC轉(zhuǎn)換的數(shù)據(jù)傳送到內(nèi)存中的一個數(shù)組里存起來,因為是采集6個通道,這里使能了ADC的掃描模式。一旦啟動ADC,就會按順序轉(zhuǎn)換SQRX里選中的通道,問題就是我一開始以為ADC與DMA并不會協(xié)調(diào)工做,也就是ADC自己轉(zhuǎn)自己的,DMA自己傳自己的,這樣的話內(nèi)存里的數(shù)組就不是我想要的了,后來著實的研究了很長時間,在群里的一位兄弟的提醒下,我才知道,可能我想的復(fù)雜了,也許就可以在ADC轉(zhuǎn)一次,然后DMA把數(shù)據(jù)傳一次,Ok,經(jīng)過實驗得知,這個想法是正確的。
[單片機(jī)]
stm32AD單通道與多通道轉(zhuǎn)換(DMA)
本章的內(nèi)容分兩部分,第一是AD的單通道轉(zhuǎn)換,第二是AD的多通道轉(zhuǎn)換。首先先將單通道轉(zhuǎn)換。 STM32中自帶的AD最大的轉(zhuǎn)換頻率是14MHZ,共有16個轉(zhuǎn)換通道,每個轉(zhuǎn) ADC123_IN10表明PC0管腳可以作為AD1,AD2,AD3的第10通道。 下面我們將PC0配置成AD1的通道10為例進(jìn)行講解。 3.1首先我們應(yīng)將PC0設(shè)置成模擬輸入: #include adc.h /*為何定義ADC1_DR_Address 為((u32)0x40012400+0x4c) ,因為存放AD轉(zhuǎn)換結(jié)果的寄存器的地址就是0x4001244c*/ #define ADC1_DR_Address ((u32)0x4001
[單片機(jī)]
STM32F4-DMA請求映射表
[單片機(jī)]
STM32F4-<font color='red'>DMA</font>請求映射表
小廣播
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 富阳市| 游戏| 岑巩县| 合阳县| 理塘县| 彰化县| 永仁县| 大渡口区| 乐至县| 绿春县| 磴口县| 临汾市| 东兰县| 宁波市| 四子王旗| 宿迁市| 娱乐| 古田县| 乐都县| 隆化县| 潜江市| 常德市| 宁津县| 湖北省| 安庆市| 新源县| 错那县| 肇庆市| 平顶山市| 双鸭山市| 临清市| 通山县| 江西省| 兴文县| 牙克石市| 新竹市| 津市市| 安泽县| 乐东| 华蓥市| 平凉市|