成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于UCOSII的RS485通信(STM32F107)

verano / 3199人閱讀

摘要:為了可靠工作,在總線狀態(tài)切換時(shí)需要做適當(dāng)延時(shí),再進(jìn)行數(shù)據(jù)收發(fā)。

一、實(shí)現(xiàn)效果

????????基于ucosii實(shí)時(shí)操作系統(tǒng)的RS485通信,采用USART + DMA進(jìn)行收發(fā),

?二、開發(fā)環(huán)境

  • 開發(fā)工具:KEIL V5
  • 開發(fā)板: STM32f107RC
  • 采用方式:USART + DMA
  • 使用系統(tǒng):UCOSII

三、RS485部分原理

????????在RS-485通訊網(wǎng)絡(luò)中,節(jié)點(diǎn)中的串口控制器使用RXTX信號(hào)線連接到收發(fā)器上,而收發(fā)器通過差分線連接到網(wǎng)絡(luò)總線,串口控制器與收發(fā)器之間一般使用TTL信號(hào)傳輸,收發(fā)器與總線則使用差分信號(hào)來傳輸。

????????發(fā)送數(shù)據(jù)時(shí),串口控制器的TX信號(hào)經(jīng)過收發(fā)器轉(zhuǎn)換成差分信號(hào)傳輸?shù)娇偩€上,

????????而接收數(shù)據(jù)時(shí),收發(fā)器把總線上的差分信號(hào)轉(zhuǎn)化成TTL信號(hào)通過RX引腳傳輸?shù)酱诳刂破髦小?/span>

????????MCU管腳輸出TTL電平,TTL電平的意思是,當(dāng)MCU管腳輸出0電平時(shí),一般情況下電壓是0V,當(dāng)MCU管腳輸出1電平時(shí),電壓是5V。因TTL電平的是由一條信號(hào)線,一條地線產(chǎn)生,信號(hào)線上的干擾信號(hào)會(huì)跟隨有效信號(hào)傳送到接收端,使得有效信號(hào)受到干擾,485通訊實(shí)際上是把MCU出來的TTL電平通過硬件層的一個(gè)轉(zhuǎn)換器芯片進(jìn)行轉(zhuǎn)換

????????RS-485通訊網(wǎng)絡(luò)的最大傳輸距離可達(dá)1200米,總線上可掛載128個(gè)通訊節(jié)點(diǎn),而由于RS-485網(wǎng)絡(luò)只有一對(duì)差分信號(hào)線,它使用差分信號(hào)來表達(dá)邏輯,當(dāng)AB兩線間的電壓差為-6V~-2V時(shí)表示邏輯1,當(dāng)電壓差為+2V~+6V表示邏輯0,在同一時(shí)刻只能表達(dá)一個(gè)信號(hào),所以它的通訊是半雙工形式的。

????????在單個(gè)實(shí)驗(yàn)板中,作為串口控制器的STM32USART外設(shè)引出TXRX兩個(gè)引腳與RS-485收發(fā)器MAX485相連,收發(fā)器使用它的AB引腳連接到RS-485總線網(wǎng)絡(luò)中。為了方便使用,我們每個(gè)實(shí)驗(yàn)板引出的AB之間都連接了1個(gè)120歐的電阻作為RS-485總線的端電阻,所以要注意如果要把實(shí)驗(yàn)板作為一個(gè)普通節(jié)點(diǎn)連接到現(xiàn)有的RS-485總線時(shí),是不應(yīng)添加該電阻的

????????MAX485芯片中有"RE"和"DE"兩個(gè)引腳,用于控制485芯片的收發(fā)工作狀態(tài)的,當(dāng)RE引腳為低電平時(shí),485芯片處于接收狀態(tài),當(dāng)DE引腳為高電平時(shí)芯片處于發(fā)送狀態(tài)。實(shí)驗(yàn)板中使用了STM32PD11直接連接到這兩個(gè)引腳上,所以通過控制PD11的輸出電平即可控制485的收發(fā)狀態(tài)。

?實(shí)驗(yàn)板之間AA連接,BB連接即可。

四、配置操作

?建立了5個(gè)任務(wù)

??任務(wù)名? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?優(yōu)先級(jí)
?? ??? ??? ?APP_TASK_START_PRIO? ? ? ? ? ? ??2?? ???????? 主任務(wù)?? ? ??? ??? ?
??????????? Task_Com4_PRIO???????????????????? ? ? ? 4?? ??? ??? ?COM4通信任務(wù)
? ? ? ? ??
?? ??? ? 當(dāng)然還包含了系統(tǒng)任務(wù):
?? ??? ???? OS_TaskIdle????????????????? 空閑任務(wù)-----------------優(yōu)先級(jí)最低
?? ??? ??? ?OS_TaskStat????????????????? 統(tǒng)計(jì)運(yùn)行時(shí)間的任務(wù)-------優(yōu)先級(jí)次低?

