久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7338|回復: 1
收起左側

STM32F407的串口編程經驗

[復制鏈接]
ID:417196 發表于 2018-10-29 13:46 | 顯示全部樓層 |閱讀模式
STM32F407的串口編程經驗
串口是嵌入式開發中最常前的外設設備,既可以用作不同單片機之間的通信,也可以用作在STM32 MCU和PC機之間的通信,STM32F407的串口功能非常強大,可以接紅外,可以接流控,也可以接SIM卡接口,但我這里只介紹我們最常用的UART通信的一點調試經驗,以STM32F407為例,對其它STM32芯片也適用,希望對大家有所幫助,如有錯誤不當之處歡迎大家聯系指正。
一、串口的三種工作方式操作串口一般有兩種方式:查詢和中斷;STM32還支持第三種DMA方式。(1)查詢:串口程序不斷地循環查詢標志,看看當前有沒有數據要它傳送或接收。如果有的話進行相應的寫操作和讀操作進行傳送或接收數據。(2)中斷:平時串口只要打開中斷即可。如果發現有一個中斷來,則意味著有數據需要接收(接收中斷)或數據已經發送完成(發送中斷)。(3)DMA方式,設置好DMA工作方式,由DMA來自動接收或發送數據。一般來說,查詢方式的效率是比較低的,并且由于STM32的UART硬件上沒有FIFO,如果程序功能比較多,查詢不及時的話很容易出現數據丟失的現象, 故實際項目中這種方式用的并不多。中斷方式的話我們可以分別設置接收中斷和發送中斷,當串口有數據需要接收時才進入中斷程序進行讀讀操,這種方式占用CPU資源比較少,實際項目中比較常用,但需要注意中斷程序不要太復雜使執行時間太長,如果執行時間超過一個字符的時間的話也會出現數據丟失的現象,這個波特率比較高的串口編程中比較容易出現,可以考慮用循環BUF方法,在中斷程序中只負責實時地接收實數數和發送時的填數(寫發送寄存器),其它操作放在中斷外處理。STM32還提供了第三種DMA方式用來支持高速地串口傳輸。這種方式只要設置好接收和發送緩沖位置,可以由DMA來自動接收和發送數據,這可以最小化占用CPU時間。
二、串口的使用步驟(1)中斷方式基本步驟是初試化時鐘,腳位、波特率設置、安裝中斷服務程序、開中斷等,參考代碼如下:
1.    voiduart_init(void)
2.    {
3.      USART_InitTypeDef USART_InitStructure;
4.      NVIC_InitTypeDefNVIC_InitStructure;
5.      GPIO_InitTypeDef  GPIO_InitStructure;
6.      
7.      /*Enable GPIO clock  */
8.      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
9.      
10.     /* Enable USART clock */
11.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
12.   
13.     /* Connect USART pins to AF7 */
14.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_USART3);
15.    GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,  GPIO_AF_USART3);
16.     
17.    /* Configure USART Tx and Rx as  alternatefunction push-pull */
18.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
19.    GPIO_InitStructure.GPIO_Speed=  GPIO_Speed_100MHz;
20.     GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
21.    GPIO_InitStructure.GPIO_PuPd=  GPIO_PuPd_UP;
22.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
23.    GPIO_Init(GPIOC,  &GPIO_InitStructure);
24.     
25.    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
26.    GPIO_Init(GPIOC,  &GPIO_InitStructure);
27.    /*  USARTxconfiguration  ----------------------------------------------------*/
28.    /* USARTx configured as follow:
29.          - BaudRate =3750000 baud
30.    - Maximum BaudRate that can be achievedwhen  using the Oversampling by 8
31.       is: (USART APB Clock / 8)
32.  Example:
33.     - (USART3 APB1  Clock / 8) = (30MHz / 8) = 3750000 baud
34.     - (USART1 APB2 Clock / 8) = (60 MHz / 8) =7500000  baud
35.    - Maximum BaudRate that can  beachieved when using the Oversampling by 16
36.      is: (USART APB Clock / 16)
37.  Example: (USART3 APB1 Clock / 16) = (30 MHz /16)  = 1875000 baud
38.  Example: (USART1  APB2 Clock / 16) = (60 MHz /16) = 3750000 baud
39.          - Word Length = 8Bits
40.          - one Stop Bit
41.          - No parity
42.          - Hardware flowcontrol disabled (RTS and  CTS signals)
43.          - Receiveand  transmit enabled
44.     */
45.     USART_InitStructure.USART_BaudRate = 115200;
46.    USART_InitStructure.USART_WordLength=  USART_WordLength_8b;
47.     USART_InitStructure.USART_StopBits =USART_StopBits_1;
48.    USART_InitStructure.USART_Parity=  USART_Parity_No;
49.    USART_InitStructure.USART_HardwareFlowControl=  USART_HardwareFlowControl_None;
50.     USART_InitStructure.USART_Mode =USART_Mode_Rx | USART_Mode_Tx;
51.    USART_Init(USART3,  &USART_InitStructure);
52.     
53.    /* NVIC configuration  */
54.    /* Configure the Priority  Group to2 bits */
55.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
56.   
57.     /* Enable the USARTx Interrupt */
58.    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
59.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
60.    NVIC_InitStructure.NVIC_IRQChannelSubPriority=  0;
61.     NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
62.     NVIC_Init(&NVIC_InitStructure);
63.   
64.    /* Enable USART  */
65.    USART_Cmd(USART3,  ENABLE);
66.    USART_ITConfig(USART3,  USART_IT_RXNE,ENABLE);
67.  }
68.   
復制代碼

