极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19716|回复: 10

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

[复制链接]
发表于 2014-5-15 14:24:59 | 显示全部楼层 |阅读模式
数字接口完全不够用呀,可以共用吗?如果能应该如何做?
回复

使用道具 举报

发表于 2014-5-15 14:46:04 | 显示全部楼层
你是需要输出复用还是输入复用?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-15 14:58:00 | 显示全部楼层
caiwenping 发表于 2014-5-15 14:46
你是需要输出复用还是输入复用?

都需要呀,可有法子呀?不胜感激
回复 支持 反对

使用道具 举报

发表于 2014-5-15 15:09:16 | 显示全部楼层
我以前用51单片机的时候,用PCF8574T这块I2C芯片扩展了8个IO口,可做输入和输出。
回复 支持 反对

使用道具 举报

发表于 2014-5-15 15:10:50 | 显示全部楼层
本帖最后由 caiwenping 于 2014-5-15 18:02 编辑

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

[pre lang="c" line="1" file="lcd1602_i2c.h"]
#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_

#define  LINE1                        0
#define  LINE2                     1
#define  LINE1_HEAD            0x80
#define  LINE2_HEAD            0xC0
#define  DATA_MODE            0x28
#define  OPEN_SCREEN        0x0C
#define  DISPLAY_ADDRESS   0x80
#define  CLEARSCREEN    LCD_en_command(0x01)

#define  MSB    0x80
#define  LSB    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
[/code]
回复 支持 反对

使用道具 举报

发表于 2014-5-15 15:15:49 | 显示全部楼层
在arduino下,用wire写i2c驱动的代码应该更容易,这样i2c可以带上八块扩展芯片,通过SDA/SCL这两个I2C端口可以扩展到8*8=64口IO
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-15 15:27:13 | 显示全部楼层
caiwenping 发表于 2014-5-15 15:15
在arduino下,用wire写i2c驱动的代码应该更容易,这样i2c可以带上八块扩展芯片,通过SDA/SCL这两个I2C端口可 ...

谢谢了,有电路图吗?
回复 支持 反对

使用道具 举报

发表于 2014-5-15 15:38:16 | 显示全部楼层
wdb_9955 发表于 2014-5-15 15:27
谢谢了,有电路图吗?

http://wenku.baidu.com/link?url=HW5UBZqAKLCfIakHQ26E0-uxyIyvfFlDUSHqOgxf5fuXZFoXhayLvsjteBu_EXmmxZJgdc0PFVz_XZDftF89EPXC4rY-5BPW6DKU_6IdBAG
回复 支持 反对

使用道具 举报

发表于 2014-5-15 18:09:35 | 显示全部楼层
模拟接口可以当数字接口用。A0-A5(14-19)。{:soso_e182:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-19 16:18:30 | 显示全部楼层
谢谢大家了
回复 支持 反对

使用道具 举报

发表于 2014-8-28 20:51:24 | 显示全部楼层
caiwenping 发表于 2014-5-15 15:10
这里贴上我用PCF8574T做i2c扩展8个IO驱动1602的51的一些代码

请问能不能附带一个i2c.h?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-7 21:05 , Processed in 0.037592 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表