2020年9月

热点默认频率范围

define VHF1_MIN 136000000

define VHF1_MAX 174000000

define VHF2_MIN 219000000

define VHF2_MAX 225000000

define UHF1_MIN 420000000

define UHF1_MAX 475000000

define UHF2_MIN 842000000

define UHF2_MAX 950000000

I2C/MCP23017 version

// I2C/MCP23017 version, 2016-09-17

include <stdio.h>

include <stdlib.h>

include <linux/i2c-dev.h>

include <error.h>

include <sys/types.h>

include <sys/stat.h>

include <fcntl.h>

include <unistd.h>

int addr = 0x26; / 23017 chip I2C addr /
char *i2cbus= "/dev/i2c-0";

define D4 1 // 23017 GPB0

define D5 2 // 23017 GPB1

define D6 4 // 23017 GPB2

define D7 8 // 23017 GPB3

define BK_R 16 // 23017 GPB4

define BK_G 32 // 23017 GPB5

define BK_B 64 // 23017 GPB6

define RS 128 // 23017 GPB7

define EN_HI 0xFF // 23017 GPA7

define EN_LO 0x7F // 23017 GPA7

define IODIRA 0x00 // 23017 bit directions for GPIO-A

define IODIRB 0x01 // 23017 bit directions for GPIO-A

define OLATA 0x14 // 23017 output latch: GPIO-A

define OLATB 0x15 // 23017 output latch: GPIO-B

// commands

define LCD_CLEARDISPLAY 0x01

define LCD_RETURNHOME 0x02

define LCD_ENTRYMODESET 0x04

define LCD_DISPLAYCONTROL 0x08

define LCD_CURSORSHIFT 0x10

define LCD_FUNCTIONSET 0x20

define LCD_SETCGRAMADDR 0x40

define LCD_SETDDRAMADDR 0x80

// flags for display entry mode ( | LCD_ENTRYMODESET = 0x04 );

define LCD_ENTRYRIGHT 0x00

define LCD_ENTRYLEFT 0x02

define LCD_ENTRYSHIFTINCREMENT 0x01

define LCD_ENTRYSHIFTDECREMENT 0x00

// flags for display on/off control ( | DISPLAYCONTROL = 0x08 )

define LCD_DISPLAYON 0x04

define LCD_DISPLAYOFF 0x00

define LCD_CURSORON 0x02

define LCD_CURSOROFF 0x00

define LCD_BLINKON 0x01

define LCD_BLINKOFF 0x00

// flags for display/cursor shift ( | LCD_CURSORSHIFT = 0x10 )

define LCD_DISPLAYMOVE 0x08

define LCD_CURSORMOVE 0x00

define LCD_MOVERIGHT 0x04

define LCD_MOVELEFT 0x00

// flags for function set ( | LCD_FUNCTIONSET = 0x20 )

define LCD_8BITMODE 0x10

define LCD_4BITMODE 0x00

define LCD_2LINE 0x08

define LCD_1LINE 0x00

define LCD_5x10DOTS 0x04

define LCD_5x8DOTS 0x00

int i2c_fd, gpb, bklt=0;
unsigned char displaycontrol=0, displayfunction=0, displaymode=0;

wr_reg(unsigned char reg, unsigned char val) {
unsigned char buf[4];

buf[0]=reg;
buf[1]=val;
if ((write(i2c_fd, buf, 2)) != 2) {
fprintf(stderr,"Error writing 0x%x to reg 0x%x @ addr 0x%x on %sn",val,reg,addr,i2cbus);
exit(1);
}
}

pulse_en () {

    wr_reg(OLATA,EN_HI);
    usleep(2);
    wr_reg(OLATA,EN_LO);
    usleep(1);
    wr_reg(OLATA,EN_HI);
    usleep(2);

}

write1nibble(unsigned char nib) {

    wr_reg(OLATB,(bklt | (nib & 0xF)) );  // RS=high-bit => 0

    usleep(20);

    pulse_en();

    usleep(40);

}

