1. 程式人生 > >USART串列埠總結2

USART串列埠總結2

前言:開始學USART+DMA的時候看到帖子《STM32 UART DMA實現未知資料長度接收》,覺得方法妙極了。此下出自此帖子——(整體的思路是這樣的,一開始設定好DMA接收,可以把緩衝區長度設定為幀最大長度,我們可以把RX連線到定時器的管腳輸入端,並且一開始設定輸入並且使能引腳下降沿中斷,當幀的第一個位元組傳送時,因為起始位為低電平,空閒時UART為高電平,滿足條件,進入中斷,禁止中斷,並且在中斷中開啟定時器,該定時器工作在復位模式,上升沿復位,並且設定好定時器輸出比較值為超時時間,比如20ms,這樣,在傳輸後面位元組時,肯定會有高低電平出現,即便是傳輸的是0x000xFF,雖然UART資料區不變,但是都為

1,或都為0,但是因為起始位為低電平,停止位是高電平,所以肯定會有上升沿,定時器會一直復位,輸出定時器的計數器一直到達不了輸出比較值,當一幀傳輸結束後,定時在最後一個位元組復位後,由於沒有資料繼續到達,無法復位,則計數器就能計到輸出比較值,這時發出中斷,在定時器中斷中可以計算出接收資料的長度,並且通知外部資料已經接收完畢。

今天我在工作中調通了另一種USART+DMA接收未知資料長度的接收,使用的是USRAT空閒匯流排中斷接收,這種方法也在網站上比較多見,以前沒試過,今天才知道如此的爽,另外我使用DMA傳送USART資料替代了以前的查詢法傳送,發現更加爽了。其速度快了很多,尤其是在大量資料傳輸與傳送的時候其優勢更加明顯。

我舉個例子:1、後臺資料->USART1-> USART2->其它裝置,其它裝置資料->USART2-> USART21->後臺,這兩個資料過程也可能同時進行。

2、由於硬體的限制,USART1USART2的傳輸波特率不一樣,比如USART1使用GPRS通訊,USART2使用短距離無線通訊;或者USART1使用乙太網通訊,USART2使用485匯流排通訊。

由於在寢室只有膝上型電腦,只有一個串列埠轉USB,沒辦法實現兩個串列埠之間的資料轉發了,只好實現串列埠各自的資料轉發。

現在我把我實現的過程簡單描述一下:

1、 初始化設定:USART1_RX+DMA1_

 Channel5,USART2_RX+DMA1_ Channel6USART1_TX+DMA1_ Channel4USART2_TX+DMA1_ Channel7(具體設定請看程式包)。

2、 當資料傳送給USART1接收完畢時候會引起USART1的串列埠匯流排中斷,計算DMA1_ Channel5記憶體陣列剩餘容量,得到接收的字元長度。將接收的字元複製給DMA1_ Channel4記憶體陣列,啟動DMA1_ Channel4通道傳輸資料,(傳輸完成需要關閉。)下一次資料接收可以在啟動DMA1_ Channel4時候就開始,不需要等待DMA1_ Channel4資料傳輸完成。但是上一次DMA1_ Channel4完成之前,不可以將資料複製給DMA1_ Channel4記憶體陣列,會沖掉以前資料。

3、 USART2類同USART1

呵呵,下面貼程式:

IO口定義:

void GPIO_Configuration(void)

{

   GPIO_InitTypeDef GPIO_InitStructure;

   /* 1步:開啟GPIOUSART部件的時鐘 */

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

   /* 2步:將USART TxGPIO配置為推輓複用模式 */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOA, &GPIO_InitStructure);

   /* 3步:將USART RxGPIO配置為浮空輸入模式

   由於CPU復位後,GPIO預設都是浮空輸入模式,因此下面這個步驟不是必須的

   但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設定引數

   */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

   GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 1步:開啟GPIOUSART2部件的時鐘 */

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

/* 2步:將USART2 TxGPIO配置為推輓複用模式 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 3步:將USART2 RxGPIO配置為浮空輸入模式

由於CPU復位後,GPIO預設都是浮空輸入模式,因此下面這個步驟不是必須的

但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設定引數

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*  3步已經做了,因此這步可以不做

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

*/

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

串列埠初始化:

void USART_Configuration(void)

{

USART_InitTypeDef USART_InitStructure;

   /* 4步:配置USART引數

   - BaudRate = 115200 baud

   - Word Length = 8 Bits

   - One Stop Bit

   - No parity

   - Hardware flow control disabled (RTS and CTS signals)

   - Receive and transmit enabled

   */

   USART_InitStructure.USART_BaudRate = 19200;

   USART_InitStructure.USART_WordLength = USART_WordLength_8b;

   USART_InitStructure.USART_StopBits = USART_StopBits_1;

   USART_InitStructure.USART_Parity = USART_Parity_No;

   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

   USART_Init(USART1, &USART_InitStructure);

   //空閒中斷

   USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);

/* 5步:使能 USART, 配置完畢 */

   USART_Cmd(USART1, ENABLE);  

/* CPU的小缺陷:串列埠配置好,如果直接Send,則第1個位元組傳送不出去

   如下語句解決第1個位元組無法正確傳送出去的問題 */

   USART_ClearFlag(USART1, USART_FLAG_TC); /* 清發送外城標誌,Transmission Complete flag */

USART_InitStructure.USART_BaudRate = 9600;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

   USART_Init(USART2, &USART_InitStructure);

   USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);//開啟空閒,幀錯,噪聲,校驗錯中斷 

