wdb_9955 发表于 2014-5-15 14:24:59

数字接口不够怎么办,可以共用一个接口吗?

数字接口完全不够用呀,可以共用吗?如果能应该如何做?

caiwenping 发表于 2014-5-15 14:46:04

你是需要输出复用还是输入复用?

wdb_9955 发表于 2014-5-15 14:58:00

caiwenping 发表于 2014-5-15 14:46 static/image/common/back.gif
你是需要输出复用还是输入复用?

都需要呀,可有法子呀?不胜感激

caiwenping 发表于 2014-5-15 15:09:16

我以前用51单片机的时候,用PCF8574T这块I2C芯片扩展了8个IO口,可做输入和输出。

caiwenping 发表于 2014-5-15 15:10:50

本帖最后由 caiwenping 于 2014-5-15 18:02 编辑

这里贴上我用PCF8574T做i2c扩展8个IO驱动1602的51的一些代码


#ifndef __STC12C5A_H_
#include "STC12c5a.h"
#endif

#ifndef __I2C_H_
#include "i2c.h"
#endif

#ifndef __INTRINS_H_
#include <intrins.h>
#endif

#ifndef __LCD1602I2C_H_
#define __LCD1602I2C_H_

#defineLINE1                        0
#defineLINE2                   1
#defineLINE1_HEAD            0x80
#defineLINE2_HEAD            0xC0
#defineDATA_MODE            0x28
#defineOPEN_SCREEN        0x0C
#defineDISPLAY_ADDRESS   0x80
#defineCLEARSCREEN    LCD_en_command(0x01)

#defineMSB    0x80
#defineLSB    0x01

unsigned char LCD1602_RS=0x01;
unsigned char LCD1602_RW=0x01<<1;
unsigned char LCD1602_EN=0x01<<2;
unsigned char LCDIO;

unsigned char code PCF8574_ADD=0x4e;

bit LCD_send(unsigned dat);
unsigned char LCD_recv(void);
void LCD_en_command(unsigned char command);//write command function
void LCD_en_dat(unsigned char temp);//write data function
void LCD_set_xy(unsigned char x,unsigned char y );//set display address function
void LCD_init(void);//lcd initize function
void LCD_write_char(unsigned char x,unsigned char y,unsigned char dat);//write lcd a character function
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s);//write lcd string function
void LCD_custom(unsigned char add,unsigned char *string);
void LCD_switch(bit onoff);

bit busy(void);//读忙函数

void delay_us(unsigned char us);                //@11.0592MHz
void delay_ms(unsigned char ms);       


void LCD_switch(bit onoff)
{
        if(onoff==1)
        {
                LCDIO=LCDIO|0x08;
        }
        else
        {
                LCDIO=LCDIO&0xf7;
        }
        LCD_send(LCDIO);
}

bit LCD_send(unsigned dat)
{
        bit busy;
       
        i2c_start();
        i2c_send(PCF8574_ADD|0x00);
        busy|=i2c_recv_ack();
        i2c_send(dat);
        busy|=i2c_recv_ack();
        i2c_stop();
       
        return busy;
}

unsigned char LCD_recv()
{       
        unsigned char dat;
       
        i2c_start();
        i2c_send(PCF8574_ADD|0x01);
        i2c_recv_ack();
        dat=i2c_recv();
        i2c_send_noack();
        i2c_stop();
        return dat;
}

bit busy(void)
{
        unsigned char busy;
        LCDIO&=0x08;
        LCDIO&=~(LCD1602_EN|LCD1602_RW);
        LCDIO|=LCD1602_RW|0x80;
       
        i2c_start();
        i2c_send(PCF8574_ADD|0x00);
        i2c_recv_ack();
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        LCDIO|=LCD1602_EN;
        i2c_send(LCDIO);
        i2c_recv_ack();
        i2c_stop();
       
        busy=LCD_recv()&0x80;
       
        LCDIO&=~LCD1602_EN;
        i2c_start();
        i2c_send(PCF8574_ADD|0x00);
        i2c_recv_ack();
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        LCDIO|=LCD1602_EN;
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        LCDIO&=~LCD1602_EN;
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        LCDIO&=~LCD1602_RW;
        i2c_send(LCDIO);
        i2c_recv_ack();
        i2c_stop();

        return (bit)busy;
}

void LCD_en_command(unsigned char command)
{
        unsigned char delay=1;
        while(busy());
       
        LCDIO&=0x08;
        i2c_start();
        i2c_send(PCF8574_ADD|0x00);
        i2c_recv_ack();       
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        {
                LCDIO|=LCD1602_EN;
               i2c_send(LCDIO);
                i2c_recv_ack();

                LCDIO&=0x0f;
                LCDIO|=command&0xf0;
                i2c_send(LCDIO);
                i2c_recv_ack();
                delay_us(delay);
               
                LCDIO&=~LCD1602_EN;
                i2c_send(LCDIO);
                i2c_recv_ack();

                command<<=4;
               
                LCDIO|=LCD1602_EN;
               i2c_send(LCDIO);
                i2c_recv_ack();

                LCDIO&=0x0f;
                LCDIO|=command&0xf0;
                i2c_send(LCDIO);
                i2c_recv_ack();
                delay_us(delay);
               
                LCDIO&=~LCD1602_EN;
                i2c_send(LCDIO);
                i2c_recv_ack();
        }
        i2c_stop();
}                                       

