<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > STM32F10x 學(xué)習筆記5(USART實(shí)現串口通訊 1)

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

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

本文引用地址:http://dyxdggzs.com/article/201611/318840.htm

從前面的介紹可知USART模塊功能非常的強大。這里我只簡(jiǎn)單講講如何用USART模塊來(lái)實(shí)現標準EIA-232串口通訊。

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

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

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

  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);

這樣設置了還不能使用。因為我們將USART2重定向了。重定向操作需要寫(xiě)復用重映射和調試I/O配置寄存器(AFIO_MAPR)。GPIO_PinRemapConfig()可以完成這項任務(wù)。

  1. GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

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

對寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX進(jìn)行讀寫(xiě)操作前,應當首先打開(kāi)AFIO的時(shí)鐘。參考第6.3.7節APB2外設時(shí)鐘使能寄存器(RCC_APB2ENR)。

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

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

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

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

按照上面給出的配置,寫(xiě)好程序:

  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è)字符的函數可以這么寫(xiě):

  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è)函數可以手工優(yōu)化一下,里面的兩個(gè)函數調用都可以去掉,甚至于這個(gè)函數可以用匯編來(lái)實(shí)現或者寫(xiě)成inline 函數。不過(guò)這里只是個(gè)示例代碼,沒(méi)有考慮這些。

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

  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è)函數中:

  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. }

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




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

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>