串口可用之后,很多debug信息就可以通過串口打印輸出了,所以我打算先把讀到的溫濕度數(shù)據(jù)通過串口打印出來,然后再調(diào)OLED顯示,之后再將數(shù)據(jù)通過OLED屏顯示,一步一步來。
首先還是在板子自帶的Information sheet上找到I2C的管腳,有I2C1和I2C2,但還是由于硬件老白的原因,只能用X32接口上的I2C2了。
看了下溫濕度的資料,最高耐壓5.5V,先接到3.3V上試一下,按如下方式連接X32和溫濕度計
接下來依然是通過MHC來使能I2C驅(qū)動
1. 打開MHC的Options選項卡,找到I2C對應的driver選項打開并做相應的配置,我的配置如下
2. 打開MHC的Pin Settings,將RF4和RF5設置為I2C2的SDA和SCL
3. 然后生成代碼,主要包含以下幾個源文件,我為了添加callback以及封裝DHT12的驅(qū)動,又添加了bsp_i2c.c和bsp_dht12.c兩個文件
4. 分析I2C驅(qū)動代碼后可知在SYS_Initialize中已經(jīng)根據(jù)用戶的配置調(diào)用了I2C相關的初始化函數(shù),所以使用時只需要在我們的封裝層里直接調(diào)用drv_i2c_mapping.c中的其他API就可以了,我添加的bsp_i2c.c和bsp_dht12.c中的代碼如下,DHT12的數(shù)據(jù)還沒有做校驗
bsp_i2c.c
#include “system/common/sys_common.h”
#include “system_config.h”
#include “system_definitions.h”
#include “driver/i2c/drv_i2c.h”
#include
#include
#define BSP_I2C_BUF_SIZE 0x10
typedef struct bsp_i2c_dev {
DRV_HANDLE I2CHandle;
OS_SEM SemLock; /* I2C Exclusive access sempahore */
OS_SEM SemWait; /* Transfer Complete signal */
CPU_INT08U TxBuf[BSP_I2C_BUF_SIZE]; /* The transfer data area */
CPU_INT08U RxBuf[BSP_I2C_BUF_SIZE]; /* The receive data area */
} BSP_I2C_DEV;
static BSP_I2C_DEV BSP_I2C_DevTbl[BSP_I2C_NBR_MAX];
static void BSP_I2C2_Callback (DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle, uintptr_t context);
CPU_BOOLEAN BSP_I2C_Init (CPU_INT08U i2c_id,
CPU_INT08U i2c_mode,
CPU_INT32U bit_rate)
{
OS_ERR err;
BSP_I2C_DEV *p_i2c_dev;
switch (i2c_id) {
case BSP_I2C_ID_I2C2:
p_i2c_dev = (BSP_I2C_DEV *)&BSP_I2C_DevTbl[0];
break;
default:
return (DEF_FAIL);
}
/* Setup the I2C handle */
p_i2c_dev-》I2CHandle = DRV_I2C_Open(DRV_I2C_INDEX_0, 0);
/* -------------- CREATE OS SEMAPHORES ------------- */
OSSemCreate((OS_SEM *)&(p_i2c_dev-》SemWait), “I2C Wait”, 0, &err);
OSSemCreate((OS_SEM *)&(p_i2c_dev-》SemLock), “I2C Lock”, 1, &err);
switch (i2c_id) {
case BSP_I2C_ID_I2C2:
DRV_I2C_BufferEventHandlerSet(p_i2c_dev-》I2CHandle, BSP_I2C2_Callback, NULL);
break;
default:
return (DEF_FAIL);
}
return (DEF_OK);
}
CPU_BOOLEAN BSP_I2C_WrRd (CPU_INT08U i2c_id,
CPU_INT08U i2c_addr,
CPU_INT08U *offset_buf,
CPU_INT08U offset_len,
CPU_INT08U *p_buf,
CPU_INT16U nbr_bytes)
{
OS_ERR err;
BSP_I2C_DEV *p_i2c_dev;
if ((offset_buf == (CPU_INT08U *)0) || (p_buf == (CPU_INT08U *)0)) {
return (DEF_FAIL);
}
if ((nbr_bytes 《 1) ||
((offset_len + 1) 》 BSP_I2C_BUF_SIZE) ||
((nbr_bytes + 1) 》 BSP_I2C_BUF_SIZE)) {
return (DEF_FAIL);
}
switch (i2c_id) {
case BSP_I2C_ID_I2C2:
p_i2c_dev = (BSP_I2C_DEV *)&BSP_I2C_DevTbl[0];
break;
default:
return (DEF_FAIL);
}
/* Lock the I2C peripheral */
OSSemPend(&(p_i2c_dev-》SemLock), 0, OS_OPT_PEND_BLOCKING, 0, &err);
/* Do master write transfer */
DRV_I2C_TransmitThenReceive(p_i2c_dev-》I2CHandle, i2c_addr,
offset_buf, offset_len, p_buf, nbr_bytes, NULL);
/* Wait until the transfer completes */
OSSemPend(&(p_i2c_dev-》SemWait), 1000, OS_OPT_PEND_BLOCKING, 0, &err);
OSSemPost(&(p_i2c_dev-》SemLock), OS_OPT_POST_1, &err); /* Release the I2C Peripheral */
return DEF_OK;
}
static void BSP_I2C2_Callback (DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle, uintptr_t context)
{
OS_ERR err;
BSP_I2C_DEV *p_i2c_dev;
p_i2c_dev = (BSP_I2C_DEV *)&BSP_I2C_DevTbl[0];
OSSemPost(&(p_i2c_dev-》SemWait), OS_OPT_POST_1, &err); /* Post to the sempahore */
}
bsp_dht12.c
#include “system/common/sys_common.h”
#include “system_config.h”
#include “system_definitions.h”
#include
#include
CPU_BOOLEAN BSP_DHT12_Read (CPU_INT08U *hum_high,
CPU_INT08U *hum_low,
CPU_INT08U *temp_high,
CPU_INT08U *temp_low)
{
CPU_BOOLEAN ret;
CPU_INT08U byte_addr = 0;
CPU_INT08U data_buf[4];
ret = BSP_I2C_WrRd(BSP_I2C_ID_I2C2, 0xB8, &byte_addr, 1, data_buf, 4);
if (ret) {
*hum_high = data_buf[0];
*hum_low = data_buf[1];
*temp_high = data_buf[2];
*temp_low = data_buf[3];
}
return ret;
}
5. 在_SYS_Tasks任務中添加我們自己代碼的初始化
6. 最后在APP_Tasks中添加讀溫濕度數(shù)據(jù)的處理,每秒讀一次并通過串口打印出來
串口打印輸出如下
串口定時地將溫濕度數(shù)據(jù)打印出來,也算是一個簡陋的溫濕度計吧。下一步就是調(diào)試SPI和OLED屏,給我們的溫濕度計做一個好看一點的輸出界面,畢竟這是一個實(kao)力(lian)說(chi)話(fan)的時代。
-
PIC32MX470
+關注
關注
0文章
5瀏覽量
1802
發(fā)布評論請先 登錄
相關推薦
評論