?4.1 主任務(wù)建立

 //建立主任務(wù), 優(yōu)先級(jí)最高  建立這個(gè)任務(wù)另外一個(gè)用途是為了以后使用統(tǒng)計(jì)任務(wù)os_err = OSTaskCreate((void (*) (void *)) App_TaskStart, (void *) 0,   //指向任務(wù)代碼的指針                                                                   (void *) 0,    //任務(wù)開始執(zhí)行時(shí),傳遞給任務(wù)的參數(shù)的指針                                                      (OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], //分配給任務(wù)的堆棧的棧頂指針   從頂向下遞減                  (INT8U) APP_TASK_START_PRIO);    //分配給任務(wù)的優(yōu)先級(jí)  
static  void App_TaskStart(void* p_arg) {   (void) p_arg    //使能ucos 的統(tǒng)計(jì)任務(wù)   #if (OS_TASK_STAT_EN > 0)    //----統(tǒng)計(jì)任務(wù)初始化函數(shù)     OSStatInit();                                      /* Determine CPU capacity.   */                          #endif      //建立其他的任務(wù)     App_TaskCreate();   while (1)   {       	  //1秒一次循環(huán)      OSTimeDlyHMSM(0, 0,1, 0);    } }

4.2 其他任務(wù)建立

static  void App_TaskCreate(void)  {     //CPU_INT08U os_err;		    //Com1_SEM=OSSemCreate(1);            //建立串口4中斷的信號(hào)量    Com4_MBOX = OSMboxCreate((void *) 0);             //建立串口4中斷的消息郵箱          //串口4接收及發(fā)送任務(wù)---------------------------------------------------------         OSTaskCreateExt(Task_Com4,                    //指向任務(wù)代碼的指針                        (void *)0,                 //任務(wù)開始執(zhí)行時(shí),傳遞給任務(wù)的參數(shù)的指針                     (OS_STK *)&Task_Com4Stk[Task_Com4_STK_SIZE-1],//分配給任務(wù)的堆棧的棧頂指針   從頂向下遞減                     Task_Com4_PRIO,               //分配給任務(wù)的優(yōu)先級(jí)					 Task_Com4_PRIO,               //預(yù)備給以后版本的特殊標(biāo)識(shí)符,在現(xiàn)行版本同任務(wù)優(yōu)先級(jí)                     (OS_STK *)&Task_Com4Stk[0],   //指向任務(wù)堆棧棧底的指針,用于堆棧的檢驗(yàn)                     Task_Com4_STK_SIZE,           //指定堆棧的容量,用于堆棧的檢驗(yàn)                     (void *)0,                   //指向用戶附加的數(shù)據(jù)域的指針,用來擴(kuò)展任務(wù)的任務(wù)控制塊				     OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //選項(xiàng),指定是否允許堆棧檢驗(yàn),是否將堆棧清0,任務(wù)是否要進(jìn)行浮點(diǎn)運(yùn)算等等。 }

4.2.1 建立子任務(wù)——串口通信的任務(wù)

串口通信的任務(wù):這里采用消息郵箱進(jìn)行消息傳遞,

  • 在建立其他任務(wù)App_TaskCreate(void)的開始就首先建立串口的消息郵箱:Com4_MBOX=OSMboxCreate((void *)?0);
  • 然后在串口通信的任務(wù)中進(jìn)入循環(huán)后就一直等待消息郵箱的信息(第8行),如果沒有消息過來就一直等待,在此期間其他任務(wù)可以進(jìn)行,一旦有消息發(fā)送過來,由于串口通信的優(yōu)先級(jí)較高,就能很快響應(yīng),根據(jù)收到的消息msg來自定義。
  • 這里因?yàn)榇诮邮找玫街袛?,所以下面就說說串口通信的接收中斷部分。
static  void Task_Com4(void *p_arg){         INT8U err;		 int i;    unsigned char * msg;     (void)p_arg;                             while(1)	{                 //OSSemPend(Com1_SEM,0,&err);          //等待串口接收指令成功的信號(hào)量       msg=(unsigned char *)OSMboxPend(Com4_MBOX, 0,&err);         //等待串口接收指令成功的郵箱信息		        //輸出郵箱信息的前10個(gè)數(shù)據(jù)      if(msg != NULL)	  {			for(i = 0; i < 2; i++)			{				G_u8Usart1SendBuf[i] = 0x10;			}								USART_DMA_SendStart(DMA2_Channel5, 2);								memcpy(G_u8Usart1SendBuf, msg, 10);								USART_DMA_SendStart(DMA2_Channel5, 10);		}	    //DealWith_Data(pfifo); //處理數(shù)據(jù)    }  }

? ? ? ? 以下是串口中斷函數(shù),接收串口數(shù)據(jù),當(dāng)發(fā)現(xiàn)是完整的幀時(shí),就調(diào)用OSMboxPost(Com4_MBOX,(void *)&msg);發(fā)送一個(gè)郵箱消息,進(jìn)而那邊的串口任務(wù)從掛起到喚醒,執(zhí)行相應(yīng)的過程。

使用ringbuffer實(shí)現(xiàn)任意數(shù)據(jù)類型的FIFO處理接收數(shù)據(jù),可以參考:stm32f0串口 DMA 空閑中斷接收——基于HAL庫(代碼篇)_噗噗bug博客-CSDN博客

void UART4_IRQHandler(void){  uint16_t t;	unsigned int i;	unsigned char msg[50];	OS_CPU_SR  cpu_sr;		OS_ENTER_CRITICAL()     //保存全局中斷標(biāo)志,關(guān)總中斷/	OSIntNesting++;		OS_EXIT_CRITICAL();  //恢復(fù)全局中斷標(biāo)志		if(USART_GetITStatus(UART4,USART_IT_IDLE) == SET)          //檢查中斷是否發(fā)生	{			RS485_TX_EN = 0;   				DMA_Cmd(DMA2_Channel3,DISABLE);                         //關(guān)閉DMA傳輸        DMA_ClearFlag( DMA2_FLAG_TC3 );  		t = DMA_GetCurrDataCounter(DMA2_Channel3);              //獲取剩余數(shù)量				//FIFO_Add(pfifo, G_u8Usart1RecvBuf, UART4_RECV_MAXLEN - t); //fifo數(shù)據(jù)保存				memcpy(msg, G_u8Usart1RecvBuf, UART4_RECV_MAXLEN - t);	    OSMboxPost(Com4_MBOX,(void *)&msg);				DMA_SetCurrDataCounter(DMA2_Channel3,UART4_RECV_MAXLEN);   //重新設(shè)置傳輸?shù)臄?shù)量				 		DMA_Cmd(DMA2_Channel3,ENABLE);                      //開啟DMA傳輸		USART_ReceiveData(UART4);                           //讀一次數(shù)據(jù),不然會(huì)一直進(jìn)中斷		USART_ClearFlag(UART4,USART_FLAG_IDLE);             //清除串口中斷標(biāo)志	}		OSIntExit();}

4.3?硬件初始化部分?

void BSP_Init(void){   /* NVIC configuration */   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    RS485_Config();   uart_init(9600);   delay_init();       //延遲函數(shù)初始化}

?4.4 RS485發(fā)送函數(shù)

注意:在485芯片的通信中,尤其要注意對(duì)485控制端DE的軟件編程。為了可靠工作,在485總線狀態(tài)切換時(shí)需要做適當(dāng)延時(shí),再進(jìn)行數(shù)據(jù)收發(fā)。具體的做法是

? ? ?在數(shù)據(jù)發(fā)送狀態(tài)下, ??先將控制端置“1”,延時(shí)1ms左右的時(shí)間,在發(fā)送有效的數(shù)據(jù),一包數(shù)據(jù)發(fā)送結(jié)束后再延時(shí)1ms后,將控制端置“0”,這樣處理會(huì)使總線在狀態(tài)切換時(shí),有一個(gè)穩(wěn)定的工作過程。代碼中延遲10ms(參考:https://blog.csdn.net/yx_l128125/article/details/7914102)

#define RS485_TX_EN  PAout(15)   設(shè)置RS485 mode控制, RX:0, TX:1void USART_DMA_SendStart(DMA_Channel_TypeDef *DMA_Streamx, u16 m_u16SendCnt)  {    	USART_DMACmd(UART4, USART_DMAReq_Tx, ENABLE);    RS485_TX_EN = 1;	delay_ms(10);	//延遲    DMA_Cmd(DMA_Streamx, DISABLE);   	delay_ms(10);	//延遲	    DMA_SetCurrDataCounter(DMA_Streamx, m_u16SendCnt);      DMA_Cmd(DMA_Streamx, ENABLE);                      	while(1)	{		if(DMA_GetFlagStatus(DMA2_FLAG_TC5)!=RESET)//μè′yí¨μà5′?ê?íê3é		{			DMA_ClearFlag(DMA2_FLAG_TC5);//??3yí¨μà5′?ê?íê3é±ê??			break; 		 }	}					delay_ms(10);	//延遲	RS485_TX_EN=0;   } 

4.5 主函數(shù)

int main(void){	    unsigned  char os_err;		OSInit();      //硬件初始化    BSP_Init();         // FIFO 環(huán)型處理數(shù)據(jù)初始化	pfifo = &fifo;	FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);	    OSInit();	    //先發(fā)送一段數(shù)據(jù),可屏蔽	for(i = 0; i < 50; i++)	{		G_u8Usart1SendBuf[i] = 0x10 + i;	}	USART_DMA_SendStart(DMA2_Channel5, 50);		 os_err = OSTaskCreate((void (*) (void *)) App_TaskStart, (void *) 0,                    //指向任務(wù)代碼的指針                         (void *) 0,                                           //任務(wù)開始執(zhí)行時(shí),傳遞給任務(wù)的參數(shù)的指針               (OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],    //分配給任務(wù)的堆棧的棧頂指針   從頂向下遞減               (INT8U) APP_TASK_START_PRIO);    //分配給任務(wù)的優(yōu)先級(jí) 	    OSTimeSet(0);    OSStart();      /* Start multitasking*/}

五、運(yùn)行串口調(diào)試

?參考:[stm32][ucos] 1、基于ucos操作系統(tǒng)的LED閃爍、串口通信簡(jiǎn)單例程 - beautifulzzzz - 博客園

stm32f0串口 DMA 空閑中斷接收——基于HAL庫(代碼篇)_噗噗bug博客-CSDN博客

代碼:

https://download.csdn.net/download/qq_41070511/24419255

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/121077.html

相關(guān)文章

  • STM32】標(biāo)準(zhǔn)庫與HAL庫對(duì)照學(xué)習(xí)教程八--串口通信詳解

    摘要:異步通信與同步通信異步通信異步通信是指通信的發(fā)送與接收設(shè)備使用各自的時(shí)鐘控制數(shù)據(jù)的發(fā)送和接收過程。同步通信同步通信時(shí)要建立發(fā)送方時(shí)鐘對(duì)接收方時(shí)鐘的直接控制,使雙方達(dá)到完全同步。配置串口設(shè)置為異步通信基礎(chǔ)參數(shù)波特率為。 ...

    yck 評(píng)論0 收藏0
  • 關(guān)于STM32 RS485控制I/O口不能正常輸出高低電平解決方法

    摘要:當(dāng)單片機(jī)要接收數(shù)據(jù)的時(shí)候,控制為低電平,數(shù)據(jù)通過接收回來。檢測(cè)通過萬用表測(cè)量控制的引腳一直處于高電平,即使函數(shù)就單獨(dú)寫將該引腳為低電平,測(cè)量出來還是高電平。 一、問題: 問題現(xiàn)象:在進(jìn)行RS485操作時(shí),發(fā)現(xiàn)接收時(shí)而進(jìn)時(shí)而不進(jìn)中斷: 將485的AB輸出腳直接與串口的TX,RX對(duì)接發(fā)現(xiàn)串...

    null1145 評(píng)論0 收藏0
  • 基于STM32移植UCGUI圖形界面框架(3.9.0源碼版本)

    摘要:基于的移植教程可以看這里二介紹是一種用于嵌入式應(yīng)用的圖形支持軟件。適用于使用任何控制和的任何尺寸的物理和虛擬顯示。一個(gè)層,稱作驅(qū)動(dòng)程序,包含了對(duì)的全部訪問。并在主函數(shù)里加入下面的代碼,測(cè)試移植是否成功。 一、環(huán)境介紹 keil:? ? 5.25 MCU:? STM32F103ZET6 UCG...

    microcosm1994 評(píng)論0 收藏0
  • EC20模組使用MQTT庫對(duì)接EMQX,基于STM32F407

    摘要:一說明本庫基于編譯,其他的內(nèi)核也支持,采用串口和模組通信。使用時(shí)添加文件到工程中,頭文件引用即可。此外,需要外部實(shí)現(xiàn)模組的復(fù)位操作,一般是對(duì)管腳拉高一段時(shí)間,復(fù)位函數(shù)需要指定函數(shù)為。四實(shí)例以下為使用的庫,實(shí)現(xiàn)對(duì)接自建。 一、說明 本lib庫基于STM32F407編譯,其他的cortexM4內(nèi)...

    whatsns 評(píng)論0 收藏0
  • STM32F103基于spi實(shí)現(xiàn)OLED顯示

    摘要:文章目錄一原理二實(shí)現(xiàn)顯示中文滾動(dòng)顯示顯示字符串讀取溫濕度顯示溫濕度三結(jié)果開機(jī)顯示歡迎信息循環(huán)讀取溫濕度以及滾動(dòng)顯示我的四總結(jié)五參考六源碼一原理的定義就是串行外圍設(shè)備接口。 ...

    xfee 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<