單片機之間用普通IO做模擬通信設計(類似於IIC的主機和從機)

一、背景介紹

一般單片機之間通信由Mcu的硬件模塊完成,一般有:Spi、IIC、Uart、Can等,但也會遇到通信接口全部用完,則可以使用IO來模擬做通信協議。以下例程中,主機使用3個IO,從機也使用3個IO,實現主機發數據給從機的目的。(因沒有使用到從機給主機發數據,所以沒有設計)

二、使用過程設計

在比較熟悉Iic、Spi等通信協議,瞭解時鐘、數據線等之後,便可以嘗試使用IO來模擬實現通信協議。

在此應用中,主機使用3個普通Io,從機使用3個普通Io。分別用作:片選CS,時鐘線SCL,數據線SDACS線從機控制,SCL和SDA線主機控制。時序圖如下所示

由於從機比較空閒(此實際應用中從機在2Ms內有80%時間處於空閒),所以在從機可以接收數據時,把CS線拉高,此時主機在想發數據時查詢CS線是否處於高電平,處於高電平時,通過控制SCL和SDA線發送串行16Bit數據。

三、主機程序設計思路

主機通過查詢CS線到拉高時,則通過控制SDA和SCL發送數據。

/*調用此函數,下發2個8Bit(16Bit)數據*/
void ArrayShowDriveProcess(UINT8 data1, UINT8 data2)
{
	UINT8 i;
	UINT16 tempTransferData;
	UINT32 tempData;
	tempData = GetMs(0);
	while((GpioInDataGet(COM_PORT)&COM_CS_PIN) == 0)
	{//等待CS線拉高
		if((GetMs(0) - tempData) > 3)
		{//OverTime, return back.                    //3Ms內還沒等到CS線拉高,發送失敗,退出發送
			return;
		}
	}
	{//SDA High,開始傳輸,大約需要75Us傳輸完成16Bit。Clk=200KHz
		GpioOutDataClrBits(COM_PORT,COM_SCL_PIN);    //拉低SCL
		tempTransferData = ((data2<<8)|data1);
		for(i = 0 ; i < 16 ; i++ )                   //循環16次,發送16Bit數據
		{
			GpioOutDataClrBits(COM_PORT,COM_SCL_PIN);
			if(tempTransferData&BIT15)
				GpioOutDataSetBits(COM_PORT,COM_SDA_PIN);//拉SDA = 1
			else
				GpioOutDataClrBits(COM_PORT,COM_SDA_PIN);//拉SDA = 0
			tempTransferData <<= 1;
			__ASM
			{
			/*1*//*等待一定時間,此處用Nop方便控制時鐘頻率*/
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
			}
			GpioOutDataSetBits(COM_PORT,COM_SCL_PIN);    //拉高CS
			__ASM
			{
			/*1*//*等待一定時間,此處用Nop方便控制時鐘頻率*/
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
				NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
			}
		}
	}
	return;                                               //發送完成,退出
}

四、從機程序設計

從機在可接收數據時,拉高CS線後通過查詢SCL和接收SDA發來的數據。

    UINT32 tempData;
    UINT32 tempData2;
    UINT8 i,ioRec;
	
    tempData2 = GetMs(0);
    GpioOutDataSetBits(COM_PORT, COM_CS_PIN);                //拉高CS,從機可接收數據
    while((GetMs(0) - tempData2) < 2)                        //在2Ms內查詢是否需要接收數據
    {
        if( (GpioInDataGet(COM_PORT)&COM_SCL_PIN) == 0)      //判斷CS線
	    {//查詢到時鐘線下降,開始傳輸
		    ioRec = 0;
	    	tempData = GetMs(0);
	    	for(i = 0; i < 16;)                              //循環查收16Bit數據
	    	{
	    		if((ioRec == 0)&&(GpioInDataGet(COM_PORT)&COM_SCL_PIN))
	        	{//Low To High                               //SCL電平從低變高
				    ioRec = 1;
		    		recData <<= 1;
    				if((GpioInDataGet(COM_PORT)&COM_SDA_PIN))
	    			{
		    			recData |= BIT0;                    //SDA電平高,接收1
			    	}
				    else// if(GpioInDataGet(COM_PORT)&COM_SDA_PIN)
    				{
	    				recData &= (~BIT0);                 //SDA電平低,接收0
		    		}
			    	i++;
    			}
	    		else if((ioRec == 1)&&((GpioInDataGet(COM_PORT)&COM_SCL_PIN) == 0))
		    	{//High to Low                               //SCL電平從高變低
			    	ioRec = 0;
    			}
	    		else
		    	{//Judge Over Time
			    	if((GetMs(0) - tempData) > 2)            //2Ms Over Time.
				    {                               //判斷接收是否超時。超過2Ms,拉高CS退出
					    GpioOutDataClrBits(COM_PORT, COM_CS_PIN);
    					recData = 0xFF;
	    				break;
		    		}
			    }
    		}
	    	GpioOutDataClrBits(COM_PORT, COM_CS_PIN);        //接收完成,拉高CS線
	}
	GpioOutDataClrBits(COM_PORT, COM_CS_PIN);     //等待接收時間完成,退出後拉高拉高CS線

五、總結

一般做模擬主機發送比較簡單,只需在發送時控制信號線和時鐘線,按照速率發送數據即可。

做從機的接收都比較複雜,而且對從機的響應速度有要求(如果從機中斷程序較多,則會影響響應速度),需要從機比較空閒才能做接收。另外,一般做從機的模擬接收也可通過IO的中斷,來達到及時響應的目的。

在此應用中,因爲從機固定在2Ms內有80%的時間可拉高接收數據,而且從機程序架構比較簡單,也沒有中斷服務程序,纔可以這樣做。以後遇到問題具體問題再具體分析。

本人新建了個QQ羣,如想進一步溝通可添加:947187213。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章