終于完成了韋根26查詢法的程序了,IIC和串口通詢昨天改好,因?yàn)楝F(xiàn)在沒做到聯(lián)網(wǎng)部分,所以沒做聯(lián)網(wǎng)方面的通訊協(xié)議和程序。
串口通訊程序
void Init(void) { TMOD|=0x21;//定時(shí)器1為方式2,定時(shí)器0方式1 TL1=0xfd; //初始值設(shè)置波特率為9600 // TH1=0xfd; ET0=1; TR1=1; //開定時(shí)器1 REN=1; //允許接收數(shù)據(jù)// 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 //<----在此設(shè)定mcu類型, 51代表51系列; avr代表avr系列 #endif //-----------------------51類MCU------------------------------------------- #if MCU_MODEL==51 // #include<reg51.h> //在此設(shè)定51類MCU的頭文件 // #include<intrins.h> //_nop_()函數(shù)需要 // #include"xd.h" // #include"xdprj.h" //---------定義I2總線端口, 可根據(jù)實(shí)際使用改變----------- sbit SCL=P2^0; //I2總線時(shí)鐘線 sbit SDA=P2^1; //I2總線數(shù)據(jù)線 #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_() //延時(shí)用,如果要加長延時(shí),可增加或減少 _nop_(); //------------------------avr類MCU----------------------------------------- #elif MCU_MODEL==avr #include<iom16v.h> //在此設(shè)定avr類MCU的頭文件 #include<macros.h> // #include"xd.h" // #include"xdprj.h" //-----定義I2總線端口, 可根據(jù)實(shí)際使用改變---- #define SCL_L PORTC&=~BIT(0) //I2總線時(shí)鐘線 #define SCL_H PORTC|=BIT(0) #define SDA_L PORTC&=~BIT(1) //I2總線數(shù)據(jù)線 #define SDA_H PORTC|=BIT(1) #define SDA_TO_IN DDRC&=~BIT(1); _NOP() //設(shè)數(shù)據(jù)線位輸入 #define SDA_TO_OUT DDRC|=BIT(1); _NOP() //設(shè)數(shù)據(jù)線位輸出 #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單片機(jī)在晶振為8MHz時(shí),延時(shí)5us, 可根據(jù)實(shí)際情況改變 #endif //--------------------------------------------------------------------------- //------在此設(shè)定芯片型號------ #define e2prom 2 // <---在此設(shè)定芯片型號, 1代表24C01; 16代表24C16; 512代表24C512 #if e2prom==1 #define PAGE_SIZE 8 //芯片頁寫緩沖器大小,單位:字節(jié)/ #define SIZE 0x007f // 芯片內(nèi)含有多少個(gè)8位的字節(jié)/ #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 //-------------------------- //--------在此設(shè)定芯片地址------- #define W_ADD_COM 0xa0 //寫字節(jié)命令及器件地址(根據(jù)地址實(shí)際情況改變), 1010 A2 A1 A0 0 #define R_ADD_COM 0xa1 //讀命令字節(jié)及器件地址(根據(jù)地址實(shí)際情況改變), 1010 A2 A1 A0 1 //------------------------------- //-----在此改變預(yù)置錯(cuò)誤號----- //#define I2C_ERR ERR_10 //寫字節(jié)命令及器件地址錯(cuò), 在此也就是讀寫器件錯(cuò)!! //--------------------------- //-------------------------------以下為其它I2總線器件可調(diào)用的函數(shù)-------------------------- //起始信號 void i2cstart(void) { //SCL_L; //DELAY_us; SDA_H; //發(fā)送起始條件的數(shù)據(jù)信號*/ DELAY_us; SCL_H; DELAY_us; //起始條件建立時(shí)間大于4.7us,延時(shí)*/ SDA_L; //發(fā)送起始信號*/ DELAY_us; //起始條件鎖定時(shí)間大于4μs* SCL_L; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)/ DELAY_us; } //停止信號 / void i2cstop(void) { //SCL_L; //DELAY_us; SDA_L; //發(fā)送結(jié)束條件的數(shù)據(jù)信號* DELAY_us; SCL_H; DELAY_us; // 結(jié)束條件建立時(shí)間大于4μs SDA_H; // 發(fā)送I2C總線結(jié)束信號* DELAY_us; } //等待從器件應(yīng)答/ void i2cask() { uchar i; SCL_H; DELAY_us; while((SDA==1)&&(i<250))i++; SCL_L; DELAY_us; } /*/MCU應(yīng)答信號/ void i2cack() { SDA_L; DELAY_us; SCL_H; DELAY_us; SCL_L; DELAY_us; } */ //i2c讀要調(diào)用的函數(shù) //從器件讀出一個(gè)字節(jié) uchar i2crd(void) { uchar i,temp; //i2c讀要調(diào)用的函數(shù) //從器件讀出一個(gè)字節(jié) uchar i2crd(void) { uchar i,temp; SCL_L; DELAY_us; // 準(zhǔn)備接收數(shù)據(jù)位*時(shí)鐘低電平周期大于4.7μs SDA_H; DELAY_us; //置數(shù)據(jù)線接上內(nèi)部上拉(數(shù)據(jù)輸入方式),此為必須/ for(i=0;i<8;i++) { SCL_H; // 置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效/ DELAY_us; temp<<=1; SDA_TO_IN; //如果是avr單片機(jī),就設(shè)SDA引腳位輸入狀態(tài) if(SDA_IF_H) temp=temp+1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入temp中; SCL_L; DELAY_us; SDA_TO_OUT; //如果是avr單片機(jī),就設(shè)SDA引腳位輸出狀態(tài) } // SCL_L; // DELAY_us; //主器件應(yīng)答脈沖 // SDA_L; DELAY_us; // SCL_H; DELAY_us; return(temp); }//把一個(gè)字節(jié)數(shù)據(jù)輸入器件,并以收到應(yīng)答信號為止/ //寫入成功返回1,失敗返回0 uchar i2cwt(uchar a) { uchar i; for(i=0;i<8;i++) //要寫入的數(shù)據(jù)長度為8位* { SCL_L; DELAY_us; if((a<<i)&0x80) // 判斷發(fā)送位(按位與,只要最高位為1則真) SDA_H; else SDA_L; DELAY_us; SCL_H; //置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位* DELAY_us; //保證時(shí)鐘高電平周期大于4μs* } SCL_L; DELAY_us; SDA_H; // 8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位* DELAY_us; SCL_H; DELAY_us; SDA_TO_IN; //如果是avr單片機(jī),就設(shè)SDA引腳位輸入狀態(tài)/ if(SDA_IF_L) //測試有無應(yīng)答/ { SDA_TO_OUT; return(1); //有應(yīng)答返回1 } else { SDA_TO_OUT; return(0); //無應(yīng)答 } } 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};//接收韋根數(shù)據(jù)26位 idata unsigned char WG[8]={0xaa,0xbb,0,0,0,0,0xcc,0xdd};//存韋根ID卡卡號的HID和PID碼,其中HID碼為8位即一字節(jié),PID碼16位兩字節(jié) 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; //關(guān)中斷以免外部中斷的干擾 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; }