中斷服務程序如下:
1.    voidUSART3_IRQHandler(void)
2.    {
3.    unsigned charch;  
4.    if(USART_GetITStatus(USART3,  USART_IT_RXNE)!= RESET)
5.       {
6.       /* Read one byte from the  receive data register */
7.       ch =  (USART_ReceiveData(USART3));
8.     
9.        printf("in[%c].\r\n",ch);
10.    }   
11.  }
復制代碼


直接把接收到的字符打印出來。
(2)DMA方式基本步驟同中斷方式,額外需要DMA的初始化配置,參考代碼如下:
1.    void  uart_init(void)
2.    {
3.      USART_InitTypeDef  USART_InitStructure;
4.      NVIC_InitTypeDef NVIC_InitStructure;
5.      GPIO_InitTypeDefGPIO_InitStructure;
6.      DMA_InitTypeDefDMA_InitStruct;
7.      
8.       /*Enable GPIO clock */
9.      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
10.   
11.     /* Enable USART clock */
12.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
13.   
14.     /* Connect USART pins to AF7 */
15.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_USART3);
16.    GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,  GPIO_AF_USART3);
17.     
18.    /* Configure USART Tx and Rx as  alternatefunction push-pull */
19.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
20.    GPIO_InitStructure.GPIO_Speed=  GPIO_Speed_100MHz;
21.     GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
22.    GPIO_InitStructure.GPIO_PuPd=  GPIO_PuPd_UP;
23.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
24.    GPIO_Init(GPIOC,  &GPIO_InitStructure);
25.     
26.    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
27.    GPIO_Init(GPIOC,  &GPIO_InitStructure);
28.    /*  USARTxconfiguration  ----------------------------------------------------*/
29.    /* USARTx configured as follow:
30.          - BaudRate =3750000 baud
31.    - Maximum BaudRate that can be achievedwhen  using the Oversampling by 8
32.       is: (USART APB Clock / 8)
33.  Example:
34.     - (USART3 APB1  Clock / 8) = (30MHz / 8) = 3750000 baud
35.     - (USART1 APB2 Clock / 8) = (60 MHz / 8) =7500000  baud
36.    - Maximum BaudRate that can  beachieved when using the Oversampling by 16
37.      is: (USART APB Clock / 16)
38.  Example: (USART3 APB1 Clock / 16) = (30 MHz /16)  = 1875000 baud
39.  Example: (USART1  APB2 Clock / 16) = (60 MHz /16) = 3750000 baud
40.          - Word Length = 8Bits
41.          - one Stop Bit
42.          - No parity
43.          - Hardware flowcontrol disabled (RTS and  CTS signals)
44.          - Receiveand  transmit enabled
45.     */
46.     USART_InitStructure.USART_BaudRate = 115200;
47.    USART_InitStructure.USART_WordLength=  USART_WordLength_8b;
48.     USART_InitStructure.USART_StopBits =USART_StopBits_1;
49.    USART_InitStructure.USART_Parity=  USART_Parity_No;
50.    USART_InitStructure.USART_HardwareFlowControl=  USART_HardwareFlowControl_None;
51.     USART_InitStructure.USART_Mode =USART_Mode_Rx | USART_Mode_Tx;
52.    USART_Init(USART3,  &USART_InitStructure);
53.   
54.  /*  DMA_Configuration */
55.     DMA_DeInit(DMA1_Stream1);
56.     
57.    DMA_InitStruct.DMA_Channel=  DMA_Channel_4;   
58.     DMA_InitStruct.DMA_PeripheralBaseAddr=  (u32)&USART3->DR; //source  buf
59.     DMA_InitStruct.DMA_Memory0BaseAddr =(u8)pdata; //target buf
60.   
61.    DMA_InitStruct.DMA_DIR=  DMA_DIR_PeripheralToMemory;
62.     DMA_InitStruct.DMA_BufferSize =lenght;  //BuffSize;
63.    DMA_InitStruct.DMA_PeripheralInc=  DMA_PeripheralInc_Disable;
64.     DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
65.    DMA_InitStruct.DMA_PeripheralDataSize =  DMA_PeripheralDataSize_Word;
66.     DMA_InitStruct.DMA_MemoryDataSize=  DMA_MemoryDataSize_Byte;
67.    DMA_InitStruct.DMA_Mode =DMA_Mode_Circular;  //DMA_Mode_Normal;
68.     DMA_InitStruct.DMA_Priority = DMA_Priority_High;
69.    DMA_InitStruct.DMA_FIFOMode=  DMA_FIFOMode_Disable;
70.     DMA_InitStruct.DMA_FIFOThreshold =DMA_FIFOThreshold_HalfFull;
71.    DMA_InitStruct.DMA_MemoryBurst=  DMA_MemoryBurst_Single;
72.     DMA_InitStruct.DMA_PeripheralBurst =DMA_PeripheralBurst_Single;
73.    DMA_Init(DMA1_Stream1,  &DMA_InitStruct);
74.   
75.    /* NVIC configuration  */
76.    /* Configure the Priority  Group to2 bits */
77.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
78.   
79.     /* Enable the USARTx Interrupt */
80.    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;  
81.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
82.    NVIC_InitStructure.NVIC_IRQChannelSubPriority=  0;
83.     NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
84.    NVIC_Init(&NVIC_InitStructure);  
85.   
86.    /* Open DMA  interrupt*/
87.     DMA_ITConfig(DMA1_Stream1, DMA_IT_TC,ENABLE);
88.    DMA_Cmd(DMA1_Stream1, ENABLE);
89.    USART_Cmd(USART3, ENABLE);
90.     USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);
91.  }
復制代碼


