中移4G模块-ML302-OpenCpu开发-MCP23017输入/输出

B站:https://space.bilibili.com/309103931

中移4G模块-ML302专栏:https://blog.csdn.net/qq_33259323/category_10453372.html

中移4G模块-ML302文集:https://www.bilibili.com/read/readlist/rl328642

1.中移4G模块-ML302-OpenCpu开发-(固件编译和烧录)

https://blog.csdn.net/qq_33259323/article/details/108586847

https://www.bilibili.com/read/cv7876504

2.中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云)

https://blog.csdn.net/qq_33259323/article/details/108638945

https://www.bilibili.com/read/cv7876527

2.1中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-订阅主题)

https://blog.csdn.net/qq_33259323/article/details/108960540

https://www.bilibili.com/read/cv7879954

2.2中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-接收和发送数据)

https://blog.csdn.net/qq_33259323/article/details/108964810

https://www.bilibili.com/read/cv7886836

2.3中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-RRPC通讯)

https://blog.csdn.net/qq_33259323/article/details/108965071

https://www.bilibili.com/read/cv7888259

3.中移4G模块-ML302-OpenCpu开发-串口开发

https://blog.csdn.net/qq_33259323/article/details/108974888

https://www.bilibili.com/read/cv7888865

4.中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C

https://blog.csdn.net/qq_33259323/article/details/109020642

https://www.bilibili.com/read/cv7922942

5.中移4G模块-ML302-OpenCpu开发-MCP23017输入/输出

https://blog.csdn.net/qq_33259323/article/details/109109136

https://www.bilibili.com/read/cv7969395

7.中移4G模块-ML302-OpenCpu开发-PCF8591测量电压

https://blog.csdn.net/qq_33259323/article/details/109109266

https://www.bilibili.com/read/cv7969365

8.中移4G模块-ML302-OpenCpu开发-GPIO

https://blog.csdn.net/qq_33259323/article/details/108960947

https://www.bilibili.com/read/cv7877192

9.中移4G模块-ML302-OpenCpu开发-ADC

https://blog.csdn.net/qq_33259323/article/details/109020864

https://www.bilibili.com/read/cv7922958

10.中移4G模块-ML302-OpenCpu开发-CJSON

https://blog.csdn.net/qq_33259323/article/details/109020898

https://www.bilibili.com/read/cv7923020

11.中移4G模块-ML302-OpenCpu开发-HTTP

https://blog.csdn.net/qq_33259323/article/details/109020904

https://www.bilibili.com/read/cv7923054

中移4G模块-ML302-OpenCpu开发-MCP23017输入/输出

根据上几篇文章,我使用的是ML302 -> UART -> STC15W408 -> I2C->MCP23017 

如果不熟悉的可以看一下下面这篇文章

4.中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C

https://blog.csdn.net/qq_33259323/article/details/109020642

https://www.bilibili.com/read/cv7922942

mm_mcp23017.c

#include "cm_main.h"
#include "mm_iic.c"

//-------------------------------¶¨ÒåMCP017ÄÚ²¿¼Ä´æÆ÷µØÖ·------------------------------ 
#define MCP23017_IODIR 			0x00
#define MCP23017_IPOL 			0x02
#define MCP23017_GPINTEN 		0x04
#define MCP23017_DEFVAL 		0x06
#define MCP23017_INTCON 		0x08
#define MCP23017_IOCON 			0x0A
#define MCP23017_GPPU 			0x0C
#define MCP23017_INTF 			0x0E
#define MCP23017_INTCAP 		0x10
#define MCP23017_GPIO 			0x12
#define MCP23017_OLAT 			0x14
#define MCP23017_PORTA			0x00
#define MCP23017_PORTB			0x01
#define INPUT					0x01
#define OUTPUT					0x00
#define ENABLE					0x01
#define DISABLE					0x00
#define SET						0x01
#define RESET					0x00
#define POLARITY_REVERSE		0x01
#define POLARITY_NON_REVERSE	0x00
#define PIN0					0x01
#define PIN1					0x02
#define PIN2					0x04
#define PIN3					0x08
#define PIN4					0x10
#define PIN5					0x20
#define PIN6					0x40
#define PIN7					0x80
#define ALLPIN					0xFF
#define DIS_INTERRUPT			0x00	   
#define HIGHLEVEL_INTERRUPT		0x01	   
#define LOWLEVEL_INTERRUPT		0x02	   
#define CHANGE_INTERRUPT		0x03	   
#define INTA_INTB_CONJUNCTION	0x00	   
#define INTA_INTB_INDEPENDENT	0x01	   
#define HWA_EN					0x00	   
#define HWA_DIS					0x01	   
#define INT_OD					0x00	   
#define INT_PUSHPULL_HIGH		0x01	   
#define INT_PUSHPULL_LOW		0x02	 
#define I2C_READ      0x01    // ¡®¶Á¡¯Ö¸Áî´úÂë
#define I2C_WRITE     0x00    // ¡®Ð´¡¯Ö¸Áî´úÂë  
#define DEV_ID 0x40 				 //MCP23017 IICÉ豸ʶ±ðÂë

