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
",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);
}