终于完成了韦根26查询法的程序了,IIC和串口通询昨天改好,因为现在没做到联网部分,所以没做联网方面的通讯协议和程序。
串口通讯程序
void Init(void)
{
TMOD|=0x21;//定时器1为方式2,定时器0方式1
TL1=0xfd; //初始值设置波特率为9600 //
TH1=0xfd;
ET0=1;
TR1=1; //开定时器1
REN=1; //允许接收数据//
SM0=0;
SM1=1;
EA=1; //开所有中断
ES=1;
}
void SEND(unsigned char *a)
{
uchar b;
for(b=0;b<8;b++)
{
SBUF=*a;
while(TI==0);
TI=0;
a=a+1;
}
}
IIC总线24cxx读写通用程序
#include<config.h>
//#include<delay.h>
#ifndef MCU_MODEL
#define MCU_MODEL 51 //<----在此设定mcu类型, 51代表51系列; avr代表avr系列
#endif
//-----------------------51类MCU-------------------------------------------
#if MCU_MODEL==51
// #include<reg51.h> //在此设定51类MCU的头文件
// #include<intrins.h> //_nop_()函数需要
// #include"xd.h"
// #include"xdprj.h"
//---------定义I2总线端口, 可根据实际使用改变-----------
sbit SCL=P2^0; //I2总线时钟线
sbit SDA=P2^1; //I2总线数据线
#define SCL_L SCL=0
#define SCL_H SCL=1
#define SDA_L SDA=0
#define SDA_H SDA=1
#define SDA_TO_IN //为配合avr共用次程序而空定义的宏
#define SDA_TO_OUT //为配合avr共用次程序而空定义的宏
#define SDA_IF_L SDA==0 //如果sda为低
#define SDA_IF_H SDA==1 //如果sda为高
//------------------------------------------------------
#define DELAY_us _nop_(); _nop_(); _nop_(); _nop_(); _nop_() //延时用,如果要加长延时,可增加或减少 _nop_();
//------------------------avr类MCU-----------------------------------------
#elif MCU_MODEL==avr
#include<iom16v.h> //在此设定avr类MCU的头文件
#include<macros.h>
// #include"xd.h"
// #include"xdprj.h"
//-----定义I2总线端口, 可根据实际使用改变----
#define SCL_L PORTC&=~BIT(0) //I2总线时钟线
#define SCL_H PORTC|=BIT(0)
#define SDA_L PORTC&=~BIT(1) //I2总线数据线
#define SDA_H PORTC|=BIT(1)
#define SDA_TO_IN DDRC&=~BIT(1); _NOP() //设数据线位输入
#define SDA_TO_OUT DDRC|=BIT(1); _NOP() //设数据线位输出
#define SDA_IF_L (PINC&BIT(1))==0 //如果sda为低
#define SDA_IF_H (PINC&BIT(1))==BIT(1) //如果sda为高
//-------------------------------------------
#define DELAY_us tus(7) //avr单片机在晶振为8MHz时,延时5us, 可根据实际情况改变
#endif
//---------------------------------------------------------------------------
//------在此设定芯片型号------
#define e2prom 2 // <---在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512
#if e2prom==1
#define PAGE_SIZE 8 //芯片页写缓冲器大小,单位:字节/
#define SIZE 0x007f // 芯片内含有多少个8位的字节/
#elif e2prom==2
#define PAGE_SIZE 8
#define SIZE 0x00ff
#elif e2prom==4
#define PAGE_SIZE 16
#define SIZE 0x01ff
#elif e2prom==8
#define PAGE_SIZE 16
#define SIZE 0x03ff
#elif e2prom==16
#define PAGE_SIZE 16
#define SIZE 0x07ff
#elif e2prom==32
#define PAGE_SIZE 32
#define SIZE 0x0fff
#elif e2prom==64
#define PAGE_SIZE 32
#define SIZE 0x1fff
#elif e2prom==128
#define PAGE_SIZE 64
#define SIZE 0x3fff
#elif e2prom==256
#define PAGE_SIZE 64
#define SIZE 0x7fff
#elif e2prom==512
#define PAGE_SIZE 128
#define SIZE 0xffff
#endif
//--------------------------
//--------在此设定芯片地址-------
#define W_ADD_COM 0xa0 //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa1 //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
//-------------------------------
//-----在此改变预置错误号-----
//#define I2C_ERR ERR_10 //写字节命令及器件地址错, 在此也就是读写器件错!!
//---------------------------
//-------------------------------以下为其它I2总线器件可调用的函数--------------------------
//起始信号
void i2cstart(void)
{
//SCL_L;
//DELAY_us;
SDA_H; //发送起始条件的数据信号*/
DELAY_us;
SCL_H;
DELAY_us; //起始条件建立时间大于4.7us,延时*/
SDA_L; //发送起始信号*/
DELAY_us; //起始条件锁定时间大于4μs*
SCL_L; //钳住I2C总线,准备发送或接收数据/
DELAY_us;
}
//停止信号 /
void i2cstop(void)
{
//SCL_L;
//DELAY_us;
SDA_L; //发送结束条件的数据信号*
DELAY_us;
SCL_H;
DELAY_us; // 结束条件建立时间大于4μs
SDA_H; // 发送I2C总线结束信号*
DELAY_us;
}
//等待从器件应答/
void i2cask()
{
uchar i;
SCL_H;
DELAY_us;
while((SDA==1)&&(i<250))i++;
SCL_L;
DELAY_us;
}
/*/MCU应答信号/
void i2cack()
{
SDA_L;
DELAY_us;
SCL_H;
DELAY_us;
SCL_L;
DELAY_us;
} */
//i2c读要调用的函数
//从器件读出一个字节
uchar i2crd(void)
{ uchar i,temp;
//i2c读要调用的函数
//从器件读出一个字节
uchar i2crd(void)
{ uchar i,temp;
SCL_L; DELAY_us; // 准备接收数据位*时钟低电平周期大于4.7μs
SDA_H; DELAY_us; //置数据线接上内部上拉(数据输入方式),此为必须/
for(i=0;i<8;i++)
{
SCL_H; // 置时钟线为高使数据线上数据有效/
DELAY_us;
temp<<=1;
SDA_TO_IN; //如果是avr单片机,就设SDA引脚位输入状态
if(SDA_IF_H)
temp=temp+1; //读数据位,接收的数据位放入temp中;
SCL_L;
DELAY_us;
SDA_TO_OUT; //如果是avr单片机,就设SDA引脚位输出状态
}
// SCL_L;
// DELAY_us; //主器件应答脉冲
// SDA_L; DELAY_us;
// SCL_H; DELAY_us;
return(temp);
}//把一个字节数据输入器件,并以收到应答信号为止/
//写入成功返回1,失败返回0
uchar i2cwt(uchar a)
{ uchar i;
for(i=0;i<8;i++) //要写入的数据长度为8位*
{
SCL_L;
DELAY_us;
if((a<<i)&0x80) // 判断发送位(按位与,只要最高位为1则真)
SDA_H;
else
SDA_L;
DELAY_us;
SCL_H; //置时钟线为高,通知被控器开始接收数据位*
DELAY_us; //保证时钟高电平周期大于4μs*
}
SCL_L;
DELAY_us;
SDA_H; // 8位发送完后释放数据线,准备接收应答位*
DELAY_us;
SCL_H;
DELAY_us;
SDA_TO_IN; //如果是avr单片机,就设SDA引脚位输入状态/
if(SDA_IF_L) //测试有无应答/
{ SDA_TO_OUT;
return(1); //有应答返回1
}
else
{ SDA_TO_OUT;
return(0); //无应答
}
}
void wt24c(uchar address,uchar date)
{
i2cstart();
i2cwt(0xa0);
i2cask();
i2cwt(address);
i2cask();
i2cwt(date);
i2cask();
i2cstop();
}
uchar rd24c(uchar address)
{
uchar temp;
i2cstart();
i2cwt(0xa0);
i2cask();
i2cwt(address);
i2cask();
i2cstart();
i2cwt(0xa1);
i2cask();
temp=i2crd();
return temp;
i2cstop();
}
查询法读韦根26程序
idata unsigned char WGDATA[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//接收韦根数据26位
idata unsigned char WG[8]={0xaa,0xbb,0,0,0,0,0xcc,0xdd};//存韦根ID卡卡号的HID和PID码,其中HID码为8位即一字节,PID码16位两字节
uchar a,x,j,LL,II,YY;
void ys100us(uint u)
{ uint y;
uchar x;
for(y=u;y>0;y--)
{
for(x=20;x>0;x--)
_nop_();
}
}
void DATA(void)
{
if(DATA0!=DATA1)
{
if(DATA0==0)
{
WGDATA[Cnt]=0;
if(Cnt==25)
a=1;
Cnt++;
ys100us(15);
}
if(DATA1==0)
{
WGDATA[Cnt]=1;
if(Cnt==25)
a=1;
Cnt++;
ys100us(15);
}
}
}
bit re(void)
{
if(Read_Card())
{
WG[3]=WGDATA[1];
WG[4]=WGDATA[2];
WG[5]=WGDATA[3];
return 1;
// SEND(&WG[0]);
}
DATA();
if(a==1)
{
EA=0; //关中断以免外部中断的干扰
a=0;
Cnt=0;
// rd24c(ptr,0,10);
// WG[0]=*ptr;
for(x=1;x<9;x++)
LL=(LL<<1)|WGDATA[x];
for(x=9;x<17;x++)
II=(II<<1)|WGDATA[x];
for(x=17;x<25;x++)
YY=(YY<<1)|WGDATA[x];
//WG[0]=rd24c(0);
//ysms(100);
WG[3]=LL;
WG[4]=II;
WG[5]=YY;
EA=1;
// SEND(&WG[0]);
return 1;
}
return 0;
} |