int MCP23017_INIT(unsigned char deviceAddr,unsigned char intab,unsigned char hwa,unsigned char o);
//设置制定地址的MCP23017的指定端口的指定引脚为输入或输出状态
int MCP23017_IO_DIR(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char dir);
//设置指定地址的MCP23017的指定端口的指定引脚是否开启上拉电阻
int MCP23017_IO_PU(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char pu);
//设置指定地址的MCP23017的指定端口的指定引脚是否对端口极性取反
int MCP23017_IO_POLARITY(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char polarity);
//设置指定地址的MCP23017的指定端口的指定引脚是否开启中断功能及中断的类型
int MCP23017_IO_INT(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char intKind);
//读取指定地址的MCP23017的指定端口的中断标志寄存器
unsigned char MCP23017_READ_INTF(unsigned char deviceAddr,unsigned char port);
//读取指定地址的MCP23017的指定端口发生中断时中断捕捉寄存器捕捉到的端口值
unsigned char MCP23017_READ_INTCAP(unsigned char deviceAddr,unsigned char port);
//读取指定地址的MCP23017的指定端口值
void MCP23017_READ_GPIO(unsigned char deviceAddr,unsigned char port);
//向指定地址的MCP23017的指定端口写值
int MCP23017_WRITE_GPIO(unsigned char deviceAddr,unsigned char port,unsigned char val);
//设置指定地址的MCP23017的指定端口的指定引脚
int MCP23017_SET_GPIO_PIN(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char s);
//读取指定地址的MCP23017的指定端口的输出锁存寄存器
unsigned char MCP23017_READ_OLAT(unsigned char deviceAddr,unsigned char port);
//写指定地址的MCP23017的指定端口的输出锁存寄存器
int MCP23017_WRITE_OLAT(unsigned char deviceAddr,unsigned char port,unsigned char val);
//从指定地址的MCP23017器件的指定寄存器读一字节数据
int I2C_Read_Byte_MCP23017(unsigned char deviceAddr, unsigned char regAddress, unsigned char* recv);
//向指定地址的MCP23017器件的指定寄存器写一字节数据
int I2C_Write_Byte_MCP23017(unsigned char deviceAddr, unsigned char regAddress, unsigned char content);


