LPC4370使用學習:GPIO的引腳功能使用,和12864OLED模擬I2C驅動

一:  手中有塊LPC4370的開發板,由於便宜,因此引腳引出的很少,並且只有基本的底板資源驅動代碼和例程。 函數

  看着手冊和例程看了老半天,寫程序寫了半天,結果GPIO總是驅動不起來,由於引腳配置寄存器中有個MODE(選擇引腳功能)的選項中8個function功能不知道到底啥意思,其中一個手冊 LPC4350_30_20_10_User_manuall_CN( 下載地址: http://www.waveshare.net/w/upload/d/d9/LPC4350_30_20_10_User_manuall_CN.pdf    原諒我,只是單純的找資源,我買的開發板不是這家的...... )中在 15.4.1 標準電平驅動引腳的引腳配置寄存器  的 表 123. 標準電平驅動引腳的引腳配置寄存器  中能夠看到只標註了每一個引腳有八個功能,看了例程也沒有介紹究竟是怎麼用的。通過一番探究,終於知道了這八個引腳功能怎麼用的。ui

  這八個引腳功能的使用要配合另外一個手冊 LPC4350_30_20_10_Datasheet_CN(下載地址:http://www.waveshare.net/w/upload/4/48/LPC4350_30_20_10_Datasheet_CN.pdf)中的6.2 引腳描述  中的 表 3. 引腳描述 來對應查找。spa

 首先在左側的 多路複用數字引腳 找到對應使用的引腳,再在右側找到要使用的功能,從上到下按照從0到7的順序找本身要用到的功能,用到第幾個就是FUNC幾。每一個引腳的功能順序竟然沒有規則(仍是雖然有可是我沒找到?),要一個一個查找,好麻煩。.net

  注意:其中GPIO功能後面寫着對應的GPIO引腳的數字命名(術語叫啥??),這個下面會用到。有的原理圖上只有能標到字母的引腳號,而還找到了一張LPC43xx原理圖上詳細的引腳功能都寫上了(這個本身找吧,通常的都會給,只要有一個引腳名就能夠到第二個手冊上查到)資源

  不知走過路過的有沒有什麼更好的方法麼?只能按表查找?開發

 

二:下面再來講說基本的庫函數:(感受寄存器方法不是我能駕馭的了的......怎麼簡單我喜歡怎麼來)文檔

  1)首先,爲了使用方便,能夠先作以下定義:get

/* 假設使用P9_4 的GPIO功能*/it

 

#define Pin_Name_GPIO_PORT      9
#define Pin_Name_GPIO_Pin       4
#define Name_GPIO_Function        FUNC4
#define Name_GPIO_PORT         5
#define Name_GPIO_BIT          17io

前兩個好理解,用哪一個腳就寫啥,如用PD_4就分別寫成0x0d 和 4,其餘同理。

function項上面說了,查表。

最後兩個呢,也是看FUNCX那個,就是上面說的那個引腳描述表,在GPIO功能後面緊接着標了GPIOx[y],則PORT 項定義的就是x,BIT項定義的就是y.到時候一看圖就對應起來了。沒截圖,到時候一看就懂。

 2)初始化函數:

void scu_pinmux(uint8_t port, uint8_t pin, uint8_t mode, uint8_t func)
{
  uint32_t * scu_base=(uint32_t*)(LPC_SCU_BASE);
  scu_base[(PORT_OFFSET*port+PIN_OFFSET*pin)/4]=mode+func;
}

第一個參數就是上面的第一個  Pin_Name_GPIO_PORT ,第二個參數就是第二個Pin_Name_GPIO_Pin,第三個參數是引腳的一些模式設置,如速度,是否開啓上拉等,具體的去scu_18xx_43xx.h查看。第四個參數就是FUNCx,x爲你想用的那個功能。

3)引腳方向設置:輸入仍是輸出  0:輸入;1:輸出

參數分別爲第四個Name_GPIO_PORT和第五個Name_GPIO_BIT,其中bitValue須要左移一位,詳情見例子(緣由?我也不知道......之後多用用也許我就哪天頓悟了)

void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
{
  if (dir)
    {
      LPC_GPIO_PORT->DIR[portNum] |= bitValue;
    } else
    {
      LPC_GPIO_PORT->DIR[portNum] &= ~bitValue;
    }
}

