用PCF8574来扩展单片机的IO口,虽然IIC通信程序网上到处都是,但是之前也是驱动一个关于iic总线的芯片,那芯片怎么也不答应我,估计是地址的原因吧。地址这个事情总是不好把握。所以当拿到文档的时候,有点害怕这个芯片的时候有点不知所措,也害怕不答应我。还好运气比较好,后来居然立马就答应了。

1、利用Arduino,将硬件测试一下,很顺利就通了,这样就可以顺利的进行下一步了。

2、拷贝iic的通信程序

/********************延时***************/

void nop4()

{

_nop_();    //等待一个机器周期

_nop_();    //等待一个机器周期

_nop_();    //等待一个机器周期

_nop_();    //等待一个机器周期

}

//***************************************

void Start()

{

SDA=1;

_nop_();

SCL=1;

nop4();

SDA=0;

nop4();

SCL=0;

_nop_();

_nop_();

}

void Stop()

{

SDA=0;

_nop_();

SCL=0;

nop4();//>4us后SCL跳变

SCL=1;

nop4();

SDA=1;

_nop_();

_nop_();

}

//******************************************

void  Write_A_Byte(unsignedchar c)

{

unsigned char BitCnt;

for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位

{

if((c<<BitCnt)&0x80) SDA=1;   //判断发送位

else  SDA=0;

_nop_();

SCL=1;               //置时钟线为高,通知被控器开始接收数据位

nop4();

_nop_();

SCL=0;

}

_nop_();

_nop_();

SDA=1;               //8位发送完后释放数据线,准备接收应答位

_nop_();

_nop_();

SCL=1;

_nop_();

_nop_();

_nop_();

if(SDA==1)ack=0;

else

{

ack=1;       //判断是否接收到应答信号

P1=0x00;

}

SCL=0;

_nop_();

_nop_();

}

3、根据PCF8574的数据手册的描述,如果R / W位低,从主数据,输出到P端口。

也就是写了地址之后后面的RW为低电平,再写数据进去就可以输出了。

bitWrite_Random_Address_Byte(unsigned char add,unsigned char dat)

{     Start();   //启动总线

Write_A_Byte(add<<1|0); //发送器件地址

if(ack==0)return(0);

Write_A_Byte(dat);   //发送数据

if(ack==0)return(0);

Stop(); //结束总线

return(1);

}

4、根据Arduino的程序,我们会发现地址是0x27,要注意这里的0x27只是,我们还需要把它往左边移动以为1位,才算是把地址写进去了,很多IIC大家看Arduino可以运行通,但是在写地址的时候总是不会左移,所以器件就不答应,看下面的表可以看到,A0、A1、A2这里是可变的,我的板上我用万用表测过A0、A1、A2都是高电平,所以地址开始是00100111,也就是0x27,最后一位要写0,最后编程01001110,所以在发送地址的时候要Write_A_Byte(add<<1|0);,左移以为在或上0,如果是读的话就是或上1咯,A0、A1、A2也可以改变电平变成别的地址。

5、这样,只需要调用Write_Random_Address_Byte(unsigned char add,unsigned char dat)函数就可以让输出编程你想让输出的电平咯。下面就是最直接的来驱动流水灯,可以看到效果。这样就可以想怎么输出什么电平就输出什么电平了。

Write_Random_Address_Byte(0x27,0xfe);//第一个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xfd);//第二个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xfb);//第三个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xf7);//第四个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xef);//第五个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xdf);//第六个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0xbf);//第七个灯亮

delay_nms(1000);

Write_Random_Address_Byte(0x27,0x7f); //第八个灯亮

delay_nms(1000);

6、驱动LCD1602,为了2跟线达到驱动1602的目的,首先要知道其实1602,在驱动的时候不仅11跟线可以驱动,其实4+3根线也是可以驱动的。其实用2根线来驱动1602实际上也是用7根线来驱动,而我们现在用PCF8574是可以任意输出8个高低电平的,所以来控制这7个脚是足够的还可以剩余一个脚,网上也有很多相关程序,我就不再多说。要注意在写每一次用到输出电平的时候都要写一次地址,上面我们都已经包装在一起了,所以在写命令和写数据的时候直接调用这个就ok了。