void mm_MCP23017_INIT_UART_INIT(){
	mm_uartiic_init();
}
//--------------------------------------------------------------------------------------   
//  函数名称:bit MCP23017_INIT(unsigned char deviceAddr,unsigned char ab,unsigned char hwa,unsigned char o)
//  函数功能:初始化指定地址的MCP23017器件
//	参数:deviceAddr——设备地址,有A0,A1,A2决定
//		  intab——配置INTA、INTB是否关联,取值INTA_INTB_CONJUNCTION、INTA_INTB_INDEPENDENT
//		  hwa——配置A0、A1、A2硬件地址是否使能,取值HWA_EN、HWA_DIS	
//		  o——配置INTA、INTB的输出类型,取值INT_OD、INT_PUSHPULL_HIGH、INT_PUSHPULL_LOW 
//--------------------------------------------------------------------------------------   
int MCP23017_INIT(unsigned char deviceAddr,unsigned char intab,unsigned char hwa,unsigned char o){
	unsigned char state;
	int res;
	
	//首先设置其他位的默认状态
	state = 0x2E;		//001011 10,BANK = 0,默认不关联AB(bit = 0),禁用顺序操作,使能变化率控制、使能硬件地址,开漏输出
	if(intab==INTA_INTB_CONJUNCTION){
		state |= 0x40;
	}
	if(hwa==HWA_DIS){
		state &= (~0x08);
	}
	if(o==INT_PUSHPULL_HIGH){
		state &= (~0x04);
		state |= 0x02;
	}
	if(o==INT_PUSHPULL_LOW){
		state &= (~0x04);
		state &= (~0x02);
	}

	//写回方向寄存器
	res = I2C_Write_Byte_MCP23017(deviceAddr,MCP23017_IOCON,state);
	
	return res;
}

int MCP23017_IO_DIR(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char dir){

	unsigned char portState = 0x20;
	
	//首先读取当前端口方向的配置状态
	//因为B端口的地址比A端口的寄存器的地址都是大1,所以采用+的技巧切换寄存器
	//I2C_Read_Byte_MCP23017(deviceAddr,MCP23017_IODIR+port,portState);

	if(dir==INPUT){
		portState |= pin;
	}else{
		portState &= (~pin);
	}

	//写回方向寄存器
	I2C_Write_Byte_MCP23017(deviceAddr,MCP23017_IODIR+port,portState);
	
	return 1;
}

int MCP23017_IO_PU(unsigned char deviceAddr,unsigned char port,unsigned char pin,unsigned char pu){
	unsigned char portState = 0x20;

	if(pu==ENABLE){
		portState |= pin;
	}else{
		portState &= (~pin);
	}

	// if(pu==ENABLE){
	// 	portState = 0xFF;
	// }else{
	// 	portState = 0x00;
	// }

	//写回方向寄存器
	I2C_Write_Byte_MCP23017(deviceAddr,MCP23017_GPPU+port,portState);
	
	return 1;
}

int MCP23017_WRITE_GPIO(unsigned char deviceAddr,unsigned char port,unsigned char val){	
	int res;
	
	//因为B端口的地址比A端口的寄存器的地址都是大1,所以采用+的技巧切换寄存器
	res = I2C_Write_Byte_MCP23017(deviceAddr,MCP23017_GPIO+port,val);

	return res;
}

//--------------------------------------------------------------------------------------   
//  函数名称:unsigned char MCP23017_READ_GPIO(unsigned char deviceAddr,unsigned char port)
//  函数功能:读取指定地址的MCP23017的指定端口值
//	参数:deviceAddr——设备地址,有A0,A1,A2决定
//		  port——端口名称,取值MCP23017_PORTA、MCP23017_PORTB
//	返回值:中断发生时,当时端口的值
//--------------------------------------------------------------------------------------   
void MCP23017_READ_GPIO(unsigned char deviceAddr,unsigned char port){
	I2C_Read_Byte_MCP23017(deviceAddr,MCP23017_GPIO+port,NULL);
}




int I2C_Write_Byte_MCP23017(unsigned char deviceAddr, unsigned char regAddress, unsigned char content){
	mm_send_iic_data(DEV_ID | (deviceAddr<<1) | I2C_WRITE,regAddress,content);
    return 1;
}

int I2C_Read_Byte_MCP23017(unsigned char deviceAddr, unsigned char regAddress, unsigned char* recv){
	mm_read_iic_data(DEV_ID | (deviceAddr<<1) | I2C_WRITE,regAddress);
	return 1;
}

 串口,直接在main函数里面调用mm_uart_init()

#include "cm_main.h"
#include "mm_mcp23017_new.c"