使用例子:

    scu_pinmux(Pin_Name_GPIO_PORT  ,Pin_Name_GPIO_Pin  , (MD_PUP | MD_EZI | MD_ZI), Name_GPIO_Function );

    GPIO_SetDir(Name_GPIO_PORT,(1<<Name_GPIO_BIT), 1);

    兩個語句完成對某個引腳的初始化。可能須要引腳時鐘的初始化,這個可能在系統初始化中了,或者須要本身寫?我再試試。

 4)某引腳輸出高電平:

void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
{
LPC_GPIO_PORT->SET[portNum] = bitValue;
}

5)某引腳輸出低電平:

void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)
{
LPC_GPIO_PORT->CLR[portNum] = bitValue;
}

兩個參數都要用第四和第五個,即分別對應Name_GPIO_PORT 和Name_GPIO_BIT

 

使用時能夠修改定義,也可直接輸入Pin值。

而引腳的輸入設置,就是把上面GPIO_SetDir 的最後一個方向參數設置爲0即爲輸入。

引腳的輸入狀態讀取,函數都在 gpio_18xx_43xx.h頭文件裏,gpio_18xx_43xx.c裏面沒有。具體可本身翻閱。

三:GPIO模擬IIC驅動12864OLED的模擬IIC代碼:

  LPC4370貌似有兩個很強大的硬件I2C口,包括I2C0,和I2C1,可是,目前我還沒看懂,不會用。會用了在抽空貼一下用法。

//模擬IIC使用引腳:

//  SCL   P1_3   GPIO 0[10]   FUNC0
//  SDA  PD_4   GPIO 6[18]   FUNC4
//詳情見LPC4357MCU的詳細原理圖
//FUNCx的肯定要到Datesheet文檔按照引腳詳細查詢

#define SCL_Pin_name_PORT 1
#define SCL_Pin_name_BIT 3
#define SCL_pin_Function FUNC0
#define SCL_GPIO_PORT 0
#define SCL_GPIO_BIT 10

#define SDA_Pin_name_PORT 0xd
#define SDA_Pin_name_BIT 4
#define SDA_pin_Function FUNC4
#define SDA_GPIO_PORT 6
#define SDA_GPIO_BIT 18

/***************************************/
//IIC初始化代碼

//做者:執念執戰
/***************************************/

void IIC_init(void )

{

scu_pinmux(SCL_Pin_name_PORT ,SCL_Pin_name_BIT , MD_PUP|MD_ZI , SCL_pin_Function);
GPIO_SetDir(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT), 1);

scu_pinmux(SDA_Pin_name_PORT ,SDA_Pin_name_BIT , MD_PUP|MD_ZI, SDA_pin_Function);
GPIO_SetDir(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT), 1);

}


///***************************************/

//IICstart函數

//做者:執念執戰

//備註:可能因爲LPC4370速度太快,若是不加延時屏幕根本不亮。加了延時就行了。延時時間並不精確,隨便寫的。

///***************************************/

void IIC_start()
{

GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
delay(10);

}
/***************************************/

//IIC_stop函數

// 做者:執念執戰

//備註:可能因爲LPC4370速度太快,若是不加延時屏幕根本不亮。加了延時就行了。延時時間並不精確,隨便寫的。

/***************************************/

void IIC_stop()
{

GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
delay(10);


}

/***************************************/
// Write_IIC_Byte函數

//做者:執念執戰
//備註:可能因爲LPC4370速度太快,若是不加延時屏幕根本不亮。加了延時就行了。延時時間並不精確,隨便寫的。
/***************************************/

void Write_IIC_Byte(uint8_t IIC_Byte)//I2C_WriteByte(uint8_t addr,uint8_t data)
{
uint8_t i;

for(i=0;i<8;i++)
{
if(IIC_Byte&0x80)
  GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
else
  GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
delay(2);
GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
delay(2);
GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));

IIC_Byte<<=1;
}
delay(5);
GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
delay(2);
GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
delay(2);
GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
delay(2);


}

 

/***************************************/
//I2C_WriteByte函數

//做者:執念執戰/***************************************/void I2C_WriteByte(uint8_t addr,uint8_t data){ IIC_start(); Write_IIC_Byte(0x78); Write_IIC_Byte(addr); //write data Write_IIC_Byte(data); IIC_stop();}

相關文章
相關標籤/搜索