终于完成了韦根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//#include #ifndef MCU_MODEL #define MCU_MODEL 51 //<----在此设定mcu类型, 51代表51系列; avr代表avr系列 #endif //-----------------------51类MCU------------------------------------------- #if MCU_MODEL==51 // #include //在此设定51类MCU的头文件 // #include //_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//在此设定avr类MCU的头文件 #include // #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<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; }
上一篇:单片机控制1602液晶显示万年历
下一篇:流量传感器测量车辆瞬时耗油量的程序实验
推荐阅读最新更新时间:2024-03-16 13:06
- 热门资源推荐
- 热门放大器推荐