#include #include #include #include #include #include #include #include #include #define I2C_SDA 43 // GPIO1_B3 #define I2C_SCL 44 // GPIO1_B4 #define I2C_INT 52 typedef unsigned char UINT8; typedef unsigned short UINT16; #define STATUS_SUCCESS 0 #define STATUS_FAILURE -1 #define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码 #define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘 #define CH455_I2C_ADDR 0x40 // CH455的地址 #define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码 #define CH455_BIT_ENABLE 0x01 // #define CH455_BIT_ENABLE 0x03 // 开启/关闭位 #define CH455_BIT_SLEEP 0x04 // 睡眠控制位 #define CH455_SYSON (CH455_SYSOFF | CH455_BIT_ENABLE) #define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠 #define CH455_SLEEPON (CH455_SYSOFF | CH455_BIT_SLEEP) // 开启睡眠 static unsigned char TxBuf[24] = {0}; static unsigned char RxBuf[24] = {0}; void CH455_I2c_Stop(void); void CH455_I2C_WrByte(unsigned char IIC_Byte); void delay_us(int i) { int j, k; for (j = 0; j < i; j++) for (k = 0; k < 10; k++) ; } void initGpio(int addr) { // printf("开始创建GPIO%d节点\n", addr); FILE *fp = fopen("/sys/class/gpio/export", "w"); if (fp == NULL) perror("export open filed"); else fprintf(fp, "%d", addr); fclose(fp); // printf("结束创建GPIO%d节点\n", addr); } // 设置为gpio方向 void setGpioDirection(int addr, char *direction) { // printf("设置第GPIO%d为out模式\n",addr); char path[100] = {0}; sprintf(path, "/sys/class/gpio/gpio%d/direction", addr); FILE *fp = fopen(path, "w"); if (fp == NULL) perror("direction open filed"); else fprintf(fp, "%s", direction); fclose(fp); // printf("结束设置第GPIO%d为out模式\n",addr); } // 设置gpio的电平 void set_gpioValue(int addr, int value) { // printf("设置GPIO%d为%d\n", addr, value); char path[64]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr); FILE *fp = fopen(path, "w"); if (fp == NULL) perror("direction open filed"); else fprintf(fp, "%d", value); fclose(fp); // printf("结束设置GPIO%d位置为%d\n", addr, value); } void IOWR_OUT(int addr, int val) { initGpio(addr); setGpioDirection(addr, "out"); set_gpioValue(addr, val); } void IOWR_IN(int addr, int val) { initGpio(addr); setGpioDirection(addr, "in"); set_gpioValue(addr, val); } // 读gpio节点状态 int IORD(int addr) { char path[64]; char value_str[3]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr); // printf("/sys/class/gpio/gpio%d/value", addr); FILE *fp = fopen(path, "r"); // fd = open(path, O_RDONLY); if (fp == NULL) { printf("Failed to open gpio value for reading!"); return -1; } if (fread(value_str, sizeof(char), 3, fp) < 0) { perror("Failed to read value!"); return -1; } fclose(fp); // printf("读取GPIO状态结束\n"); return (atoi(value_str)); } // 开始位 void CH455_I2c_Start(void) { IOWR_OUT(I2C_SDA, 1); delay_us(5); IOWR_OUT(I2C_SCL, 1); delay_us(5); IOWR_OUT(I2C_SDA, 0); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); } // 结束位 void CH455_I2c_Stop(void) { IOWR_OUT(I2C_SCL, 0); delay_us(5); IOWR_OUT(I2C_SDA, 0); delay_us(5); IOWR_OUT(I2C_SCL, 1); delay_us(5); IOWR_OUT(I2C_SDA, 1); delay_us(5); } // 主控端写入一个字节到从机 void CH455_I2C_WrByte(unsigned char IIC_Byte) { unsigned char i; for (i = 0; i < 8; i++) { // IOWR(I2C_SCL, 0); //钳住I2C总线,准备发送数据 if (IIC_Byte & 0x80) IOWR_OUT(I2C_SDA, 1); else IOWR_OUT(I2C_SDA, 0); delay_us(5); IOWR_OUT(I2C_SCL, 1); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); IIC_Byte <<= 1; } delay_us(5); IOWR_OUT(I2C_SDA, 1); delay_us(5); IOWR_OUT(I2C_SCL, 1); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); } // 主控端对从机读取一个字节 static unsigned char CH455_I2C_RdByte(void) // 读取一个字节数据 { unsigned char i = 0; unsigned char bytedata = 0; delay_us(5); // 将数据设置为输入模式 IOWR_IN(I2C_SDA, 1); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); for (i = 0; i < 8; i++) { IOWR_OUT(I2C_SCL, 1); delay_us(5); bytedata <<= 1; delay_us(5); bytedata = bytedata | (IORD(I2C_SDA)); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); } IOWR_OUT(I2C_SDA, 1); // 数据线设置回输出模式 delay_us(5); IOWR_OUT(I2C_SCL, 1); delay_us(5); IOWR_OUT(I2C_SCL, 0); delay_us(5); return (bytedata); // 返回数据 } // 写命令 static unsigned char CH455_Write(UINT16 cmd) { printf("CH455_Write start...\n"); CH455_I2c_Start(); // 启动总线 printf("CH455_Write first byte= %02x\n", ((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR); printf("CH455_Write second byte= %02x\n", (UINT8)cmd); CH455_I2C_WrByte(((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR); CH455_I2C_WrByte((UINT8)cmd); // 发送数据 CH455_I2c_Stop(); // 结束总线 printf("CH455_Write end...\n"); printf("\n"); return 1; } static unsigned char CH455_Read(void) // 读取按键值 { printf("CH455_Read start...\n"); UINT8 keycode; CH455_I2c_Start(); // 启动总线 printf("write byte= %02x\n", (UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR); CH455_I2C_WrByte((UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR); keycode = CH455_I2C_RdByte(); // 读取数据 printf("read byte= %02x\n", keycode); CH455_I2c_Stop(); // 结束总线 printf("CH455_Read end...\n"); printf("\n"); return keycode; } void key_Inter(void) { int ret; int val = 0; char buf[8]; int num; UINT16 key_value; pollfd pfd; pfd.fd = -1; pfd.fd = open("/sys/class/gpio/gpio52/value", O_RDONLY); if (pfd.fd > 0) printf("huagao::open sucess,fd = %d\n", pfd.fd); else printf("huagao::open failed,fd = %d\n", pfd.fd); pfd.events = POLLPRI; num = read(pfd.fd, buf, 8); // This is to clear the avaible read for (int i = 0; i < 8; i++) printf("huagao::buf[%d] = %d\n", i, buf[i]); ret = CH455_Write(CH455_SYSON); printf("CH455_SYSON = %02x\n", (CH455_SYSON)); printf("CH455_Read() = %02x\n", CH455_Read()); key_value = 0xff; while (1) { ret = poll(&pfd, 1, 1000); if (ret > 0) { printf("--------------------------------------------\n"); printf("huagao::poll get date.\n"); printf("huagao::poll ret = %d\n", ret); /* POLLIN: 有普通数据或者优先数据可读 POLLRDNORM: 有普通数据可读 POLLRDBAND: 有优先数据可读 POLLPRI: 有紧急数据可读 POLLOUT: 有普通数据可写 POLLWRNORM: 有普通数据可写 POLLWRBAND: 有紧急数据可写 POLLERR: 有错误发生 POLLHUP: 有描述符挂起事件发生 POLLNVAL: 描述符非法 */ if (pfd.revents & POLLPRI) { lseek(pfd.fd, 0, SEEK_SET); num = read(pfd.fd, buf, 8); buf[num - 1] = '\0'; ret = atoi(buf); for (int i = 0; i < 8; i++) printf("huagao::buf[%d] = %d\n", i, buf[i]); printf("huagao::atoi(buf) ret = %d\n", ret); } key_value = CH455_Read(); printf("CH455_Read() = %02x\n", key_value); printf("--------------------------------------------\n"); printf("\n"); } else if (ret == 0) { printf("--------------------------------------------\n"); printf("huagao::ret = %d\n", ret); printf("huagao::poll time out.\n"); printf("--------------------------------------------\n"); printf("\n"); } else { printf("--------------------------------------------\n"); printf("huagao::ret = %d\n", ret); printf("huagao::poll err.\n"); printf("--------------------------------------------\n"); printf("\n"); } } } int main(void) { system("echo 52 > /sys/class/gpio/export"); system("echo in > /sys/class/gpio/gpio52/direction"); system("echo falling > /sys/class/gpio/gpio52/edge"); key_Inter(); return 0; }