日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

STM32----摸石头过河系列(五)

發(fā)布時(shí)間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32----摸石头过河系列(五) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天總結(jié)一下DMA(Direct Memory Access,直接存儲(chǔ)器存儲(chǔ)),在以往我們從串口讀取數(shù)據(jù)到內(nèi)存的流程是,cpu通過串口讀取導(dǎo)數(shù)據(jù),然后CPU再將數(shù)據(jù)寫入固定的內(nèi)存。這種讀取方式占用了大量的cpu資源,如果數(shù)據(jù)量非常大,CPU將耗費(fèi)大量的時(shí)間來(lái)進(jìn)行數(shù)據(jù)的讀寫操作。因此DMA應(yīng)運(yùn)而生。DMA的作用是啥呢?從名字能看出來(lái)一二,它可以直接從串口讀取數(shù)據(jù)存儲(chǔ)在內(nèi)存中,幾乎不占用CPU的資源。打個(gè)比方來(lái)說(shuō),一個(gè)砌墻的工人,他的主要工作是砌墻,但他首先需要耗費(fèi)大量時(shí)間去搬磚到自己身邊,然后才開始砌墻,這樣他砌墻的進(jìn)度肯定很慢。現(xiàn)在砌墻的工人不自己去搬磚了,他雇傭了另外一個(gè)人來(lái)幫助他去把磚搬過來(lái),在搬之前砌墻的工人告訴搬磚的工人,他要去哪里搬磚、搬什么樣的磚、搬磚的速度、搬過來(lái)后放在那里等問題。這樣雖然在開始耗費(fèi)了點(diǎn)時(shí)間去告訴搬磚工人一些要求,看起來(lái)比較繁瑣,其實(shí)這些所占用的時(shí)間比起自己去搬磚耗費(fèi)的時(shí)間少多了。在這個(gè)例子中,砌墻的工人就是我們所說(shuō)的CPU,磚就是需要讀寫數(shù)據(jù),搬磚工人就是DMA,DMA的引入為CPU讀寫數(shù)據(jù)節(jié)省了大量的時(shí)間,CPU只需要在開始耗費(fèi)極少的時(shí)間對(duì)DMA進(jìn)行相關(guān)的配置,就可以去做其他的事情。

