/*****************************************************************************
程序名:
编写人:dragon101788
I2C协议具体描述:
0x50 开始算密码
0x51 密码第1字节
0x52 密码第2字节
0x53 密码第3字节
0x54 密码第4字节
0x55 密码第5位
0x56 密码第6位
0x57 密码第7位
0x58 密码第8位
*****************************************************************************/
#include <STC12C5A60S2.h> // 包含头文件
#include <stdlib.h>
#include <stdio.h>
unsigned char code secret_key[8]={'1','9','8','8','1','0','1','7'};
unsigned char random[8]={0x55,'2'};
sbit IR_INT=P3^2;
sbit LED=P3^4;
sbit LED2=P3^5;
//#define I2C_TIMEOUT 200
unsigned int i2c_timeout;//超时时间
#define I2C_TIMEOUT (i2c_timeout*2+5)
unsigned char I2CsADDR=0x17;
sbit I2CsCLK=P1^1;
sbit I2CsDAT=P1^0;
unsigned char dat[4] = {0,0,0,0}; //用于存放按键码值,初始化为 0000 0000
void RSHash()
{
char i;
unsigned char a=0;
unsigned char hash=0;
for(i = 0; i < 8; i++)
{
a = random[i]+hash;
hash += a;
random[i]=secret_key[hash%8]*hash;
}
}
/*****************************************************************************
UART 串口初始化函数
振荡晶体为 12MHz,PC 串口端设置 [ 4800,8,无,1,无 ]
*****************************************************************************/
void UART_Init (void)
{
EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
ES = 1; //允许UART 串口的中断
TMOD = 0x20; //定时器 T/C1 工作方式 2
SCON = 0x50; //串口工作方式 1,允许串口接收
TL1 = 0xF9; //定时器初值低 8 位设置,修改此处的值来修改波特率
TH1 = 0xF3; //定时器初值高 8 位设置,修改此处的值来修改波特率
PCON = 0x80; //波特率倍频
TR1 = 1; //定时器启动
}
/*****************************************************************************
UART 串口接收中断处理函数
*****************************************************************************/
void UART_R (void) interrupt 4 using 1
{
unsigned char ch; //定义串口接收数据变量
//LED=!LED;
RI = 0; //令接收中断标志位为 0(软件清零)
ch = SBUF; //将接收到的数据送入变量 UART_data
putchar(ch);
}
int i2s_wait_low()
{
int i;
for(i=0;i<I2C_TIMEOUT;i++)
{
if(I2CsCLK==0)
{
i2c_timeout=i;
return i;
}
}
return -1;
}
int i2s_wait_high()
{
int i;
for(i=0;i<I2C_TIMEOUT;i++)
{
if(I2CsCLK==1)
{
return i;
}
}
return -1;
}
int i2s_send_ack()
{
//int i;
//低电平变化
i2s_wait_low();
I2CsDAT=0;
//高电平稳定
i2s_wait_high();
return 0;
}
int i2s_read_ack()
{
//int i;
//低电平变化
i2s_wait_low();
//高电平稳定
i2s_wait_high();
return (I2CsDAT==0);
}
void i2s_stop()
{
int i;
i2s_wait_high();
for(i=0;i<I2C_TIMEOUT;i++)
{
if(I2CsCLK==0)
{
LED=0;
I2CsDAT=1;
return;
}
}
}
char i2s_read_byte(unsigned char * pbyte)
{
char i;
//int ret;
unsigned char byte;
for(i=0;i<8;i++)
{
if(i2s_wait_low()<0)
{//STOP位
I2CsDAT=1;
return -1;
}
I2CsDAT=1;
if(i2s_wait_high()<0)
{
return -1;
}
byte<<=1;
byte|=I2CsDAT;
}
*pbyte=byte;
return 0;
}
char i2s_send_byte(unsigned char * pbyte)
{
char i;
//int ret;
unsigned char byte = *pbyte;
for(i=0;i<8;i++)
{
if(i2s_wait_low()<0)
{
return -1;
}
I2CsDAT=(byte>>7-i)&0x1;
if(i2s_wait_high()<0)
{
return -1;
}
}
return 0;
}
unsigned char cmd[12]={0};
void i2s_slave()
{
unsigned char addr=0;
char rw=0;
char ret;
char i;
int count;
//START 信号
if(I2CsDAT==0&&I2CsCLK==1)
{
//收到START信号
LED2=1;
LED=1;
i2c_timeout=200;
}
else return;
//读取地址位
ret=i2s_read_byte(&addr);//接收数据
if(ret<0)
{
LED2=0;
return;
}
rw=addr&0x01;
addr=addr>>1;
if(addr==I2CsADDR)
{//收到地址位正确,返回ack
i2s_send_ack();
}
else return;
//地址匹配成功,读取数据
if(rw==0)//主机写数据
{
LED=0;
for(i=0;i<12;i++)
{
ret=i2s_read_byte(&cmd[i]);//接收数据
if(ret<0)
{//收到stop信号,或者伪START
count=i;
//if(count==1)break;//收到伪START
//printf("timeout=%d\r\n",i2c_timeout);
//printf("addr=%#x\r\n",(int)addr);
//for(i=0;i<12;i++)
// printf("cmd[%x]\r\n",(int)cmd[i]);
//printf("count[%d]\r\n",count);
break;
}
i2s_send_ack();
}
}
else //主机读数据
{
if(cmd[0]>0x50&&cmd[0]<=0x58)
{
i2s_send_byte(&random[cmd[0]-0x51]);
i2s_read_ack();
}
}
//i2s_stop();
if(rw==0&&count==2)
{//收到STOP并且写数据
if(cmd[0]==0x50)
{//收到数据
//for(i=0;i<8;i++)
// printf("random[%x]\r\n",random[i]);
RSHash();//计算哈希值
}
else if(cmd[0]>0x50&&cmd[0]<=0x58)
{
random[cmd[0]-0x51]=cmd[1];
}
}
}
void udelay(unsigned int udec)
{
//公式为 t=(12/fos)*n fos=晶振平率 n=udec
//(65536-udec+校准值)
TH0 = (65536-udec+200)/256; //定时 0.85ms,
TL0 = (65536-udec+200)%256; //定时 0.85ms,
TR0 = 1;
while( !TF0 );
TF0 = 0;
TR0 = 0;
}
/*****************************************************************************
主函数
*****************************************************************************/
void main (void)
{
UART_Init();
TMOD = 0x21; // 定时器 0,方式 1
IT0 = 1; // 外部中断0,下降沿触发
EX0 = 1; // 允许外部中断
EA = 1; // 允许中断
//printf("\r\n####HU#### main\r\n");
while(1)
{
i2s_slave();
}
}
/*****************************************************************************
外部中断 0 处理函数
/****************************************************************************/
void INT0() interrupt 0 using 1
{
unsigned char i,j;
unsigned short k;
EX0 = 0; //拒绝外部中断 0
for(i=0;i<10;i++) //0.85ms 延时,运行 10 次,即 8.5ms
{
TH0 = (65536-850)/256; //定时 0.85ms,
TL0 = (65536-850)%256; //定时 0.85ms,
TR0 = 1;
while( !TF0 );
TF0 = 0;
TR0 = 0;
if( IR_INT )// 这 8.5ms 期间只要 IR_INT 变高电平,就非合法的红外信号,跳出
{
EX0 = 1; // 跳出,准许中断,重新判断按键是否有效
return ;
}
}
while( !IR_INT ); //程序进行到这里,表明是合法的红外信号(9ms引导结束)
TH0 =(65536-2250)/256; //定时 2.25ms
TL0 =(65536-2250)%256; //定时 2.25ms
TR0 = 1;
while(!TF0);
TF0 = 0;
TR0 = 0;
if( !IR_INT ) //IR_INT 为低表明是连发码,跳出
{
printf(".");
EX0=1; // 跳出,允许中断,重新判断按键是否有效
return;
}
while( IR_INT ); //等待4.5ms 高电平的结果码结束
for(i=0; i<4; i++) //开始接收用户码
{
for(j=0; j<8; j++) //接收 8 次数据位
{
while( !IR_INT ); //等待 0.56ms 低电平结束
dat[i] >>= 1; //把上次的数据位右移一位,移动 8 次证
TH0 =(65536-1000)/256; //定时 1ms
TL0 =(65536-1000)%256; //定时 1ms
TR0 = 1;
while( !TF0 );
TR0=0;
TF0=0;
if( IR_INT ) //若为高电平,则数据为“1”,如果是低电平数据为 0
{
dat[i] |= 0x80; //所有数据位 1 放最高位
while( IR_INT ); //等待高电平过去
}
}
}
if(dat[0]==0x00&&dat[1]==0xFF) //判断地址是否为 0X00FF,如果不是,则不是这个红外遥控发出
{
printf("OK\r\n");
}
EX0=1; //允许中断,重新判断按键是否有效
k=dat[2]<<8|dat[3];
printf("###HU### infrared 0x%04x\r\n",k);
return;
}
51单片机作为i2c从设备,加密芯片+红外+串口
5星 · 超过95%的资源 需积分: 34 63 浏览量
2013-06-13
11:59:01
上传
评论 3
收藏 54KB RAR 举报
龙图腾
- 粉丝: 274
- 资源: 51
最新资源
- 基于QT+C++做界面+使用esunny外盘api实现的一个快速行情、交易系统+源码+开发文档说明(毕业设计&课设&项目开发)
- 三菱PLC例程源码单钮起停控制程序三例
- oracle相关数据库的知识,包括建表语句,索引视图,触发器存储过程等
- MATLAB人脸识别+可调摄像头,库外判别预警,GUI界面.zip
- Oracle数据库备份与恢复.pdf
- 302P-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 基于servlet的游戏商城(采用RESTful架构风格).zip
- 三菱PLC例程源码单按钮正反停
- C# 飞机大战项目, 获取道具,双排子弹 散弹的实现
- 三菱PLC例程源码单按钮五台电机启停控制SFC程序
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