USART_Cmd(USART2, ENABLE);

/* CPU的小缺陷:串列埠配置好,如果直接Send,則第1個位元組傳送不出去

   如下語句解決第1個位元組無法正確傳送出去的問題 */

   USART_ClearFlag(USART2, USART_FLAG_TC); /* 清發送外城標誌,Transmission Complete flag */

}

DMA配置:

void DMA_Configuration(void)

{

  DMA_InitTypeDef DMA_InitStructure;

  /* DMA clock enable */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1

  /* DMA1 Channel4 (triggered by USART1 Tx event) Config */

  DMA_DeInit(DMA1_Channel4);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_SEND_DATA;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = 512;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel4, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);

  DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);

  /* Enable USART1 DMA TX request */

  USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

  DMA_Cmd(DMA1_Channel4, DISABLE);

  /* DMA1 Channel5 (triggered by USART2 Tx event) Config */

  DMA_DeInit(DMA1_Channel7);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_SEND_DATA;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = 512;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel7, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);

  DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);

  /* Enable USART1 DMA TX request */

  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

  DMA_Cmd(DMA1_Channel7, DISABLE);

  /* DMA1 Channel5 (triggered by USART1 Rx event) Config */

  DMA_DeInit(DMA1_Channel5);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RECEIVE_DATA;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 512;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel5, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

  DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);

  /* Enable USART1 DMA RX request */

  USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

  DMA_Cmd(DMA1_Channel5, ENABLE);

  /* DMA1 Channel6 (triggered by USART1 Rx event) Config */

  DMA_DeInit(DMA1_Channel6);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RECEIVE_DATA;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 512;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel6, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

  DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);

  /* Enable USART2 DMA RX request */

  USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

  DMA_Cmd(DMA1_Channel6, ENABLE);

}