DMA中斷服務程序如下:
1.    voidDMA1_Stream1_IRQHandler(void) //UART3_RX
2.    {
3.        static short i;
4.     
5.        //Whena  Transfer Complete
6.    if(SET==  DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1))
7.    {
8.    DMA_ClearITPendingBit(DMA1_Stream1,DMA_IT_TCIF1);
9.    i++;
10.  }
11.  }
復制代碼


上面程序只配了DMA接收,發送類似。

三、實現DMX512協議DMX512 協議是美國劇場技術協會( United States Institute for TheaterTechnology,  USITT) 制定的數字多路復用協議, 其制定的初衷是為了使舞臺、劇場等地所使用的眾多的調光器和控制器能相互兼容。雖然它不是一個行業或國家標準, 但是由于它的簡單性和實用性, 自從出臺以來, 得到了世界各地生產商和使用者普遍承認,這個協議在LED控制方面應用很廣泛,利用STM32 USART可以高速傳輸的特性,我們很容易用STM32來實現DMX512協議。(1)數據的格式及傳輸DMX512  協議規定數據以數據包的形式通過異步通訊的方式進行傳輸。每個數據包由若干數據幀組成, 每幀數據包括1 位低電平起始位、8 位數據位和2 位高電平停止位。DMX 協議要求數據傳輸的波特率為250kb/s, 亦即每位的傳輸時間為4us, 每幀數據的傳輸時間為44us, 它支持多達512 幀數據傳輸, 每幀數據與相應的控制支路相對應。數據包的傳送要符合一定的格式和時序要求。為了使接收器能夠分辨出第一幀數據, 每一個數據包以一個不短于88us 的低電平信號為起始信號, 即所謂的“Break”信號, 接收器接收到“Break”信號就準備接受隨后而來的數據幀; 緊接著“Break”信號之后是不短于8us 的高電平信號M. a. b ( Mark after  Break) ; 之后就是數據幀。在DMX512 協議中, M. a. b 之后的第一幀數據被稱為“Star-t code”, 在協議中規定其為零, 但在實際應用中可以由生產廠家自己確定其具體的值,  以傳遞特殊消息。“Star-t  code”標明其后面的數據是8  位控制信號數據幀。數據幀之間可以有時間間隔, 也可以沒有;  同樣, 數據包之間可以有時間間隔, 也可以沒有。DMX512 協議規定“Break”信號、M. a. b 信號的最短時間, 并規定“Break”信號、M. a. b 信號、數據幀之間及數據包之間的時間間隔的最大值不得超過1s, 否則做出錯處理, 但是DMX512 協議并未對出錯處理做任何規定。為了嚴格實現DMX512  數據的時序要求,“Break”和M.  a. b信號我們可以用定時器來實現。具體的UART配置如下:  
1.    USART_InitStructure.USART_BaudRate=  250000;
2.      USART_InitStructure.USART_WordLength = USART_WordLength_8b;
3.      USART_InitStructure.USART_StopBits=  USART_StopBits_2;
4.      USART_InitStructure.USART_Parity = USART_Parity_No;
5.      USART_InitStructure.USART_HardwareFlowControl=  USART_HardwareFlowControl_None;
6.      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
7.      USART_Init(USART1,  &USART_InitStructure);
復制代碼




