串口可用之后,很多debug信息就可以通过串口打印输出了,所以我打算先把读到的温湿度数据通过串口打印出来,然后再调OLED显示,之后再将数据通过OLED屏显示,一步一步来。
首先还是在板子自带的Information sheet上找到I2C的管脚,有I2C1和I2C2,但还是由于硬件老白的原因,只能用X32接口上的I2C2了。
看了下温湿度的资料,最高耐压5.5V,先接到3.3V上试一下,按如下方式连接X32和温湿度计
接下来依然是通过MHC来使能I2C驱动
1. 打开MHC的Options选项卡,找到I2C对应的driver选项打开并做相应的配置,我的配置如下
2. 打开MHC的Pin Settings,将RF4和RF5设置为I2C2的SDA和SCL
3. 然后生成代码,主要包含以下几个源文件,我为了添加callback以及封装DHT12的驱动,又添加了bsp_i2c.c和bsp_dht12.c两个文件
4. 分析I2C驱动代码后可知在SYS_Initialize中已经根据用户的配置调用了I2C相关的初始化函数,所以使用时只需要在我们的封装层里直接调用drv_i2c_mapping.c中的其他API就可以了,我添加的bsp_i2c.c和bsp_dht12.c中的代码如下,DHT12的数据还没有做校验
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中添加读温湿度数据的处理,每秒读一次并通过串口打印出来
串口打印输出如下
串口定时地将温湿度数据打印出来,也算是一个简陋的温湿度计吧。下一步就是调试SPI和OLED屏,给我们的温湿度计做一个好看一点的输出界面,毕竟这是一个实(kao)力(lian)说(chi)话(fan)的时代。
-
PIC32MX470
+关注
关注
0文章
5浏览量
1803
发布评论请先 登录
相关推荐
评论