void mm_uart_init(){
    // 串口初始化
    mm_uartiic_init();
    osDelay(500);
    cm_gpio_write(19,CM_GPIO_LOW);
    osDelay(1000);
    
        // 16路输出初始化
        MCP23017_INIT(0x00,INTA_INTB_INDEPENDENT,HWA_EN,INT_OD);
        osDelay(600);
		MCP23017_IO_DIR(0x00,MCP23017_PORTA,ALLPIN,OUTPUT);
        osDelay(600);
        MCP23017_IO_DIR(0x00,MCP23017_PORTB,ALLPIN,OUTPUT);
        osDelay(600);

        // 16路输入初始化
	    MCP23017_INIT(0x01,INTA_INTB_INDEPENDENT,HWA_EN,INT_OD);
        osDelay(600);
	    MCP23017_IO_PU(0x01,MCP23017_PORTA,ALLPIN,ENABLE);
        osDelay(600);
	    MCP23017_IO_PU(0x01,MCP23017_PORTB,ALLPIN,ENABLE); 
        osDelay(600);

    while(1){
        // 16路输出测试
        //  A
        MCP23017_WRITE_GPIO(0x00,MCP23017_PORTA,0x01);
        osDelay(100);
        MCP23017_WRITE_GPIO(0x00,MCP23017_PORTA,0x00);
        osDelay(100);
        //  B
        MCP23017_WRITE_GPIO(0x00,MCP23017_PORTB,0x01);
        osDelay(100);
        MCP23017_WRITE_GPIO(0x00,MCP23017_PORTB,0x00);
        osDelay(100);

        //  16路输入测试
        MCP23017_READ_GPIO(0x01,MCP23017_PORTA);
        osDelay(100);

        MCP23017_READ_GPIO(0x01,MCP23017_PORTB);  
        osDelay(100);
    }
}

mm_iic.c 

#include "cm_main.h"
#define MM_UART CM_UART_2
unsigned char mm_I2C_UART_BUFFER[50] = {0};
int mm_I2C_UART_FLAG = 0;

/**
 *  串口转IID
 */

// 串口回调函数
static void mm_test_oc_uart_cb(void *param,unsigned int evt){

    cm_uart_receive(MM_UART,mm_I2C_UART_BUFFER,1024);

    cm_printf("%s\r\n",mm_I2C_UART_BUFFER);
    
    memset(mm_I2C_UART_BUFFER,0,50);
}

// 写数据
//10 90 43 00 0d        10 90 43 00 0d
//char dasasw[10] = {0x10,0x90,0x43,0xff,0x0D};       // PCF8591
//char dasasw[10] = {0x10,0x90,0x43,0xff,0x0D};       // MCP23017
void mm_send_iic_data(u_char driver_address,u_char data_address,u_char dat){
    char dasasw[10] = {0x10,driver_address,data_address,dat,0x0D};       
    char * send_uart_data = dasasw;
    cm_uart_send_cache(MM_UART,send_uart_data,5);
}

// 读数据
//11 90 43 0D
//char dasasw[10] = {0x11,0x90,0x43,0x0D};
void mm_read_iic_data(u_char driver_address,u_char data_address){
    char dasasw[10] = {0x11,driver_address,data_address,0x0D};       
    char * send_uart_data = dasasw;
    cm_uart_send_cache(MM_UART,send_uart_data,4);
}

void mm_uartiic_init(){
     cm_uart_cfg_t mm_uart_cfg;

    mm_uart_cfg.id = MM_UART;
    mm_uart_cfg.baud = CM_UART_BAUD_115200;
    mm_uart_cfg.databit = CM_UART_DATA_BITS_8;
    mm_uart_cfg.stopbit = CM_UART_STOP_BITS_1;
    mm_uart_cfg.parity = CM_UART_NO_PARITY;
    mm_uart_cfg.cb = mm_test_oc_uart_cb;
    mm_uart_cfg.param = "test param mm";
    mm_uart_cfg.event = CM_UART_EVENT_RX_ARRIVED;
    //mm_uart_cfg.rx_buf_size = 1*1024;
    //mm_uart_cfg.tx_buf_size = 1*1024;
    mm_uart_cfg.rx_buf_size = 0;
    mm_uart_cfg.tx_buf_size = 0;

    cm_uart_init(&mm_uart_cfg);
}

猜你喜欢

转载自blog.csdn.net/qq_33259323/article/details/109109136