writenibbles(unsigned char value, char mode) {

    unsigned char nib;

    //fprintf(stderr,"sending %X / %d]\n",value, mode);

    /* high nibble first */
    nib = (value >> 4);
    wr_reg(OLATB,(bklt | (nib & 0xF) | (mode ? 0x80 : 0x00)) );

    usleep(20);

    pulse_en();

    usleep(20);

    nib = (value & 0x0f);
    wr_reg(OLATB,(bklt | (nib & 0xF) | (mode ? 0x80 : 0x00)) );

    usleep(20);

    pulse_en();

    usleep(100);

}

message (char *msg) {
int j;

for (j=0; (msg[j]!=0); j++) {
if ((msg[j] == 'n' || msg[j] == 'r'))

    writenibbles(0xC0,0);  /* next line */

else writenibbles(msg[j],1);
}
}

main(int argc, char **argv) {

int i,s;

if (argc < 2) {

   fprintf(stderr,"usage: %s <bkcolor>\n",argv[0]);
   fprintf(stderr,"usage: %s <bkcolor> \"message\"\n",argv[0]);
   fprintf(stderr," -OR-  %s <bkcolor> <charnum1> <param2>...\n",argv[0]);
   exit(1);

}

bklt=((7 ^ atoi(argv[1])) << 4);

if ((i2c_fd = open(i2cbus, O_RDWR)) < 0) {

   fprintf(stderr,"Failed to open i2c port %s\n",i2cbus);
   exit(1);

}
if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {

   fprintf(stderr,"Unable to get bus access to talk to addr %x on %s\n",addr,i2cbus);
   exit(1);

}

wr_reg (IODIRA,0x7F); // 0xFF & ~EN;
wr_reg (IODIRB,0x00); // all GPIO-B pins to output

if (argc == 2) {
wr_reg(OLATB,bklt);
exit(0);
}

/ init: enter & exit 8-bit mode to reset possible nibble misalignment... /
write1nibble(0x3);
usleep(5000);
write1nibble(0x3);
usleep(5000);
write1nibble(0x3);
usleep(1000);
write1nibble(0x2);
usleep(1000);

writenibbles(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS,0);
usleep(50);
writenibbles(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF,0); // 0x0C
usleep(50);
writenibbles(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT,0); // 0x06
usleep(50);

writenibbles(LCD_CLEARDISPLAY,0);
usleep(3200);

if (argc > 3) {
s=atoi(argv[2]);
for (i=s;i<(s+16);i++) writenibbles(i,1);
writenibbles(0xC0,0);
for (i=(s+16);i<(s+32);i++) writenibbles(i,1);
}
else
message (argv[2]);
close(i2c_fd);

return 0;
}

Linux i2c C-language example INA219 power monitoring chips

include <stdio.h>

include <stdlib.h>

include <linux/i2c-dev.h>

include <fcntl.h>

include <string.h>

include <sys/ioctl.h>

include <sys/types.h>

include <sys/stat.h>

include <unistd.h>

int fd;
int addr1 = 0x44;
int addr2 = 0x45;
char *i2cbus= "/dev/i2c-0";

unsigned char buf[32]; // Buffer for i2c data being read/written

int read_register(int addr, unsigned char reg, unsigned char mask, unsigned char sh)
{

    short value;

    if ((fd = open(i2cbus, O_RDWR)) < 0) {
            fprintf(stderr,"Failed to open i2c port\n");
            exit(1);
    }
   
    if (ioctl(fd, I2C_SLAVE, addr) < 0) {
            fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
            exit(1);
    }

    buf[0] = reg;

    if ((write(fd, buf, 1)) != 1) {
            fprintf(stderr,"Error sending register address %d to %X\n",reg,addr);
            exit(1);
    }

    if (read(fd, buf, 2) != 2) {
            fprintf(stderr,"Unable to read from register %d on %X\n",reg,addr);
            exit(1);
    }

    close(fd);

    if (mask != 0 ) buf[1] &= mask;

    value = ( (buf[0] << 8) | buf[1]);

    if (sh != 0 ) return (int)(value << sh);
      else return (int)(value);

}

