找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1116|回复: 0
收起左侧

单片机IIC读卡系统设计仿真程序

[复制链接]
ID:449849 发表于 2022-4-9 22:18 | 显示全部楼层 |阅读模式
用STM32或者51单片机设计一个读卡系统,对外接的I2C接口电路或者SPI接口电路进行读写操作,读写内容可以通过数码管或者其他监视器件查看,并用示波器观看通信线路波形。 51hei.png 51hei.png

单片机源程序如下:

  1. #include<reg51.h>
  2. #include<intrins.h>


  3. typedef unsigned int u16;
  4. typedef unsigned char u8;
  5. sbit SDA=P1^1;
  6. sbit SCL=P1^0;
  7. void At24CO2Write(u8 dat,u8 addr);
  8. u8 At24CO2Read(u8 addr);

  9. u8 numer[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  10. u8 display[4];
  11. sbit A1=P2^2;
  12. sbit B1=P2^3;
  13. sbit C1=P2^4;
  14. #define SHUMA P0
  15. sbit K1=P3^0;//保存
  16. sbit K2=P3^1;//读取
  17. sbit K3=P3^2;//num++
  18. sbit K4=P3^3;//清零

  19. sbit led=P2^0;
  20. u8 num;
  21. void delay(u16 i)
  22. {
  23. while(i--);
  24. }

  25. void delay10us(void)   
  26. {
  27.     unsigned char a,b;
  28.     for(b=1;b>0;b--)
  29.         for(a=2;a>0;a--);
  30. }

  31. void shumaguan(u8 word[])
  32. {         u8 i;
  33.   for(i=0;i<4;i++)
  34. {
  35.   switch(i)
  36.   {
  37.   case 0:C1=0;B1=0;A1=0;break;
  38.   case 1:C1=0;B1=0;A1=1;break;
  39.   case 2:C1=0;B1=1;A1=0;break;
  40.   case 3:C1=0;B1=1;A1=1;break;
  41.   }
  42.   SHUMA=word[i];
  43.   delay(100);
  44.   SHUMA=0x00;
  45. }
  46. }
  47. void Key(u8 dat)
  48. {
  49. if(K1==0)
  50. {
  51.   delay(1000);
  52.   if(K1==0)
  53.         {                At24CO2Write(dat,1);
  54.                         led =~led;
  55.         }
  56.   while(!K1);
  57. }
  58. if(K2==0)
  59. {
  60.   delay(1000);
  61.   if(K2==0)
  62.         {
  63.                 num=At24CO2Read(1);
  64.                 led =~led;
  65.         }
  66.   while(!K2);
  67. }
  68. if(K3==0)
  69. {
  70.   delay(1000);
  71.   if(K3==0)
  72.   num++;
  73.   while(!K3);
  74. }
  75. if(K4==0)
  76. {
  77.   delay(1000);
  78.   if(K4==0)
  79.   num=0;
  80.   while(!K4);
  81. }
  82. }
  83. void change()
  84. {
  85.    display[0]=numer[num/1000];
  86.          display[1]=numer[(num%1000)/100];
  87.          display[2]=numer[(num%100)/10];
  88.          display[3]=numer[num%10];
  89. }
  90. void main()
  91. {
  92. while(1)
  93. {
  94.    Key(num);
  95.    change();
  96.    shumaguan(display);
  97. }
  98. }


  99. void I2cStart() //开始函数,时钟信号始终为高,当数据线由高变低时开始
  100. {
  101.   SDA=1;
  102.   delay10us();
  103.   SCL=1;
  104.   delay10us();
  105.   SDA=0;
  106.   delay10us();
  107.   SCL=0;
  108.   delay10us();
  109. }
  110. void I2cStop()        //停止函数,时钟信号始终为高,当数据线由低变高时开结束
  111. {
  112.   SDA=0;
  113.   delay10us();
  114.   SCL=1;
  115.   delay10us();
  116.   SDA=1;
  117.   delay10us();
  118. }
  119. void I2cAck()
  120. {

  121.          SDA=0;
  122.          delay10us();
  123.          SCL=1;
  124.          delay10us();

  125.          SCL=0;
  126.          delay10us();
  127. }

  128. void nack()
  129. {
  130.         SDA = 1;        //拉高SDA,发送非应答信号
  131.         Delay();        
  132.         SCL = 1;        //拉高SCL
  133.         Delay();        
  134.         SCL = 0;        //再拉低完成非应答位,并保持住总线
  135. }

  136. u8 I2cSend(u8 dat)
  137. {
  138.         u8 i;
  139.         for(i=0x80; i!=0; i>>=1)        //从高位到低位依次进行
  140.         {
  141.                 if((dat&i) == 0)        //该位的值依次输出到SDA上
  142.                         SDA = 0;
  143.                 else
  144.                         SDA = 1;
  145.                 delay10us();
  146.                 SCL = 1;        //拉高SCL
  147.                 delay10us();
  148.                 SCL = 0;        //再拉低SCL完成一个位周期
  149.         }

  150. }
  151. u8 I2cRead()
  152. {
  153.          u8 i, dat;
  154.         
  155.         SDA = 1;        //确保主机释放SDA
  156.         for(i=0x80; i!=0; i>>=1)        //从高位到低位依次进行
  157.         {
  158.                 delay10us();
  159.                 SCL = 1;        //拉高SCL
  160.                 if(SDA == 0)        //读取SDA的值
  161.                         dat &= ~i;        //为0时,dat中对应位清零
  162.                 else
  163.                         dat |= i;        //为1时,dat中对应位置1
  164.                 delay10us();
  165.                 SCL = 0;        //再拉低SCL使从机发送出下一位
  166.         }
  167.         return dat;

  168. }
  169. void At24CO2Write(u8 dat,u8 addr)
  170. {
  171.    I2cStart();
  172.    I2cSend(0xa0);
  173.          I2cAck();
  174.    I2cSend(addr);
  175.          I2cAck();
  176.    I2cSend(dat);
  177.          I2cAck();
  178.    I2cStop();
  179. }
  180. u8 At24CO2Read(u8 addr)
  181. {
  182.    u8 num;
  183.    I2cStart();
  184.    I2cSend(0xa0);
  185.          I2cAck();
  186.    I2cSend(addr);
  187.          I2cAck();
  188.    I2cStart();
  189.    I2cSend(0xa1);
  190.          I2cAck();
  191.    num=I2cRead();
  192. //         nack();
  193.    I2cStop();
  194.    return num;
  195. }



复制代码
Keil代码与Proteus仿真下载: 实验4.7z (73.56 KB, 下载次数: 12)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表