<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32F10x 學(xué)習(xí)筆記5(USART實(shí)現(xiàn)串口通訊 1)

          STM32F10x 學(xué)習(xí)筆記5(USART實(shí)現(xiàn)串口通訊 1)

          作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
          STM32F10x系列單片機(jī)中都包含了USART模塊,所謂USART,就是通用同步異步收發(fā)器。通用同步異步收發(fā)器(USART)提供了一種靈活的方法與使用工業(yè)標(biāo)準(zhǔn)NRZ異步串行數(shù)據(jù)格式的外部設(shè)備之間進(jìn)行全雙工數(shù)據(jù)交換。它支持同步單向通信和半雙工單線通信,也支持LIN(局部互連網(wǎng)),智能卡協(xié)議和IrDA(紅外數(shù)據(jù)組織)SIRENDEC規(guī)范,以及調(diào)制解調(diào)器(CTS/RTS)操作。它還允許多處理器通信。

          本文引用地址:http://www.ex-cimer.com/article/201611/318840.htm

          從前面的介紹可知USART模塊功能非常的強(qiáng)大。這里我只簡單講講如何用USART模塊來實(shí)現(xiàn)標(biāo)準(zhǔn)EIA-232串口通訊

          用過單片機(jī)的人肯定都接觸過串口,設(shè)置串口無非就是設(shè)置波特率、數(shù)據(jù)位、停止位、奇偶校驗(yàn)位。發(fā)送接收也就三種基本方式,輪詢、中斷和DMA。STM32F10x的USART模塊也不過如此。所以我重點(diǎn)講講我在調(diào)試代碼時(shí)犯得各種錯(cuò)誤,那些很容易得到的代碼就不詳細(xì)的講解了。

          首先說說我的硬件環(huán)境。還是那塊神舟4號(hào)開發(fā)板,用的是串口2,對(duì)應(yīng)的是USART2。默認(rèn)情況下USART2是連接到IO端口A的,但是我這里需要將USART的管腿重定向到IO端口D上。具體的管腿的關(guān)系參見下表。這個(gè)表是從STM32參考手冊上拷下來的。

          初始化USART的代碼很簡單。USART2連接到APB1總線上了,先要打開USART2的時(shí)鐘,然后設(shè)置波特率一類的參數(shù)。

          1. USART_InitTypeDefUSART_InitStructure;
          2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
          3. USART_InitStructure.USART_BaudRate=9600;
          4. USART_InitStructure.USART_WordLength=USART_WordLength_8b;
          5. USART_InitStructure.USART_StopBits=USART_StopBits_1;
          6. USART_InitStructure.USART_Parity=USART_Parity_No;
          7. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
          8. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
          9. USART_Init(USART2,&USART_InitStructure);

          這樣設(shè)置了還不能使用。因?yàn)槲覀儗SART2重定向了。重定向操作需要寫復(fù)用重映射和調(diào)試I/O配置寄存器(AFIO_MAPR)。GPIO_PinRemapConfig()可以完成這項(xiàng)任務(wù)。

          1. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

          光這樣操作還不夠。STM32參考手冊上有這么一段話:

          對(duì)寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX進(jìn)行讀寫操作前,應(yīng)當(dāng)首先打開AFIO的時(shí)鐘。參考第6.3.7節(jié)APB2外設(shè)時(shí)鐘使能寄存器(RCC_APB2ENR)。

          所以需要先打開AFIO的時(shí)鐘。因此,USART2的重定向需要兩步操作:

          [cpp]view plaincopy
          1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
          2. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

          我原以為這樣就能工作了,可是結(jié)果還是什么都沒有輸出。沒辦法只能繼續(xù)研究。在讀GPIO的相關(guān)章節(jié)時(shí)看到下圖讓我恍然大悟。

          USART2的輸入輸出都是借用PD口管腿,PD口的時(shí)鐘卻還沒給。用到的幾個(gè)IO端口也沒有設(shè)置相應(yīng)的輸入輸出狀態(tài)。在讀到8.1.9復(fù)用功能配置這一小節(jié)時(shí)發(fā)現(xiàn)了如下的表格。

          按照上面給出的配置,寫好程序:

          1. GPIO_InitTypeDefGPIO_InitStructure;
          2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
          3. /*ConfigureUSARTTxasalternatefunctionpush-pull*/
          4. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
          5. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
          6. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
          7. GPIO_Init(GPIOD,&GPIO_InitStructure);
          8. /*ConfigureUSARTRxasinputfloating*/
          9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
          10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
          11. GPIO_Init(GPIOD,&GPIO_InitStructure);

          再次測試,一切正常。

          發(fā)送一個(gè)字符的函數(shù)可以這么寫:

          1. voidUART_PutChar(USART_TypeDef*USARTx,uint8_tData)
          2. {
          3. while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET){};
          4. USART_SendData(USARTx,Data);
          5. }
          這個(gè)函數(shù)可以手工優(yōu)化一下,里面的兩個(gè)函數(shù)調(diào)用都可以去掉,甚至于這個(gè)函數(shù)可以用匯編來實(shí)現(xiàn)或者寫成inline 函數(shù)。不過這里只是個(gè)示例代碼,沒有考慮這些。

          發(fā)送字符串的函數(shù)如下:

          1. voidUART_PutStr(USART_TypeDef*USARTx,uint8_t*str)
          2. {
          3. while(0!=*str)
          4. {
          5. UART_PutChar(USARTx,*str);
          6. str++;
          7. }
          8. }

          上面串口初始化的代碼可以放到一個(gè)函數(shù)中:

          1. voidUSART2_init(void)
          2. {
          3. GPIO_InitTypeDefGPIO_InitStructure;
          4. USART_InitTypeDefUSART_InitStructure;
          5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO,ENABLE);
          6. /*ConfigureUSARTTxasalternatefunctionpush-pull*/
          7. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
          8. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
          9. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
          10. GPIO_Init(GPIOD,&GPIO_InitStructure);
          11. /*ConfigureUSARTRxasinputfloating*/
          12. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
          13. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
          14. GPIO_Init(GPIOD,&GPIO_InitStructure);
          15. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
          16. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
          17. USART_InitStructure.USART_BaudRate=9600;
          18. USART_InitStructure.USART_WordLength=USART_WordLength_8b;
          19. USART_InitStructure.USART_StopBits=USART_StopBits_1;
          20. USART_InitStructure.USART_Parity=USART_Parity_No;
          21. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
          22. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
          23. USART_Init(USART2,&USART_InitStructure);
          24. USART_Cmd(USART2,ENABLE);
          25. }

          今天先寫這么多。接收字符的函數(shù)與發(fā)送字符的函數(shù)差不多,但是這種輪詢方式效率很低,不建議使用。下次寫一篇介紹如何用中斷方式發(fā)送接收串口數(shù)據(jù),中斷方式的效率會(huì)高很多。如果有時(shí)間再寫一篇DMA方式發(fā)送接收數(shù)據(jù)的文章。




          關(guān)鍵詞: STM32F10xUSART串口通

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();