int read_register_trig(int addr, unsigned char reg, unsigned char mask, unsigned char sh)
{

    short value;

    if ((fd = open(i2cbus, O_RDWR)) < 0) {
            fprintf(stderr,"Failed to open i2c port\n");
            exit(1);
    }
   
    if (ioctl(fd, I2C_SLAVE, addr) < 0) {
            fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
            exit(1);
    }

    // trigger conversion:
    buf[0] = 0;           // config reg
    buf[1] = 0b00001111;  // upper 8 bits
    buf[2] = 0b11111111;  // lower 8 bits

    if ((write(fd, buf, 3)) != 3) {
            fprintf(stderr,"Error writing to config register\n");
            exit(1);
    }

    usleep(68000);

    buf[0] = reg;

    if ((write(fd, buf, 1)) != 1) {
            fprintf(stderr,"Error sending register address %d to %X\n",reg,addr);
            exit(1);
    }

    if (read(fd, buf, 2) != 2) {
            fprintf(stderr,"Unable to read from register %d on %X\n",reg,addr);
            exit(1);
    }

    close(fd);

    if (mask != 0 ) buf[1] &= mask;

    value = ( (buf[0] << 8) | buf[1]);

    if (sh != 0 ) return (int)(value << sh);
      else return (int)(value);

}

void init_conf_cal(int addr, unsigned int Cal)
{

    if ((fd = open(i2cbus, O_RDWR)) < 0) {
            fprintf(stderr,"Failed to open i2c port\n");
            exit(1);
    }
   
    if (ioctl(fd, I2C_SLAVE, addr) < 0) {
            fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
            exit(1);
    }
   
    // set config register

    // bit 15: (0) RESET
    // bit 14: (0) n/c
    // bit 13: (0) 0=16V range, 1=32V
    // bit 12/11: (01) PG1/PG0: Shunt voltage gain
    //           00 = 1, +/- 40mV fullscale
    //       ->  01 = 2, +/- 80mV fullscale  80mV/.01ohm = 8A FS
    //           10 = 4, +/-160mV fullscale
    //           11 = 8, +/-320mV fullscale
    // bits 10,9,8,7: (1111) BADC: bus ADC resolution, samples to average
    // bit 6,5,4,3:   (1111) SADC: shunt ADC resolution, samples to average
    // bits 2,1,0:    (111)  Op Mode: Shunt & Bus, continuous
    //                 011 = shunt & bus, triggered

    buf[0] = 0;           // config reg
    buf[1] = 0b00001111;  // upper 8 bits
    buf[2] = 0b11111111;  // lower 8 bits

    if ((write(fd, buf, 3)) != 3) {
            fprintf(stderr,"Error writing to config register\n");
            exit(1);
    }

    // CALIBRATION REGISTER  (REG 5)
    // =============================
    // VBUS_MAX   = 32V   (set above)
    // VSHUNT_MAX = 0.08V (gain 8)
    // RSHUNT     = 0.01 ohm

    // MaxPossible_I = VSHUNT_MAX / RSHUNT = 8.0A
    // MaxExpected_I = 8.0A, same

    // MinLSB = MaxExpected_I/32767 = .000244148
    // MaxLSB = MaxExpected_I/4096  = .001953125

    // CurrrentLSB = MinLSB for now = .00024414807580797753

    // Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
    // Cal = 16776

    // Cal = 16776;

    buf[0] = 5;        // calibration register
    buf[1] = ((Cal & 0xFF00) >> 8);
    buf[2] = (Cal & 0xFF);

    if ((write(fd, buf, 3)) != 3) {
            fprintf(stderr,"Error writing to config register\n");
            exit(1);
    }

    // Calculate Power LSB:
    // PowerLSB = 20 * CurrentLSB
    // PowerLSB = .0048829615161595506 (4.89 mW per bit)
    //
    // Compute max current & shunt voltage values before overflow
    //
    // Max_Current_Overflow = min(CurrentLSB*32767,MaxPossible_I) = 8.0 A
    //
    // Max_ShuntVoltage = Max_Current_Overflow * RSHUNT = .08V
    //  (clamp to VSHUNT_MAX if greater)
    //
    // Compute max power
    // MaxPower = Max_Current_Overflow * VBUS_MAX
    // MaxPower = 8.0A * 32V = 256.0W

    close(fd);

}