//********************液晶屏使能*********************

voidEnable_LCD_write()

{

LCD_data|=(1<<(3-1));//E=1;

Write_Random_Address_Byte(0x27,LCD_data);  //

delay_nus(2);

LCD_data&=~(1<<(3-1));//E=0;

Write_Random_Address_Byte(0x27,LCD_data);

}

//*************写命令****************************

voidLCD_write_command(unsigned char command)

{

delay_nus(16);

LCD_data&=~(1<<(1-1));//RS=0;

LCD_data&=~(1<<(2-1));//RW=0;

//LCD_data&=~(1<<(4-1));

Write_Random_Address_Byte(0x27,LCD_data);

LCD_data&=0X0f; //清高四位

LCD_data|=command & 0xf0; //写高四位

Write_Random_Address_Byte(0x27,LCD_data);

Enable_LCD_write();

command=command<<4; //低四位移到高四位

LCD_data&=0x0f; //清高四位

LCD_data|=command&0xf0; //写低四位

Write_Random_Address_Byte(0x27,LCD_data);

Enable_LCD_write();

}

//*************写数据****************************

voidLCD_write_data(unsigned char value)

{

delay_nus(16);

LCD_data|=(1<<(1-1));//RS=1;

LCD_data&=~(1<<(2-1));//RW=0;

Write_Random_Address_Byte(0x27,LCD_data);

LCD_data&=0X0f; //清高四位

LCD_data|=value&0xf0; //写高四位

Write_Random_Address_Byte(0x27,LCD_data);

Enable_LCD_write();

value=value<<4; //低四位移到高四位

LCD_data&=0x0f; //清高四位

LCD_data|=value&0xf0; //写低四位

Write_Random_Address_Byte(0x27,LCD_data);

Enable_LCD_write();

}

//**********************设置显示位置*********************************

voidset_position(unsigned char x,unsigned char y)

{

unsigned char position;

if (y == 0)

position = 0x80 + x;

else

position = 0xc0 + x;

LCD_write_command(position);

}

//**********************显示字符串*****************************

voiddisplay_string(unsigned char x,unsigned char y,unsigned char *s)

{

set_position(x,y);

while (*s)

{

LCD_write_data(*s);

s++;

}

}

//*************液晶初始化****************************

voidLCD_init(void)

{

LCD_write_command(0x28);

delay_nus(40);

LCD_write_command(0x28);

delay_nus(40);

Enable_LCD_write();

delay_nus(40);

LCD_write_command(0x28); //4位显示!!!!!!!!!!!!!!!!!!

LCD_write_command(0x0c); //显示开

LCD_write_command(0x01); //清屏

delay_nms(2);

}

7、主函数,静态显示字符串,后面改的画也很方便

void main(void)

{

LCD_init();

display_string(4,0,"LiaoMi"); //显示一段文字

display_string(4,1,"2016.7.8");//显示一段文字

while(1);

}

这样就可以用2跟线驱动1602啦。

下载的地址:http://download.csdn.net/detail/liaomi520/9571569

http://download.csdn.net/detail/liaomi520/9571587