發送DMX512信號過程如下,先把UART的TX腳配置為普通的GPIO并輸出低電平,然后啟動定時器計時88us,  時器到后把TX腳置為高電平并計時8us, 時器到了后在配為UART模式用DMA方式把數據發出。DMX512信號的接收是個難點,一般直接配為UART接收就行,不需要在UART模式和GPIO模式間切換,但需要在接收過程中檢查接收到“Break”信號時的狀態是有幀錯誤出現,并且接收數據全為零,這樣的話可以確認已經收到“Break”信號,隨后數據正常DMA接收就行了。


回復

使用道具 舉報

ID:662810 發表于 2019-12-12 22:28 | 顯示全部樓層
開發STMf407的集成環境是什么
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精选一区 | 中文字幕av亚洲精品一部二部 | 成人精品一区二区三区四区 | 日日噜噜夜夜爽爽狠狠 | 天天综合久久 | 97久久精品午夜一区二区 | 国产婷婷精品av在线 | 久久精品一级 | 久久久久久国产精品免费免费 | 尤物视频在线免费观看 | h肉视频 | 亚洲一区中文字幕 | 嫩草最新网址 | 999久久久| 欧美日韩国产一区二区三区 | 久久一久久 | 欧美黄视频| 日韩图区 | 欧美不卡 | 国产欧美日韩视频 | 操皮视频 | 亚洲高清在线视频 | 天天看天天摸天天操 | 91精品国产综合久久久亚洲 | av黄色在线| 成人av在线播放 | 久久久久久久一区二区三区 | 81精品国产乱码久久久久久 | 香蕉婷婷| 国产精品免费在线 | 亚洲最大成人综合 | 91精品国产综合久久久久久丝袜 | 国产精品福利网站 | 一级黄色片日本 | 欧美精品成人 | 亚洲精品电影 | 欧美在线视频一区 | a中文在线视频 | 日本在线一区二区三区 | 亚洲免费在线 | 国户精品久久久久久久久久久不卡 |