树莓派4B-模拟I2C读取CH452矩阵按键

wiringPi 包含了一个 I2C 库,来让您能够更轻松的使用树莓派的板上 I2C 接口。I2C常用方法如下所示:

int wiringPiI2CSetup(int devId);
该函数使用指定设备标示号来初始化 I2C 系统。参数 devId 是 I2C设备地址
回值是I2C设备的文件描述符.如果返回-1则表示获取I2C设备失败

int wiringPiI2CRead (int fd) ;直接读取数据(针对无需发送寄存器地址的I2C设备),fd是wiringPiI2CSetup函数的返回值,返回值是读到的数据

int wiringPiI2CWrite (int fd, int data) ;直接写数据(针对无需发送寄存器地址的I2C设备),fd同上,data是写入的数据

 
int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;写数据到8位寄存器,fd同上,reg寄存器地址,data要写入的数据

int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;写数据到16位寄存器,fd同上,reg寄存器地址,data要写入的数据

 
int wiringPiI2CReadReg8 (int fd, int reg) ;从寄存器读取8位数据,fd同上,reg寄存器地址,返回值读取到的数据

int wiringPiI2CReadReg16 (int fd, int reg) ;从寄存器读取16位数据,fd同上,reg寄存器地址,返回值读取到的数据

由于CH452的I2C不是标准I2C格式,所以只能用模拟实现:

 

代码如下所示:

#include<stdio.h>
#include <cstring>
#include<wiringPi.h>

typedef unsigned char u8;
typedef unsigned short u16;

#define  BTN_INTERRUPT 0 // 按钮中断
#define  PIN_SDA 8
#define  PIN_SCL 9
#define  PIN_RST 7

#define        CH452_SCL_SET        {digitalWrite(PIN_SCL, HIGH);}
#define        CH452_SCL_CLR        {digitalWrite(PIN_SCL, LOW);}

#define        CH452_SDA_SET        {digitalWrite(PIN_SDA, HIGH);}
#define        CH452_SDA_CLR        {digitalWrite(PIN_SDA, LOW);}
#define        CH452_SDA_IN         (digitalRead(PIN_SDA))
#define        CH452_SDA_D_OUT      {pinMode(PIN_SDA, OUTPUT);}
#define        CH452_SDA_D_IN       {pinMode(PIN_SDA, INPUT);}

// 2线接口CH452
#define        CH452_I2C_ADDR0        0x40            // CH452 ADDR=0
#define        CH452_I2C_ADDR1        0x60            // CH452 ADDR=1
#define        CH452_I2C_MASK        0x3E             // CH452 掩码
#define     CH452_GET_KEY       0x0700                // 读KEY命令

bool keys[80];

void CH452_I2c_Start(void)
{
    CH452_SDA_D_OUT;
    CH452_SDA_SET;
    CH452_SCL_SET;
    CH452_SDA_CLR;
    CH452_SCL_CLR;

}
void CH452_I2c_Stop(void)
{
    CH452_SDA_D_OUT;   // 设置SDA为输出方向
    CH452_SDA_CLR;
    CH452_SCL_SET;
    CH452_SDA_SET;        // 发送结束信号
    CH452_SDA_D_IN;       //设置SDA为输RU方向
}

// 读一个数据
u8  CH452_I2c_RdByte(void)
{
    u8 dat,i;
    CH452_SDA_SET;
    CH452_SDA_D_IN; // 设置SDA为输入方向
    dat=0;
    for(i=0;i!=8;i++)
    {
        CH452_SCL_SET;
        delayMicroseconds(3);
        dat<<=1;
        if(CH452_SDA_IN) dat++;  // 读出一位
        CH452_SCL_CLR;
        delayMicroseconds(1);
    }
    CH452_SDA_SET;
    delayMicroseconds(1);
    CH452_SCL_SET;  // 发送应答
    delayMicroseconds(2);
    CH452_SCL_CLR;
    delayMicroseconds(1);;
    return(dat);
}
// 写一个字节
void CH452_I2c_WrByte(u8 dat)
{
    u8 i;
    CH452_SDA_D_OUT;   // 输出
    for(i=0;i!=8;i++)
    {
        if(dat&0x80) {CH452_SDA_SET;}
        else {CH452_SDA_CLR;}
        delayMicroseconds(1);;
        CH452_SCL_SET;
        dat<<=1;
        delayMicroseconds(2);
        CH452_SCL_CLR;
        delayMicroseconds(1);;
    }
    CH452_SDA_D_IN;  /*SDA输入方向 */
    CH452_SDA_SET;
    delayMicroseconds(1);
    CH452_SCL_SET;  // 等待应答
    delayMicroseconds(2);
    CH452_SCL_CLR;
    delayMicroseconds(1);
}
void CH452_Write(unsigned short cmd)    // 写命令
{
    CH452_I2c_Start();
    CH452_I2c_WrByte((u8)(cmd>>7)&CH452_I2C_MASK|CH452_I2C_ADDR1);  // ADDR=1
    CH452_I2c_WrByte((u8)cmd);
    CH452_I2c_Stop();
}

u8 CH452_ReadKey(void)
{
    u8 keycode;
    CH452_I2c_Start();
    CH452_I2c_WrByte((u8)(CH452_GET_KEY>>7)&CH452_I2C_MASK|0x01|CH452_I2C_ADDR1);
    keycode=CH452_I2c_RdByte();
    CH452_I2c_Stop();
    return(keycode);
}
void irqHandler(void) {
    u8 key = CH452_ReadKey() - 0X40;
    keys[key] = !keys[key];
    printf("INTERRUPT key%d = %d\n",key,keys[key]);

}


int initI2c()
{
    //初始化所用到的IO引脚
    pinMode(BTN_INTERRUPT, INPUT);
    // INT_EDGE_FALLING:下降沿
    // INT_EDGE_RISING:上升沿
    // INT_EDGE_BOTH: 可上升沿也可以下降沿
    // INT_EDGE_SETUP:保持原有的GPIO初始方式
    int wiringPiI2CSetup(int devId);
    wiringPiISR(BTN_INTERRUPT, INT_EDGE_FALLING, &irqHandler);
    pinMode(PIN_SDA, OUTPUT);
    pinMode(PIN_SCL, OUTPUT);
    pinMode(PIN_RST, OUTPUT);

    digitalWrite(PIN_RST, HIGH);
    digitalWrite(PIN_RST, LOW);
    return 0;
}

int main()
{
    u8 data[10];
    u8 i=0;
    u8 beginData = 0;
    //初始化wiringPI的库函数
    if(wiringPiSetup()<0) {
        printf("init wiringPi error\n");
    }
    initI2c();          //spi的初始化
    CH452_Write(0X0403);
    while(1) {
        delay(100);
    }
    return 0;
}

效果如下所示:

 

 

posted @ 2021-07-12 19:20  诺谦  阅读(829)  评论(0)    收藏  举报