iic模块PCF8574驱动1602学习记载相关推荐

  1. arduino下载库出错_arduino的I2C通讯 3:驱动1602液晶屏

    上个推送,我们学习了I2C功能的基础知识.而且知道了使用很多器件都需要安装库.本次,我们一起来做一个实例,用arduino驱动1602液晶屏 1602代表屏幕有16列,2行.传统的驱动方式占用了大量的 ...

  2. 嵌入式驱动工程师学习路线【建议收藏】

    网上看了很多的嵌入式学习路线,有的比较片面,有的为了博人眼球东拼西凑,几乎把整个行业用得着用不着的技术都写上去了,没有侧重点,简直是劝退指南,还有的纯粹是打广告卖板子招生. 一口君曾经是某见的教学总监 ...

  3. linux驱动开发学习2 设备树

    设备树 dtb板级信息文件,大势所趋,一定要学  如何确定要编译哪个DTS文件:查看linux下的arch/arm/boot/dts/Makefile  DTS语言有属于自己的语法:以树形来描述设备信 ...

  4. MC9S12XEP100的IIC模块(IICV3)

    最近在写DS3231时钟芯片的驱动,这个芯片使用IIC进行通讯,以前没有用过IIC模块,照着教材和示例程序写程序后发现各种问题.没办法,还是官方数据手册靠谱,遂把相应部分又翻译了一遍.果然发现示例程序 ...

  5. Windows驱动开发学习笔记(三)—— 内核空间内核模块

    Windows驱动开发学习笔记(三)-- 内核空间&内核模块 内核空间 实验 第一步:编译如下代码 第二步:将 .sys 文件拷贝到虚拟机中 第三步:部署 .sys 文件并运行 第四步:创建一 ...

  6. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

    Windows驱动开发学习笔记(二)-- 驱动调试&内核编程基础 基础知识 驱动调试 PDB(Program Debug Database) WinDbg 加载 PDB 实验:调试 .sys ...

  7. Android深度探索(卷1)HAL与驱动开发学习笔记(8)

    Android深度探索(卷1)HAL与驱动开发学习笔记(8) 第八章 蜂鸣器驱动   L i n u x驱动的代码重用有很多种方法.可以采用标准C程序的方式.将要重用的代码放在其他的文件(在头文件中声 ...

  8. 04 基本模块的驱动

    基本模块的驱动 1 基于J-Link的调试信息输出 J-Link RTT 简介 通过RTT可以从目标微控制器输出信息以非常高的速度向应用程序发送输入而不影响目标微控制器的实时性. SEGGER RTT ...

  9. 基于FPGA的iic主从机驱动实现 Verilog实现iic slave和iic master

    基于FPGA的iic主从机驱动实现 Verilog实现iic slave和iic master 顶层模块实现master对slave自定义的寄存器读取 带仿真模块 ID:153069768739840 ...

最新文章

  1. python argparse模块_Python argparse模块应用实例解析
  2. 利用反射动态调用类成员C#
  3. drbd配置文件_Linux数据安全工具:数据镜像软件DRBD的安装与配置
  4. linux下ssh登录PIX防火墙
  5. DBA(七):PXC、MySQL存储引擎
  6. oracle的cv函数,cv_wait 和 cv_timedwait 函数
  7. JVM学习笔记(一)------基本结构
  8. 21秋期末考试财务会计(一)10166k2
  9. 二、Get和Post的区别
  10. eset nod32 v11无限试用补丁
  11. 微信公众号开发之消息模板
  12. LBS与空间索引原理
  13. Python基础——模块和正则表达式
  14. 制作SD卡系统镜像img文件
  15. 根据前序和中序推出后序
  16. LVM挂盘(centos7 使用parted命令分区挂盘操作详细)
  17. 基于s3c2440的12864液晶驱动
  18. 阿米洛 varlimo 机械键盘 cmd (win) 键锁定
  19. 作为后起之秀的远程控制软件·ToDesk,你安排了没?
  20. 诺顿杀毒软件64位_如何禁用诺顿的通知和捆绑软件

热门文章

  1. MySQL安装配置教程-win10
  2. 关于外部FLASH芯片的初步使用—以M25P80为例
  3. type 和 interface的区别
  4. 自定义开源 Piwigo 相册——分享生活、记录漫漫人生路中的美好时光和感动
  5. VC++ 判断文件是否存在
  6. 了解软件测试职业以及发展定位
  7. 航班系统C语言程序流程图,飞机订票系统(C语言代码及流程图)
  8. 曾经的经典玄幻小说(-)
  9. C语言编程练习 3.写一个函数,如果它首次被调用,则返回字母A,第二次被调用,则返回字母B,第三次调用,则返回字母C,以此类推。(提示:使用一个static数据类型)
  10. 深度linux夜间模式,在Linux下安装Yin-Yang以在KDE中设置自动夜间模式