测试流程:
1把7326_test_1.c 生成的hex 烧进单片机
2打开串口
这里会收到循环发送的00 00 00 00
3按单片机测试按键key1 看配置寄存器是不是10 不是要重新往配置寄存器写入0x10
4长按7326按键 串口接收窗口会收到键值
24c02.c
#define device_add_w 0xb0
#define device_add_r 0xb1
#include "24c02.H"
void delay()
{
;;
}
void i2c_init()
{
SDa = 1;
delay();
scl = 1;
delay();
}
void delayms(uint xms)
{
uchar x, y;
for(x = xms; x > 0; x--)
for(y = 110; y > 0; y--);
}
void start() //启动i2c
{
sda = 1;
scl = 1;
delay(); //延时必须大于4.7us,此约为五微秒
sda = 0; //在scl为高电平时,sda一个下降沿为启动信号
delay();
}
void stop() //停止i2c
{
sda = 0;
scl = 1;
delay();
sda = 1; //在scl为高电平时,sdasda一个上升沿为停止信号
delay();
}
void ack() //应答信号0
{
uchar i = 0; //等待变量
scl = 1; //在scl为高电平期间等待应答
delay();
while((sda == 1) && i < 250) //若为应答0即退出,从机向主机发送应答信号
i++; //等待一段时间
scl = 0; //应答之后将scl拉低
delay();
}
void nack() //非应答
{
scl = 1; //在scl为高电平期间,由主机向从机发送一个1,非应答信号
delay();
sda = 1;
scl = 0; //应答之后将scl拉低
delay();
}
void send_byte(uchar date) //写一个字节8位
{
uchar i, temp;
temp = date; //存入要写入的数据,即要发送到sda上的数据
for(i = 0; i < 8; i++)
{ //发送8位
temp <<= 1; //to CY 将数据的最高位移入到PSW中的CY位中
scl = 0; //只有在scl为低电平时,才允许sda上的数据变化
delay();
sda = CY; //将CY里的数据发送到sda数据线上
delay(); //可以延时
scl = 1; //在scl为高电平时,不允许sda上的数据变化,使数据稳定
delay();
scl = 0; //允许sda数据线的数据变化,等待下一个数据的传输
delay();
}
//wait ack:发送完一个字节数据后要主机要等待从机的应答,第九位
scl = 0; //允许sda变化
delay();
sda = 1; //wait:ack,sda拉高等待应答,当sda=0时,表示从机的应答
delay();
}
uchar read_byte() //读一个字节数据
{
char i, j, k;
scl = 0; //读之前先允许sda变化
delay(); //等待数据
for(i = 0; i < 8; i++)
{
scl = 1; //不允许sda变化
delay(); //使sda数据稳定后开始读数据
j = sda; //读出sda上的数据
k = (k << 1)| j; //将数据通过|运算存入k中
scl = 0; //允许sda变化等待下一位数据的到来
delay();
}
//delay(); //可不用延时
return k; //返回读出的数据
}
//write:at24c02 在at24c02中的指定地址写入数据
void write_at24c02(uchar address, uchar date)
{
start(); //启动i2c
send_byte(device_add_w); //写入期间地址和写操作
ack(); //从机应答0
send_byte(address); //写入写数据的单元地址
ack(); //ack0
send_byte(date); //在指定地址中写入数据
ack(); //从机应答0
stop(); //停止i2c
}
//read: at24c02 在at24c02的指定地址中读出写入的数据
uchar read_at24c02(address)
{
uchar dat; //用来存储读出的数据
start(); //启动i2c
send_byte(device_add_w); //写入at24c02器件地址和写操作
ack(); //从机应答0
send_byte(address); //写入要读取AT24C02的数据的单元地址
ack(); //从机应答0
start(); //再次启动i2c
send_byte(device_add_r); //写入AT24C02器件地址和读操作
ack(); //从机应答‘0’
dat = read_byte(); //读出指定地址中的数据
nack(); //主机发出非应答‘1’
stop(); //停止i2c
return dat; //返回读出的数据
}
24c02.h
#include
typedef unsigned char uchar;
typedef unsigned int uint;
sbit sda= P1^0;
sbit scl = P1^1;
void delay(void);
void i2c_init(void); //I2C初始化
void delayms(uint xms);
void start(void); //启动I2C
void stop(void); //停止I2C
void ack(void); //应答
void nack(void); //不应答
void send_byte(uchar d); //写一个字节
uchar read_byte(void); //读一个字节,返回数据
void write_at24c02(uchar addr,uchar dd);//写入指定地址的一个字节 (要写入的寄存器地址,写入十六进制数据)
uchar read_at24c02(uchar addr); //读出指定地址的一个字节 (要读取的寄存器地址)
创建整理:ly
时间:2016.8.24
功能:用51单片机对7326智能扫描按键的测试
文档组成:24c02.h 24c02.c构成了I2C驱动
7326_test_1.c 为串口测试程序
7326_test_1.c
#include
#include "24C02.H"
unsigned char uart_data;
//测试的两个按键
sbit key1=P3^4;
sbit key2=P3^5;
//发送函数
void SendASC(uchar ASC)
{
TI=0;
SBUF=ASC;
while(!TI);
}
//串口0 中断函数 这个中断函数可以不用响应 这个是再向单片机发送数据
void serial_IT() interrupt 4
{
if (RI == 1)//如果是接收中断
{
RI = 0; //清除接收中断标志
uart_data = SBUF; //接收数据
SendASC(uart_data);//将接收的数据发送
}
}
//主程序
void main()
{
//串口设置
unsigned n,nn,nnn;
SCON = 0x50; //8位串行口模式1,允许接收,REN=1
TMOD = TMOD | 0x20; //TMOD = 0x20; //定时器1,工作在模式2
TH1 = 0xe6;//波特率为1200bps,晶振频率为12MHz
TL1 = 0xe6;//波特率为1200bps,晶振频率为11.059MHz,则加载e8
ES=1; //打开串行口中断
TR1 = 1; //启动定时器
EA=1; //打开总中断
i2c_init(); // I2C的初始化
start(); // I2C开始
while(1){
if(key1==0)
{ delay();//消抖
if(key1==0)
{
write_at24c02(0x08,0x10); //用于向配置寄存器写值 这个可以参考7326技术文档
delayms(10);//需等待十毫秒
n=read_at24c02(0x08); //读取7326设备配置寄存器的值
nn= n;
SendASC(nn);
}
}
//这个是结合自己的51 写的。
//write_at24c02(0,2);
//delayms(10);
write_at24c02(0x08,0x10);
n=read_at24c02(0x10); //读缓存器的地址 由7326的文档结合电路原理图片可知
nnn= n;
SendASC(nnn);
}
}