完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
tca959 作为一款纯IIC控制的mcu,上电后即可通过主控IC的I2C 来控制mcu 的管脚,设置这些pin的input / output 模式,以及获取output的高低,另外也可以获取input的状态。通常主控IC 的IO 口不够用时用来扩展IO 口。
TCA9539 I2C地址的确定 查看TCA9539 的datasheet 文档,地址部分,总共有7位,其中Slave address 的bit 位固定,另外最后两个bits 位根据原理图中地址pin 的高低来判断 查看原理图发现,tca9539 的I2C地址脚IIC_SEL0,IIC_SEL1 接的是下拉电阻,两个PIN都是低电平,故地址应该取0x74. 结合原理图和datasheet 得到一个7bit 的I2C地址后,需要左移(x2), 末尾补零生成一个8bit 的地址给软件使用。计算后改地址为 0xE8. IIC地址的配置 找到对应板型的board.h 文件,配置tca9539 IIC 信息。包含在那一组IIC及设备的IIC 地址。其中TCA9539_I2C_ID 只是一个枚举值方便应用调用。 管脚功能配置 功能配置主要是配置对应pin的输入,输出模式及输出模式的高低状态 根据datasheet 的说明,寄存器0x06 , 0x07 分别配置port 0~ 7 , port 10~17对应bit位为1 则为输入 为0 则为输出。 而寄存器0x04, 0x05 分别是设置port 0 ~ 7,port 10 ~ 17 极性的。 例如:设置P3,P4,P5,P7,P10,P11 需要设置为output,其它为input模式 #define TCA9539_MASK_P0 (1 << 0) #define TCA9539_MASK_P1 (1 << 1) #define TCA9539_MASK_P2 (1 << 2) #define TCA9539_MASK_P3 (1 << 3) #define TCA9539_MASK_P4 (1 << 4) #define TCA9539_MASK_P5 (1 << 5) #define TCA9539_MASK_P6 (1 << 6) #define TCA9539_MASK_P7 (1 << 7) // P3,P4,P5,P7 set to output 0x47 static MAPI_U8 uTca9539_Ports_L_Mode = 0xFF & (~(TCA9539_MASK_P3)) & (~(TCA9539_MASK_P4)) & (~(TCA9539_MASK_P5)) & (~(TCA9539_MASK_P7)); // P10,P11 set to output 0xFC static MAPI_U8 uTca9539_Ports_H_Mode = (0xFF & (~(TCA9539_MASK_P0)) & (~(TCA9539_MASK_P1))); 定义寄存器0x06 需要初始化的值0x47 (0100 0111), 二进制从右到左 bit0~bit7 对应port0 ~ port7;寄存器 0x07,需要初始化的值0xFC (1111 1100) ,二进制从右到左bit0 ~ bit7 对应port10 ~ port17. MAPI_U8 uCfgLowPorts = 0x06; MAPI_U8 uCfgHighPorts = 0x07; iptr = mapi_i2c::GetI2C_Dev(TCA9539_I2C_ID); if(iptr == NULL) { printf("[%s][%d] Invalid I2c mcu addr .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } // config the port mode if(MAPI_FALSE == iptr->WriteBytes(1,&uCfgLowPorts,1,&uTca9539_Ports_L_Mode)) { printf("[%s][%d] wirte the port 0~7 failed.n",__FUNCTION__,__LINE__); return MAPI_FALSE; } if(MAPI_FALSE == iptr->WriteBytes(1,&uCfgHighPorts,1,&uTca9539_Ports_H_Mode)) { printf("[%s][%d] wirte the port 10~17 failed.n",__FUNCTION__,__LINE__); return MAPI_FALSE; } 这样就完成input , output 模式的配置。 读取输出管脚状态 通过datasheet得到,寄存器0x00,0x01 是用来获取port 的状态。 MAPI_U8 uLowRegAddr = 0x00; MAPI_U8 uHighRegAddr = 0x01; MAPI_U8 uOldData = 0x00; MAPI_U8 uData = 0x00; MAPI_U8 uMask = 0x00; MAPI_U8 uRRegAddr = (port > TCA9539_P7) ? uHighRegAddr : uLowRegAddr; iptr = mapi_i2c::GetI2C_Dev(TCA9539_I2C_ID); if(iptr == NULL) { printf("[%s][%d] Invalid I2c mcu addr .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } // 获取port 口该组的所有状态 if(MAPI_FALSE == iptr->ReadBytes(1, &uRRegAddr, 1, &uOldData)) { printf("[%s][%d] get the port status failed .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } // 计算返回对应port 口的状态 return (uData >> (port % 10) | 0x01); 设置输出管脚状态 通过datasheet可知,输出管脚的状态,通过寄存器0x2,0x03 来设置。 MAPI_BOOL device_mcu_tca9539::Set_port_Output(MAPI_U8 port, MAPI_BOOL bOutState) { mapi_i2c *iptr = NULL; // for output status MAPI_U8 uLowRegAddr = 0x00; MAPI_U8 uHighRegAddr = 0x01; MAPI_U8 uLowWReg = 0x02; MAPI_U8 uHighWReg = 0x03; MAPI_U8 uOldData = 0x00; MAPI_U8 uData = 0x00; MAPI_U8 uMask = 0x00; MAPI_U8 uRRegAddr = (port > TCA9539_P7) ? uHighRegAddr : uLowRegAddr; MAPI_U8 uWRegAddr = (port > TCA9539_P7) ? uHighWReg : uLowWReg; iptr = mapi_i2c::GetI2C_Dev(TCA9539_I2C_ID); if(iptr == NULL) { printf("[%s][%d] Invalid I2c mcu addr .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } // 通过寄存器0x00(port0 ~ port7)/0x01(port10 ~ port17)读取当前port口的状态 if(MAPI_FALSE == iptr->ReadBytes(1, &uRRegAddr, 1, &uOldData)) { printf("[%s][%d] get the port status failed .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } // 计算,并设置port 的新状态,其它port 状态不变 uMask = 1 << (port % 10); // set the new status if(bOutState){ uData = (uMask | uOldData); // set H } else { uData = (~uMask) & uOldData; // set L } // 对寄存器0x02(port0 ~ port7)/0x03(port10 ~ port17)写输出的高低状态 if(MAPI_FALSE == iptr->WriteBytes(1, &uWRegAddr, 1, &uData)) { printf("[%s][%d] set the new status failed .n",__FUNCTION__,__LINE__); return MAPI_FALSE; } printf("[%s][%d] set the P%02d to %d.n",__FUNCTION__,__LINE__,port,bOutState); return MAPI_TRUE; } #ifndef __DEVIDE_MCU_TCA9539_H__ #define __DEVIDE_MCU_TCA9539_H__ /*@ #include "mapi_mcu.h" #include "MsTypes.h" #include "MTypes.h" /*@ #define PORT_INPUT (1) #define PORT_OUTPUT (0) #define OUTPUT_H (1) #define OUTPUT_L (0) #define TCA9539_P0 (0) #define TCA9539_P1 (1) #define TCA9539_P2 (2) #define TCA9539_P3 (3) #define TCA9539_P4 (4) #define TCA9539_P5 (5) #define TCA9539_P6 (6) #define TCA9539_P7 (7) #define TCA9539_P10 (10) #define TCA9539_P11 (11) #define TCA9539_P12 (12) #define TCA9539_P13 (13) #define TCA9539_P14 (14) #define TCA9539_P15 (16) #define TCA9539_P16 (15) #define TCA9539_P17 (17) #define TCA9539_MASK_P0 (1 << 0) #define TCA9539_MASK_P1 (1 << 1) #define TCA9539_MASK_P2 (1 << 2) #define TCA9539_MASK_P3 (1 << 3) #define TCA9539_MASK_P4 (1 << 4) #define TCA9539_MASK_P5 (1 << 5) #define TCA9539_MASK_P6 (1 << 6) #define TCA9539_MASK_P7 (1 << 7) class device_mcu_tca9539 : public mapi_mcu { public: DLL_PUBLIC device_mcu_tca9539(void); DLL_PUBLIC ~device_mcu_tca9539(void); DLL_PUBLIC MAPI_BOOL Init(void); DLL_PUBLIC MAPI_BOOL Finalize(void); DLL_PUBLIC MAPI_BOOL Reset(void); DLL_PUBLIC MAPI_BOOL Set_port_mode(MAPI_U8 port, MAPI_BOOL bInput); DLL_PUBLIC MAPI_BOOL Get_port_mode(MAPI_U8 port, MAPI_U8 *uMode); DLL_PUBLIC MAPI_BOOL Set_port_Output(MAPI_U8 port, MAPI_BOOL bOutState); DLL_PUBLIC MAPI_BOOL Get_port_State(MAPI_U8 port, MAPI_BOOL *bMode, MAPI_BOOL *bState); DLL_PUBLIC MAPI_BOOL Tca9539Setup(void); }; #endif // __DEVIDE_LED_DEFAULT_H__ |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 23:42 , Processed in 1.087530 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号