📄 saa1064.c
字号:
//......................................
//名称: SAA1064.c 4位LED驱动芯片的接口程序
//编程: 机灵小老鼠(QQ: 879381753)
//日期: 20071010
//
//发现问题请指点,谢谢!
//......................................
//CPU: 89C52 11.0592MHz
//环境: Keil C51 V8.01
//引脚定义:
// CPU_P2.0 --- SAA1064_SCL 时钟
// CPU_P2.1 --- SAA1064_SDA 数据
//......................................
#include <Public.h>
#include <Intrins.h>
#include "delay_s.h"
#include "saa1064.h"
//内部函数
static void i2c_start_cond(void);
static void i2c_stop_cond(void);
static uchar i2c_read_byte(void);
static uchar i2c_read_byte_nack(void);
static void i2c_write_byte(uchar da);
//=============================================================================
//接口调用函数部分
//*******************************************************
//序号:
// HD_SAA1064_S01
//功能:
// 读出芯片的复位状态
//输入:
// add 器件的子地址 0~3
//输出:
// =1 芯片已经复位,=0 芯片在复位中
//********************************************************
bit SAA1064_read_status(uchar add)
{
uchar i;
i2c_start_cond();
i2c_write_byte(SAA1064_READ |((add <<1) &0x06));//器件地址=0111 0 A1 A0 r/w
i =i2c_read_byte_nack(); //顺序读的方式读出一个字节
i2c_stop_cond();
return((i &0x80) ?1:0);
}
//*******************************************************
//序号:
// HD_SAA1064_S02
//功能:
// 写入指令字节和数据
//输入:
// add_of_part: 器件的子地址 0~3
// add_of_reg: 器件内的寄存器地址
// len_of_all: 指定长度 1~5
// str: 存放写入指令和数据串的地址指针
//str中的数据排列决定于add_of_reg和len_of_all,完整的数据如下:
//ctl_byte, led1_byte, led2_byte, led3_byte, led4_byte,
//输出:
// 无
//********************************************************
void SAA1064_write_string_all(uchar add_of_part, uchar add_of_reg, uchar len_of_all, uchar *str)
{
uchar i;
if( (len_of_all ==0) ||
(len_of_all >5) ||
(add_of_reg >SAA1064_REGISTER_ADDR_MAX)
) return;
i2c_start_cond();
i2c_write_byte(SAA1064_WRITE |((add_of_part <<1) &0x06)); //器件地址=01110 A1 A0 r/w
i2c_write_byte(add_of_reg);
for(i=0; i<len_of_all; i++)
{
i2c_write_byte(str[i]); //字节写方式写入一个字节
}
i2c_stop_cond();
delay_x1ms(5);
}
//==============
//内部调用函数部分
//==============
//----------------------------------------------
//I2C 发启始条件:时钟线为高时数据线发生下降沿跳变
//----------------------------------------------
static void i2c_start_cond(void)
{
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SDA_HIGH;
_DELAY_NOP3;
CODE_SCL_HIGH;
_DELAY_NOP3;
CODE_SDA_LOW;
_DELAY_NOP3;
}
//----------------------------------------
//I2C 发结束条件:时钟线为高时数据线发生上升沿跳变
//----------------------------------------
static void i2c_stop_cond(void)
{
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SDA_LOW;
_DELAY_NOP3;
CODE_SCL_HIGH;
_DELAY_NOP3;
CODE_SDA_HIGH;
_DELAY_NOP3;
}
//----------------------------------------
// I2C 读取一个中间字节的数据
//----------------------------------------
static uchar i2c_read_byte(void)
{
uchar i;
uchar da=0;
for(i =0; i<8; i++)
{
da <<=1; //传输的数据高位在前
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SCL_HIGH; //时钟为高时读数据
//NOP3;
if (JUDGE_SAA1064_SDA) da++;
}
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SDA_LOW; //发送应答位
_DELAY_NOP3;
CODE_SCL_HIGH;
_DELAY_NOP3;
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SDA_HIGH;
return(da);
}
//----------------------------------------
// I2C 读取一个结尾字节的数据
//----------------------------------------
static uchar i2c_read_byte_nack(void)
{
uchar i;
uchar da =0;
for (i =0; i<8; i++)
{
da <<=1;
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SCL_HIGH;
//NOP3;
if(JUDGE_SAA1064_SDA) da++;
}
CODE_SCL_LOW;
_DELAY_NOP3;
CODE_SDA_HIGH;
_DELAY_NOP3;
CODE_SCL_HIGH;
_DELAY_NOP3;
CODE_SCL_LOW;
return( da );
}
//----------------------------------------
// I2C 写入一个字节的数据
//----------------------------------------
static void i2c_write_byte(uchar da )
{
uchar i;
for(i =0; i<8; i++)
{
CODE_SCL_LOW;
if(da&0x80)
{
CODE_SDA_HIGH;
}
else
{
CODE_SDA_LOW;
}
CODE_SCL_HIGH;
da <<=1;
}
CODE_SCL_LOW; //第8个SCL下降沿,写入8位数据
_DELAY_NOP3;
CODE_SDA_HIGH;
_DELAY_NOP3;
CODE_SCL_HIGH;
}
//=============================================================================
//End Of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -