用STM32或者51單片機設計一個讀卡系統,對外接的I2C接口電路或者SPI接口電路進行讀寫操作,讀寫內容可以通過數碼管或者其他監視器件查看,并用示波器觀看通信線路波形。完成主機跟兩個從機之間的I2C通信,可以用數碼管等顯示通信的內容,也可以用示波器監視通信線路的數據信息。
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- typedef unsigned int u16;
- typedef unsigned char u8;
- sbit SDA=P1^1;
- sbit SCL=P1^0;
- void At24CO2Write(u8 add,u8 dat,u8 addr);
- u8 At24CO2Read(u8 add,u8 addr);
- u8 numer[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- u8 display[4];
- sbit A1=P2^2;
- sbit B1=P2^3;
- sbit C1=P2^4;
- #define SHUMA P0
- sbit K1=P3^0;//保存
- sbit K2=P3^1;//讀取
- sbit K3=P3^2;
- sbit K4=P3^3;
- sbit K5=P3^4;//num++
- sbit K6=P3^5;//清零
- sbit led=P2^0;
- u8 num;
- void delay(u16 i)
- {
- while(i--);
- }
- void delay10us(void)
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=2;a>0;a--);
- }
- void shumaguan(u8 word[])
- { u8 i;
- for(i=0;i<4;i++)
- {
- switch(i)
- {
- case 0:C1=0;B1=0;A1=0;break;
- case 1:C1=0;B1=0;A1=1;break;
- case 2:C1=0;B1=1;A1=0;break;
- case 3:C1=0;B1=1;A1=1;break;
- }
- SHUMA=word[i];
- delay(100);
- SHUMA=0x00;
- }
- }
- void Key(u8 dat)
- {
-
- if(K1==0)
- {
- delay(1000);
- if(K1==0)
- {
- At24CO2Write(0xa0,dat,1);
- }
- while(!K1);
- }
- if(K2==0)
- {
- delay(1000);
- if(K2==0)
- {
- num=At24CO2Read(0xa0,1);
- }
- while(!K2);
- }
- if(K3==0)
- {
- delay(1000);
- if(K3==0)
- {
- At24CO2Write(0xa2,dat,1);
- }
- while(!K3);
- }
- if(K4==0)
- {
- delay(1000);
- if(K4==0)
- {
- num=At24CO2Read(0xa2,1);
- }
- while(!K4);
- }
- if(K5==0)
- {
- delay(1000);
- if(K5==0)
- num++;
- while(!K5);
- }
- if(K6==0)
- {
- delay(1000);
- if(K6==0)
- num=0;
- while(!K6);
- }
- }
- void change()
- {
- display[0]=numer[num/1000];
- display[1]=numer[(num%1000)/100];
- display[2]=numer[(num%100)/10];
- display[3]=numer[num%10];
- }
- void main()
- {
- // SDA=1;
- // delay10us();
- // SCL=0;
- // delay10us();
- //// u8 addr = 0x66;
- // uchar addr1=0x66, addr2=0x88, dat1, dat2;
-
- // write(0xa2, addr2, 0);
- while(1)
- {
- Key(num);
- change();
- shumaguan(display);
- }
- }
- void I2cStart() //開始函數,時鐘信號始終為高,當數據線由高變低時開始
- {
- SDA=1;
- delay10us();
- SCL=1;
- delay10us();
- SDA=0;
- delay10us();
- SCL=0;
- delay10us();
- }
- void I2cStop() //停止函數,時鐘信號始終為高,當數據線由低變高時開結束
- {
- SDA=0;
- delay10us();
- SCL=1;
- delay10us();
- SDA=1;
- delay10us();
- }
- void I2cAck()
- {
- SDA=0;
- delay10us();
- SCL=1;
- delay10us();
- SCL=0;
- delay10us();
- }
-
- void nack()
- {
- SDA = 1; //拉高SDA,發送非應答信號
- Delay();
- SCL = 1; //拉高SCL
- Delay();
- SCL = 0; //再拉低完成非應答位,并保持住總線
- }
-
- u8 I2cSend(u8 dat)
- {
- u8 i;
- for(i=0x80; i!=0; i>>=1) //從高位到低位依次進行
- {
- if((dat&i) == 0) //該位的值依次輸出到SDA上
- SDA = 0;
- else
- SDA = 1;
- delay10us();
- SCL = 1; //拉高SCL
- delay10us();
- SCL = 0; //再拉低SCL完成一個位周期
- }
- }
- u8 I2cRead()
- {
- u8 i, dat;
-
- SDA = 1; //確保主機釋放SDA
- for(i=0x80; i!=0; i>>=1) //從高位到低位依次進行
- {
- delay10us();
- SCL = 1; //拉高SCL
- if(SDA == 0) //讀取SDA的值
- dat &= ~i; //為0時,dat中對應位清零
- else
- dat |= i; //為1時,dat中對應位置1
- delay10us();
- SCL = 0; //再拉低SCL使從機發送出下一位
- }
- return dat;
- }
- void At24CO2Write(u8 add,u8 dat,u8 addr)
- {
- I2cStart();
- I2cSend(add);
- I2cAck();
- I2cSend(addr);
- I2cAck();
- I2cSend(dat);
- I2cAck();
- I2cStop();
- }
- u8 At24CO2Read(u8 add,u8 addr)
- {
- u8 num;
- I2cStart();
- I2cSend(add);
- I2cAck();
- I2cSend(addr);
- I2cAck();
- I2cStart();
- I2cSend(add+1);
- I2cAck();
- num=I2cRead();
- // nack();
- I2cStop();
- return num;
- }
復制代碼 Keil代碼與Proteus仿真下載:
實驗40.rar
(98.02 KB, 下載次數: 12)
2022-4-9 22:22 上傳
點擊文件名下載附件
|