void LCD_en_dat(unsigned char command)
{
        unsigned char delay=1;
        while(busy());

        LCDIO&=0x08;
        LCDIO|=0x01;
       
        i2c_start();
        i2c_send(PCF8574_ADD|0x00);
        i2c_recv_ack();       
        i2c_send(LCDIO);
        i2c_recv_ack();
       
        {
                LCDIO|=LCD1602_EN;
               i2c_send(LCDIO);
                i2c_recv_ack();

                LCDIO&=0x0f;
                LCDIO|=command&0xf0;
                i2c_send(LCDIO);
                i2c_recv_ack();
                delay_us(delay);
               
                LCDIO&=~LCD1602_EN;
                i2c_send(LCDIO);
                i2c_recv_ack();

                command<<=4;
               
                LCDIO|=LCD1602_EN;
               i2c_send(LCDIO);
                i2c_recv_ack();

                LCDIO&=0x0f;
                LCDIO|=command&0xf0;
                i2c_send(LCDIO);
                i2c_recv_ack();
                delay_us(delay);
               
                LCDIO&=~LCD1602_EN;
                i2c_send(LCDIO);
                i2c_recv_ack();
        }
        i2c_stop();
}

void LCD_set_xy(unsigned char x,unsigned char y)
{
        unsigned char address;
        if(y==LINE1)
                address=LINE1_HEAD+x;
        else
           address=LINE2_HEAD+x;
        LCD_en_command(address);
}

void LCD_write_char(unsigned char x,unsigned char y,unsigned char dat)
{
        LCD_set_xy(x,y);
        LCD_en_dat(dat);
}

void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s)
{
    LCD_set_xy(x,y); //set address
    while(*s)// write character
    {       
                LCD_en_dat(*s);
                s++;
    }
}

void LCD_custom(unsigned char add,unsigned char *string)
{
        unsigned char i;
        unsigned char base_add=0x40;
        base_add+=(add*8);
        for(i=0;i<8;i++)
        {
                LCD_en_command(base_add+i);
                LCD_en_dat(*string);
                string++;
        }
}

void LCD_init(void)
{       
        delay_ms(50);
        LCD_send(0x30);
        LCD_send(0x34);
        LCD_send(0x30);
        delay_ms(5);
       
        LCD_send(0x30);
        LCD_send(0x34);
        LCD_send(0x30);
        delay_us(160);

        LCD_send(0x30);
        LCD_send(0x34);
        LCD_send(0x30);

        LCD_send(0x20);
        LCD_send(0x24);
        LCD_send(0x20);       
       
        LCD_en_command(0x28);

        LCD_en_command(0x01);
        LCD_en_command(0x06);
       
        LCD_en_command(OPEN_SCREEN);//open display (enable lcd display)
        LCD_en_command(DISPLAY_ADDRESS);//set lcd first display address

        LCDIO=0x08;
}

void delay_ms(unsigned char ms)                //@11.0592MHz
{
        unsigned char i, j;

        while(ms--)
                {   
                        _nop_();
                        i = 11;
                        j = 190;
                        do
                                {
                                        while (--j);
                                }
                       while (--i);
                }
}

void delay_us(unsigned char us)                //@11.0592MHz
{
        while(us--)
                {
                        _nop_();
                }
}

#endif

caiwenping 发表于 2014-5-15 15:15:49

在arduino下,用wire写i2c驱动的代码应该更容易,这样i2c可以带上八块扩展芯片,通过SDA/SCL这两个I2C端口可以扩展到8*8=64口IO

wdb_9955 发表于 2014-5-15 15:27:13

caiwenping 发表于 2014-5-15 15:15 static/image/common/back.gif
在arduino下,用wire写i2c驱动的代码应该更容易,这样i2c可以带上八块扩展芯片,通过SDA/SCL这两个I2C端口可 ...

谢谢了,有电路图吗?

caiwenping 发表于 2014-5-15 15:38:16

wdb_9955 发表于 2014-5-15 15:27 static/image/common/back.gif
谢谢了,有电路图吗?

http://wenku.baidu.com/link?url=HW5UBZqAKLCfIakHQ26E0-uxyIyvfFlDUSHqOgxf5fuXZFoXhayLvsjteBu_EXmmxZJgdc0PFVz_XZDftF89EPXC4rY-5BPW6DKU_6IdBAG

bh4rum 发表于 2014-5-15 18:09:35

模拟接口可以当数字接口用。A0-A5(14-19)。{:soso_e182:}

wdb_9955 发表于 2014-5-19 16:18:30

谢谢大家了

echiz 发表于 2014-8-28 20:51:24

caiwenping 发表于 2014-5-15 15:10 static/image/common/back.gif
这里贴上我用PCF8574T做i2c扩展8个IO驱动1602的51的一些代码




请问能不能附带一个i2c.h?
页: [1]
查看完整版本: 数字接口不够怎么办,可以共用一个接口吗?