main (int argc, char **argv) {

    int r,v;

    if ( (argc == 3) && (argv[1][0]=='-') && (argv[1][1]=='i') ) {
      init_conf_cal(addr1,atoi(argv[2]));
      init_conf_cal(addr2,atoi(argv[2]));
      fprintf(stderr,"Initialization complete\n");
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='d') ) {
      r=0;
      printf("a%X r%d = %d",addr1,r,read_register_trig(addr1,r,0,0));
      putchar('\t');
      printf("a%X r%d = %d",addr2,r,read_register_trig(addr2,r,0,0));
      putchar('\n');
      for(r=1;r<=5;r++) {
            printf("a%X r%d = %d",addr1,r,read_register(addr1,r,0,0));
            putchar('\t');
            printf("a%X r%d = %d",addr2,r,read_register(addr2,r,0,0));
            putchar('\n');
      }
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='v') ) {
            printf("V_a: %5.3f\tV_b: %5.3f\n",
             (float)read_register_trig(addr2,2,0xF8,0)*1/2000,
             (float)read_register_trig(addr1,2,0xF8,0)*1/2000);
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='a') ) {
            printf("A_a: %5.3f\tA_b: %5.3f\n",
             (float)read_register_trig(addr2,1,0,2)*8/32767,
             (float)read_register_trig(addr1,1,0,2)*8/32767);
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='A') ) {
            printf("A_a: %5.3f\tA_b: %5.3f\n",
             (float)read_register_trig(addr2,4,0,2)*2/32767,
             (float)read_register_trig(addr1,4,0,2)*2/32767);
    }
    else if ( ( argc == 1 ) || \
              ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='p') ) ) {
            printf("P_a: %5.3f\tP_b: %5.3f\n",
             (float)read_register_trig(addr2,3,0,0)*20*8/32767,
             (float)read_register_trig(addr1,3,0,0)*20*8/32767);
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='w') ) {
            float v1,v2,a1,a2;
            char cf;
            v1=(float)read_register_trig(addr2,2,0xF8,0)*1/2000;
            v2=(float)read_register_trig(addr1,2,0xF8,0)*1/2000;
            a1=(float)read_register(addr2,4,0,2)*2/32767;
            a2=(float)read_register(addr1,4,0,2)*2/32767;
            if (a1 > 0 && a2 > 0) cf=(v1>v2 ? 'X' : 'x');
             else if (a1 > 0)     cf=(v1>v2 ? 'V' : 'v');
             else                 cf=(v1>v2 ? 'B' : 'b');
            printf("%4.2f%c %3.1f",
                    (v1>v2 ? v1 : v2), cf, (a1*v1 + a2*v2));
    }
    else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='W') ) {
            float v1,v2,p1,p2,a1,a2;
            v1=(float)read_register_trig(addr2,2,0xF8,0)*1/2000;
            v2=(float)read_register_trig(addr1,2,0xF8,0)*1/2000;
            a1=(float)read_register(addr2,4,0,2)*2/32767;
            a2=(float)read_register(addr1,4,0,2)*2/32767;
            p1=(float)read_register(addr2,3,0,0)*20*8/32767;
            p2=(float)read_register(addr1,3,0,0)*20*8/32767;
            printf("%4.2f%c %4.2f %4.2f [%4.2f %4.2f]",
                    (v1>v2 ? v1 : v2),
                    (v1>v2 ? 'V' : 'v'),
                    a1*v1,a2*v2,p1,p2);
    }
    else if ( (argc == 2) && (argv[1][0]>='0') && (argv[1][0]<='9') ) {
      r = atoi(argv[1]);
      if (r >= 0 && r <= 5) {
        printf("a%X r%d = %d",addr1,r,read_register_trig(addr1,r,0,0));
        putchar('\t');
        printf("a%X r%d = %d",addr2,r,read_register_trig(addr2,r,0,0));
        putchar('\n');
      }
      else {
        fprintf(stderr,"Invalid register.\n");
        exit(1);
      }
    }
    else {
      fprintf(stderr,"Usage: %s <-i | -d | -[vaApw] | reg_number, 0-5>\n",argv[0]);
      exit(1);
    }
    exit(0);

}