我在做實(shí)驗(yàn)的過程中,遇到了很多狗血的bug,不過最終都得以解決。今天做的實(shí)驗(yàn)是利用DMA通過USART1向發(fā)送數(shù)據(jù),同時(shí)LED持續(xù)點(diǎn)亮,當(dāng)發(fā)送數(shù)據(jù)完成時(shí),進(jìn)入中斷將LED熄滅,從而來(lái)驗(yàn)證DMA工作時(shí)CPU可以去做別的事情,而沒有影響。下面來(lái)總結(jié)一下DMA的開發(fā)流程:

  • NVIC中斷優(yōu)先級(jí)的配置
  • DMA_InitTypeDef結(jié)構(gòu)體的配置(記得調(diào)用NVIC配置的函數(shù),我多次忘記調(diào)用)
  • 初始化DMA,DMA_Init(DMA1_Channel4,&結(jié)構(gòu)體)(DMA1_Channel4為串口1的發(fā)送,具體的可以看手冊(cè))
  • 使能DMA,DMA_Cmd(DMA1_Channel4,ENABLE)
  • 配置并使能中斷DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE)
  • 開始利用DMA進(jìn)行串口發(fā)送數(shù)據(jù)USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
  • 在中斷中DMA_GetFlagStatus(DMA1_FLAG_TC4) == SET來(lái)確定發(fā)送數(shù)據(jù)完成
  • 根據(jù)以上步驟進(jìn)行先關(guān)的配置,其他的比如串口和LED的配置在前面已經(jīng)配置過了直接把USART和LED的配置文件添加在該項(xiàng)目中即可。下面來(lái)看代碼,代碼中只有DMA的配置和主函數(shù)。

    下面這是dma.c文件中的內(nèi)容:

    #include"dma.h"uint16_t SendBuff[SENDSBUFF_SIZE];static void NVIC_Config(void) {NVIC_InitTypeDef nvic_struct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);nvic_struct.NVIC_IRQChannel = DMA1_Channel4_IRQn;nvic_struct.NVIC_IRQChannelPreemptionPriority = 1;nvic_struct.NVIC_IRQChannelSubPriority = 1;nvic_struct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&nvic_struct); }void DMA1_Config(void) {DMA_InitTypeDef dma_struct;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);NVIC_Config();dma_struct.DMA_PeripheralBaseAddr = USART1_BASE + 0x04;//數(shù)據(jù)要到達(dá)的地址dma_struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//每次發(fā)送數(shù)據(jù)的大小dma_struct.DMA_MemoryBaseAddr = (u32)SendBuff;//數(shù)據(jù)所在的地址dma_struct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//每次讀取數(shù)據(jù)的大小dma_struct.DMA_BufferSize = SENDSBUFF_SIZE;//總共傳輸?shù)臄?shù)據(jù)的大小dma_struct.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲(chǔ)數(shù)據(jù)的地址是否自動(dòng)增加dma_struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//數(shù)據(jù)到達(dá)的地址是否自動(dòng)增加dma_struct.DMA_DIR = DMA_DIR_PeripheralDST;//傳輸?shù)姆较騼?nèi)存到外設(shè)dma_struct.DMA_M2M = DMA_M2M_Disable;//內(nèi)存到內(nèi)存是否允許dma_struct.DMA_Mode = DMA_Mode_Normal;//傳輸方式,發(fā)送一次還是循環(huán)發(fā)送dma_struct.DMA_Priority = DMA_Priority_Medium;//優(yōu)先級(jí)DMA_Init(DMA1_Channel4,&dma_struct);//初始化DMA_Cmd(DMA1_Channel4,ENABLE);//使能DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);//中斷配置并使能}

    SendBuff數(shù)組存儲(chǔ)的是要發(fā)送的數(shù)據(jù),兩個(gè)函數(shù)為中斷配置函數(shù),在前面的外部中斷中已經(jīng)配置過了。第二個(gè)函數(shù)為DMA的配置函數(shù),與其他外設(shè)的配置類似,先定義一個(gè)結(jié)構(gòu)體,然后開啟時(shí)鐘。這個(gè)DMA1的時(shí)鐘和之前的都不一樣,在AHB上,配置時(shí)需要注意。

    在main.c文件中:

    #include"led.h" #include"usart.h" #include"dma.h"extern uint16_t SendBuff[SENDSBUFF_SIZE];//引用外部定義的變量 int i;int main(void)//主函數(shù) {GPIO_LED_Config();USART1_Config();DMA1_Config();for(i = 0;i < SENDSBUFF_SIZE;i++)//為發(fā)送數(shù)據(jù)賦值{SendBuff[i] = 0xff;}printf("Send start!");USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);LED(ON);printf("wait interrupt!");while(1); }void DMA1_Channel4_IRQHandler(void)//中斷函數(shù) {printf("into interrupt!");if(DMA_GetFlagStatus(DMA1_FLAG_TC4) == SET)//判斷是否發(fā)送完成{printf("send success");LED(OFF);DMA_ClearFlag(DMA1_FLAG_TC4);//清除標(biāo)志位} }

    在實(shí)驗(yàn)的過程中,編譯出現(xiàn)symbol multiply defined錯(cuò)誤的原因,因?yàn)樵趚xx.h中定義了許多變量,xxx.c中調(diào)用xxx.h中的變量,在主文件中也調(diào)用了xxx.h中的變量,導(dǎo)致變量被重復(fù)定義。

    解決辦法:不應(yīng)該在xxx.h中定義xxx.c中使用的變量,應(yīng)該在xxx.c中定義所需要的變量,然后再在主程序中將調(diào)用xxx.c中定義的變量使用extern 例:extern u32 test.

    總結(jié)

    以上是生活随笔為你收集整理的STM32----摸石头过河系列(五)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美 日韩 国产 在线观看 | 天天干天天搞天天射 | 谁有毛片网站 | 亚洲一区二区在线电影 | 加勒比在线免费视频 | 久久高清无码视频 | 日韩精品一区二区三区四区 | 久久久情| 一级色视频 | 大白屁股一区二区视频 | 免费人成在线观看网站 | 成人1区2区3区| 97涩涩网| 啄木乌欧美一区二区三区 | 福利片av| 91麻豆视频 | 久久久久国产精 | 国产精品88久久久久久妇女 | 日本中文一区 | 成人在线视频观看 | 国精产品一区一区三区有限公司杨 | 男女男精品视频 | 国产情侣在线视频 | 一区二区视频网站 | 女人毛片视频 | 精品熟妇视频一区二区三区 | 久久久久免费观看 | 污视频免费在线观看网站 | 日本一区二区免费视频 | 少妇人妻偷人精品无码视频新浪 | 99视频精品在线 | 成人午夜免费网站 | 精品一区二区三区国产 | 国产春色 | 自拍亚洲欧美 | 久热99 | 涩涩资源站 | 成人性视频免费网站 | 国产crm系统91在线 | 久久嫩草视频 | 国产美女操 | jizz国产在线观看 | 一区二区三区av在线 | 色接久久| 国产黄色片在线观看 | 亚洲国产婷婷香蕉久久久久久99 | 黄色一级免费观看 | 国产 日韩 欧美 精品 | 日日摸日日碰 | 51热门大瓜今日大瓜 | 国产免费一区视频观看免费 | 亚洲欧美日韩在线播放 | 亚洲成人三区 | 亚洲国产成人精品91久久久 | 国产麻豆免费观看 | 高清免费av | 日韩福利一区二区三区 | 欧美成年人网站 | 深夜免费视频 | 黄色小网站在线观看 | 精品视频在线观看一区 | 精品国产三级片在线观看 | 人妻一区二区三区免费 | 亚洲特黄特色 | 日本三级久久 | 粗大的内捧猛烈进出 | 毛片视 | 婷婷国产| 日韩福利在线播放 | 日批视频在线 | 中文字幕在线观看免费高清 | 国产妇女视频 | 国家队动漫免费观看在线观看晨光 | 免费无码不卡视频在线观看 | 大胸美女吻戏 | 男女被到爽流尿 | 久久久这里有精品 | 中出在线| 亚州中文 | 欧美美女视频 | 永久免费的网站入口 | 色女孩综合 | 一卡二卡国产 | 黄色小视频免费网站 | 鲁鲁久久 | 国产精品99久久久久久动医院 | 伊在线久久丫 | 精品视频一二三区 | 美女在线观看www | 国产综合精品视频 | 国产男女激情 | 中文字幕在线日韩 | 91免费视频免费版 | 精品国产鲁一鲁一区二区张丽 | 日韩视频区 | 四十路av | 精品免费一区二区 | 久久精品香蕉视频 | 狠狠操网址 |