中斷優先順序配置:

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure one bit for preemption priority */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  

  /* Enable the USART1 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /* Enable the USART2 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  //Enable DMA Channel4 Interrupt 

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  //Enable DMA Channel7 Interrupt 

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /*Enable DMA Channel5 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /*Enable DMA Channel6 Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

陣列定義,含義如題名:

u8 USART1_SEND_DATA[512];     

u8 USART2_SEND_DATA[512]; 

u8 USART1_RECEIVE_DATA[512]; 

u8 USART2_RECEIVE_DATA[512]; 

u8 USART1_TX_Finish=1;// USART1傳送完成標誌量

u8 USART2_TX_Finish=1; // USART2傳送完成標誌量

USART1中斷服務函式

void USART1_IRQHandler(void)

{

u16 DATA_LEN;

u16 i;

  if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//如果為空閒匯流排中斷

    {

DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料

//USART_RX_STA = USART1->SR;//先讀SR,然後讀DR才能清除

        //USART_RX_STA = USART1->DR;

   DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5); 

if(DATA_LEN > 0)

        {

while(USART1_TX_Finish==0)//等待資料傳輸完成才下一次

            {

                ;

            }

//將資料送DMA儲存地址

            for(i=0;i<DATA_LEN;i++)

            {

                USART1_SEND_DATA[i]=USART1_RECEIVE_DATA[i];

            }

            //USARTDMA傳輸替代查詢方式傳送,克服被高優先順序中斷而產生丟幀現象。

            DMA_Cmd(DMA1_Channel4, DISABLE); //改變datasize前先要禁止通道工作

            DMA1_Channel4->CNDTR=DATA_LEN; //DMA1,傳輸資料量

            USART1_TX_Finish=0;//DMA傳輸開始標誌量

            DMA_Cmd(DMA1_Channel4, ENABLE);

}

//DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料

DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清標誌

DMA1_Channel5->CNDTR = 512;//重灌填

DMA_Cmd(DMA1_Channel5, ENABLE);//處理完,重開DMA

//SR後讀DR清除Idle

i = USART1->SR;

i = USART1->DR;

}

if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出錯

{

USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);

}

   USART_ClearITPendingBit(USART1, USART_IT_TC);

   USART_ClearITPendingBit(USART1, USART_IT_IDLE);

}

USART2中斷服務函式

void USART2_IRQHandler(void)

{

u16 DATA_LEN;

u16 i;

  if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //如果為空閒匯流排中斷

    {

DMA_Cmd(DMA1_Channel6, DISABLE);//關閉DMA,防止處理其間有資料

//USART_RX_STA = USART1->SR;//先讀SR,然後讀DR才能清除

        //USART_RX_STA = USART1->DR;

   DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6); 

if(DATA_LEN > 0)

        {

while(USART2_TX_Finish==0)//等待資料完成才下一次

            {

                ;

            }

//將資料送DMA儲存地址

            for(i=0;i<DATA_LEN;i++)

            {

                USART2_SEND_DATA[i]=USART2_RECEIVE_DATA[i];

            }

            //USARTDMA傳輸替代查詢方式傳送,克服被高優先順序中斷而產生丟幀現象。

            DMA_Cmd(DMA1_Channel7, DISABLE); //改變datasize前先要禁止通道工作

            DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,傳輸資料量

            USART2_TX_Finish=0;//DMA傳輸開始標誌量

            DMA_Cmd(DMA1_Channel7, ENABLE);

}

//DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料

DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清標誌

DMA1_Channel6->CNDTR = 512;//重灌填

DMA_Cmd(DMA1_Channel6, ENABLE);//處理完,重開DMA

//SR後讀DR清除Idle

i = USART2->SR;

i = USART2->DR;

}

if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出錯

{

USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);

}

   USART_ClearITPendingBit(USART2, USART_IT_TC);

   USART_ClearITPendingBit(USART2, USART_IT_IDLE);

}

DMA1_Channel5中斷服務函式

void DMA1_Channel5_IRQHandler(void)

{

  DMA_ClearITPendingBit(DMA1_IT_TC5);

  DMA_ClearITPendingBit(DMA1_IT_TE5);

  DMA_Cmd(DMA1_Channel5, DISABLE);//關閉DMA,防止處理其間有資料

  DMA1_Channel5->CNDTR = 580;//重灌填

  DMA_Cmd(DMA1_Channel5, ENABLE);//處理完,重開DMA

}

DMA1_Channel6中斷服務函式

void DMA1_Channel6_IRQHandler(void)

{

  DMA_ClearITPendingBit(DMA1_IT_TC6);

  DMA_ClearITPendingBit(DMA1_IT_TE6);

  DMA_Cmd(DMA1_Channel6, DISABLE);//關閉DMA,防止處理其間有資料

  DMA1_Channel6->CNDTR = 580;//重灌填

  DMA_Cmd(DMA1_Channel6, ENABLE);//處理完,重開DMA

}

DMA1_Channel4中斷服務函式

//USART1使用DMA發資料中斷服務程式

void DMA1_Channel4_IRQHandler(void)

{

  DMA_ClearITPendingBit(DMA1_IT_TC4);

  DMA_ClearITPendingBit(DMA1_IT_TE4);

  DMA_Cmd(DMA1_Channel4, DISABLE);//關閉DMA

  USART1_TX_Finish=1;//DMA傳輸完成

}

DMA1_Channel7中斷服務函式

//USART2使用DMA發資料中斷服務程式

void DMA1_Channel7_IRQHandler(void)

{

  DMA_ClearITPendingBit(DMA1_IT_TC7);

  DMA_ClearITPendingBit(DMA1_IT_TE7);

  DMA_Cmd(DMA1_Channel7, DISABLE);//關閉DMA

  USART2_TX_Finish=1;//DMA傳輸完成

}

呵呵,全部完,但是程式在開始啟動時會出現

自己發幾個不知道什麼字元,之後一切正常。如有什麼問題,請大神指教。個人認為問題不大,因為在工作的時候通過STM32訪問後臺或者後臺訪問STM32大量的間隔密的資料時沒有出現問題。而如果沒有使用DMA,單幀資料發收可以,多幀資料經過USART1USART2,就收不到從USART2反饋的第二幀資料了。不一定是速度上的問題,可能是我處理順序的問題,但是不管是巧合,還是瞎撞的,總歸解決辦法的就是好辦法。

相關推薦

USART串列總結2

前言:開始學USART+DMA的時候看到帖子《STM32 UART DMA實現未知資料長度接收》,覺得方法妙極了。此下出自此帖子——(整體的思路是這樣的,一開始設定好DMA接收,可以把緩衝區長度設定為幀最大長度,我們可以把RX連線到定時器的管腳輸入端,並且一開始設定輸入並且

USART串列全雙工與SPI全雙工通訊的區別!

目錄 1.背景知識 背景知識 首先我們先來區分一下單工、半雙工、全雙工模式。 單工:資料傳輸只支援資料在一個方向上傳輸 半雙工:允許資料傳輸在兩個方向傳輸,但是,在某一時刻,只允許資料在一個方向上傳輸,它實際上是一種切換方向的單工通訊。 全雙工:允許資

物聯網之STM32開發三(USART串列

STM32-USART串列埠的應用 內容概要: 序列通訊的基本概念 串列埠暫存器介紹 STM32實現串列埠資料的收發 HAL串列埠庫函式的使用及printf的實現 序列通訊的基本概念: 內容概要: 通訊的基本概念 USART介紹 串列埠的電路連線 串列埠

嵌入式Linux驅動學習之USART串列控制:基於AT91SAM9261EK

    普通微控制器的串列埠操作比較容易,但是基於Linux系統的串列埠操作難不難呢?其實,基於Linux作業系統的串列埠操作分為兩個部分:串列埠驅動部分(底層驅動與設備註冊)與串列埠的應用程式(使用者程式)。一般廠家或是Linux核心已經提供了基於開發板的串列埠驅動,只需

STM32F10x USART串列對映功能實現串列通訊 485初始化

這篇文章很有用!新手不要自以為是,STM32串列埠管腳重對映小樣你會嗎??? STM32F10x 系列微控制器中都包含了USART 模組,所謂USART,就是通用同步非同步收發器。通用同步非同步收發器(USART)提供了一種靈活的方法與使用工業標準NRZ非同步序列資料格

usart串列使用

static void Bsp_UsartInit(void) {     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);     GPIO_InitTypeDef  GPIO_InitStructure;     USART_InitTypeDe

STM32 USART串列DMA 接收和傳送流程詳解

https://blog.csdn.net/weibo1230123/article/details/80506484 1.dm

STM32F4——串列USART)通訊總結

一、概述:     USART即通用同步非同步收發器,用於靈活的與外部裝置全雙工資料交換,它支援多種通訊傳輸方式,可以通過小數波特率發生器提供多種波特率。 二、串列埠IO:     對於STM32F4

WIN7 64位系統 CDC類 虛擬串列驅動無法安裝的解決辦法(2

(1)最近用STM32使用USB——CDC類出現驅動安裝失敗的情況。 百度了一些網頁,方法很多,大多數是按照如下步驟處理: 首先,確保C:\Windows\System32\drivers\usbser.sys檔案存在; 其次,修改C:\Windows\inf\mdmcpq.inf檔

串列顯示亂碼的原因總結

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

STM32串列USART

一、通用同步非同步收發器(USART)          通用同步非同步收發器(USART)提供了一種靈活的方法與使用工業標準NRZ非同步序列資料格式的 外部裝置之間進行全雙工資料交換。USART利用分數波特率發生器提供寬範圍的波特率選擇。 它支

STM32系統學習——USART串列通訊)

串列埠通訊是一種裝置間非常常用的序列通行方式,其簡單便捷,大部分電子裝置都支援。 一、物理層 常用RS-232標準,主要規定了訊號的用途、通訊介面以及訊號的電平標準。     “DB9介面”之間通過串列埠訊號線建立起連線,串列埠訊號線使用”RS-232標準“傳

串列模組總結

這一次我把VC6.0上執行沒有問題的串列埠模組挪到VS2010上。 字符集轉換的問題我已經很好地解決了,編譯通過,執行的時候卻發現程式無法找到串列埠。 自然無法連線和收發資料。 我實在不知道為什麼不行,所以我查了一下串列埠通訊: 我的程式碼是用了第二種方法,使用了Active X控制元件

串列通訊問題總結

進位制不決定資料的記憶體,型別決定資料結構大小 不同進位制的加減乘除都是相同的運算,只是進率不同而已 陣列是由若干個相同的資料型別的資料組成,陣列定義時已經確定了其中每一個元素的型別 字元陣列在記憶體中存放字串,每一個字元陣列元素存放一個字元的ASCII碼 51微控制器系統中SBUF

S3C2440裸機程式【2串列uart程式

         學習ARM7晶片stm32時,裸機程式開發可以很方便的根據庫函式在工程模板上進行開發,而ARM9主要是移植Linux開發,很少有裸機程式開發,因此在玩S3C2440希望最終形成一個keil環境下的模板。用的淘寶上的JZ2440v

stm32串列通訊的一個小總結(從底層進行理解)

從底層理解stm32USART串列埠通訊 以前學串列埠通訊踩過很多坑,過了一段時間又有些忘了,現在問了幾個很強很強的人差不多弄懂了,現在寫一寫總結,免得以後又忘了。 基本知識: 1、TDR和RDR都是USART_DR暫存器的緩衝區,指的是USART_DR的0到8位,TD

STM32串列2種通訊模式:非同步通訊與同步通訊

目錄 3.非同步通訊 1.特點 4.同步通訊 1.特點  傳送資料暫存器TDR和傳送移位暫存器:傳送暫存器用來儲存要傳送的資料,一位暫存器用來將資料從LSB一位一位地移出去  接收資料暫存器RDR和接收移位暫存器:接受資料移位暫存器將資料從L

2.4GHz串列自由遙控_PS2手柄驅動安裝

2.4GHz串列埠自由遙控_手柄驅動_安裝注意事項 製作小車,買了個無線手柄,採用串列埠轉2.4GHz通訊,PS2手柄形式,USB充電,可自定義按鍵 安裝驅動廢了老大的勁,有些事項記錄在此。 介面如下:(2.4GHz模組,不知道高頻訊號會不會與干擾其它電路。

nRF52832——基於SDK15.2 加入串列透傳服務

【背景】:專案需求,需要手機和裝置進行藍芽雙向資料傳輸,需要在原工程基礎上加入此通訊工程,使用的是SDK15.2,而官方原始碼已經帶有使用的藍芽串列埠透傳例程,所以參照此例程,移植到現有的工程中即可。但是移植過程卻遇到非常蛋疼的事。 【移植要點】:下面主要提及要點,與SDK12.3的差異;

[連載]《C#通訊(串列和網路)框架的設計與實現》-2.框架的總體設計

目       錄 C#通訊(串列埠和網路)框架的設計與實現... 1 (SuperIO)- 框架的總體設計... 1 第二章           框架總體的設計... 2 2.1           宿主程式設計... 2 2.2           通訊機制設計... 7   2.2.1