找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1062|回复: 0
打印 上一主题 下一主题
收起左侧

单片机货车超重检车程序

[复制链接]
跳转到指定楼层
楼主
ID:671007 发表于 2019-12-23 10:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C语言程序
  1. #include <AT89X52.h>
  2. #include <intrins.h>
  3. #include <stdio.h>


  4. #define R24C04ADD 0xA1
  5. #define W24C04ADD 0xA0

  6. //ADC0832的引脚
  7. sbit ADCS =P2^2;  //ADC0832 chip seclect
  8. sbit ADDI =P2^4;  //ADC0832 k in
  9. sbit ADDO =P2^4;  //ADC0832 k out
  10. sbit ADCLK =P2^3;  //ADC0832 clock signal


  11. sbit SDA = P2 ^ 1;                                //数据线
  12. sbit SCL = P2 ^ 0;                                //时钟线
  13. bit bAck;                                          //应答标志 当bbAck=1是为正确的应答

  14. unsigned char dispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f};  //位扫描
  15. unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};  //共阳数码管字段码
  16. unsigned char dispbuf[4];
  17. unsigned int temp;
  18. unsigned char getdata; //获取ADC转换回来的值


  19. void delay_1ms(void)  //12mhz delay 1.01ms
  20. {
  21.    unsigned char x,y;   
  22.    x=3;
  23.    while(x--)
  24.   {
  25.        y=40;
  26.        while(y--);
  27.     }
  28. }
  29. void display(void)  //数码管显示函数
  30. {
  31.   char k;
  32.   for(k=0;k<4;k++)
  33.   {

  34.   P1 = dispbitcode[k];
  35.   P0 = dispcode[dispbuf[k]];
  36.   if(k==1)          //加上数码管的dp小数点
  37.           P0&=0x7f;
  38.   delay_1ms();         
  39.   }
  40. }

  41. /************
  42. 读ADC0832函数
  43. ************/

  44. //采集并返回
  45. unsigned int Adc0832(unsigned char channel)     //AD转换,返回结果
  46. {
  47.     unsigned char i=0;
  48.     unsigned char j;
  49.     unsigned int dat=0;
  50.     unsigned char ndat=0;

  51.     if(channel==0)channel=2;
  52.     if(channel==1)channel=3;
  53.     ADDI=1;
  54.     _nop_();
  55.     _nop_();
  56.     ADCS=0;//拉低CS端
  57.     _nop_();
  58.     _nop_();
  59.     ADCLK=1;//拉高CLK端
  60.     _nop_();
  61.     _nop_();
  62.     ADCLK=0;//拉低CLK端,形成下降沿1
  63.     _nop_();
  64.     _nop_();
  65.     ADCLK=1;//拉高CLK端
  66.     ADDI=channel&0x1;
  67.     _nop_();
  68.     _nop_();
  69.     ADCLK=0;//拉低CLK端,形成下降沿2
  70.     _nop_();
  71.     _nop_();
  72.     ADCLK=1;//拉高CLK端
  73.     ADDI=(channel>>1)&0x1;
  74.     _nop_();
  75.     _nop_();
  76.     ADCLK=0;//拉低CLK端,形成下降沿3
  77.     ADDI=1;//控制命令结束
  78.     _nop_();
  79.     _nop_();
  80.     dat=0;
  81.     for(i=0;i<8;i++)
  82.     {
  83.         dat|=ADDO;//收数据
  84.         ADCLK=1;
  85.         _nop_();
  86.         _nop_();
  87.         ADCLK=0;//形成一次时钟脉冲
  88.         _nop_();
  89.         _nop_();
  90.         dat<<=1;
  91.         if(i==7)dat|=ADDO;
  92.     }  
  93.     for(i=0;i<8;i++)
  94.     {
  95.         j=0;
  96.         j=j|ADDO;//收数据
  97.         ADCLK=1;
  98.         _nop_();
  99.         _nop_();
  100.         ADCLK=0;//形成一次时钟脉冲
  101.         _nop_();
  102.         _nop_();
  103.         j=j<<7;
  104.         ndat=ndat|j;
  105.         if(i<7)ndat>>=1;
  106.     }
  107.     ADCS=1;//拉低CS端
  108.     ADCLK=0;//拉低CLK端
  109.     ADDO=1;//拉高数据端,回到初始状态
  110.     dat<<=8;
  111.     dat|=ndat;
  112.     return(dat);            //return ad k
  113. }

  114. //启动I2C总线,即发送起始条件
  115. void StartI2C()
  116. {
  117.         SDA = 1;                              //发送起始条件数据信号
  118.         _nop_();
  119.         SCL = 1;
  120.         _nop_();                                    //起始建立时间大于4.7us
  121.         _nop_();
  122.         _nop_();
  123.         _nop_();
  124.         _nop_();
  125.         SDA = 0;                              //发送起始信号
  126.         _nop_();
  127.         _nop_();
  128.         _nop_();
  129.         _nop_();
  130.         _nop_();
  131.         SCL = 0;                                //时钟操作
  132.         _nop_();
  133.         _nop_();
  134. }
  135. //结束I2C总线,即发送I2C结束条件
  136. void StopI2C()
  137. {
  138.         SDA = 0;                                //发送结束条件的数据信号
  139.         _nop_();                                      //发送结束条件的时钟信号
  140.         SCL = 1;                                //结束条件建立时间大于4us
  141.         _nop_();
  142.         _nop_();
  143.         _nop_();
  144.         _nop_();
  145.         _nop_();
  146.         SDA = 1;                                //发送I2C总线结束命令
  147.         _nop_();
  148.         _nop_();
  149.         _nop_();
  150.         _nop_();
  151.         _nop_();        
  152. }
  153. //发送一个字节的数据
  154. void        SendByte(unsigned char c)
  155. {
  156.         unsigned char BitCnt;
  157.         for(BitCnt = 0;BitCnt < 8;BitCnt++)                                  //一个字节
  158.                 {
  159.                         if((c << BitCnt)& 0x80) SDA = 1;                   //判断发送位
  160.                         else        SDA = 0;
  161.                         _nop_();
  162.                         SCL = 1;                              //时钟线为高,通知从机开始接收数据
  163.                         _nop_();
  164.                         _nop_();
  165.                         _nop_();
  166.                         _nop_();
  167.                         _nop_();
  168.                         SCL = 0;
  169.                 }
  170.         _nop_();
  171.         _nop_();
  172.         SDA = 1;                                                //释放数据线,准备接受应答位
  173.         _nop_();
  174.         _nop_();
  175.         SCL = 1;
  176.         _nop_();
  177.         _nop_();
  178.         _nop_();
  179.         if(SDA == 1) bAck =0;
  180.         else bAck = 1;                                                //判断是否收到应答信号
  181.         SCL = 0;
  182.         _nop_();
  183.         _nop_();
  184. }
  185. //接收一个字节的数据
  186. unsigned char RevByte()
  187. {
  188.         unsigned char retc;
  189.         unsigned char BitCnt;
  190.         retc = 0;
  191.         SDA = 1;
  192.         for(BitCnt=0;BitCnt<8;BitCnt++)
  193.         {
  194.                 _nop_();
  195.                 SCL = 0;                                            //置时钟线为低,准备接收
  196.                 _nop_();
  197.                 _nop_();
  198.                 _nop_();
  199.                 _nop_();
  200.                 _nop_();
  201.                 SCL = 1;                                            //置时钟线为高使得数据有效
  202.                 _nop_();
  203.                 _nop_();
  204.                 retc = retc << 1;                                    //左移补零
  205.                 if (SDA == 1)
  206.                 retc = retc + 1;                                     //当数据为1则收到的数据+1
  207.                 _nop_();
  208.                 _nop_();
  209.         }
  210.         SCL = 0;
  211.         _nop_();
  212.         _nop_();
  213.         return(retc);                                   //返回收到的数据
  214. }

  215. //WChipAdd:写器件地址;RChipAdd:读器件地址;InterAdd:内部地址;如写正确则返回数据,
  216. //否则返回对应错误步骤序号
  217. //向指定器件的内部指定地址发送一个指定字节
  218. unsigned char WIICByte(unsigned char WChipAdd,unsigned char InterAdd,unsigned char WIICData)
  219. {
  220.         StartI2C();                                                                                      //启动总线
  221.         SendByte(WChipAdd);                                                        //发送器件地址以及命令
  222.         if (bAck==1)                                                                                          //收到应答
  223.         {
  224.                 SendByte(InterAdd);                                                                //发送内部子地址
  225.                 if (bAck ==1)
  226.                 {
  227.                         SendByte(WIICData);                                                        //发送数据
  228.                         if(bAck == 1)
  229.                         {
  230.                                 StopI2C();                    //停止总线
  231.                                 return(0xff);
  232.                         }
  233.                         else
  234.                         {
  235.                                 return(0x03);
  236.                         }                        
  237.                 }
  238.                 else
  239.                 {
  240.                         return(0x02);
  241.                 }
  242.         }
  243.         return(0x01);
  244. }
  245. //读取指定器件的内部指定地址一个字节数据
  246. unsigned char RIICByte(unsigned char WChipAdd,unsigned char RChipAdd,unsigned char InterDataAdd)
  247. {
  248.         unsigned char TempData;        
  249.         TempData = 0;
  250.         StartI2C();                                                                        //启动
  251.         SendByte(WChipAdd);                                                    //发送器件地址以及读命令
  252.         if (bAck==1)                                                                            //收到应答
  253.         {
  254.                 SendByte(InterDataAdd);                                        //发送内部子地址
  255.                 if (bAck ==1)
  256.                 {
  257.                         StartI2C();
  258.                         SendByte(RChipAdd);        
  259.                         if(bAck == 1)
  260.                         {
  261.                                 TempData = RevByte();       //接收数据
  262.                                 StopI2C();                  //停止I2C总线
  263.                                 return(TempData);           //返回数据
  264.                         }
  265.                         else
  266.                         {
  267.                                 return(0x03);
  268.                         }        
  269.                 }
  270.                 else
  271.                 {
  272.                         return(0x02);
  273.                 }
  274.         }
  275.         else
  276.         {
  277.                 return(0x01);
  278.         }
  279. }


  280. void main(void)
  281. {
  282.   unsigned int OverCounter = 0;
  283.   unsigned char ptemp;
  284.   bit OverFlg = 0;
  285.   unsigned int temp,ppress = 0;
  286.   float  press;        
  287.   while(1)
  288.   {         
  289.                      
  290.           getdata=Adc0832(0);
  291.           if(14<getdata<243)                                       //当压力值介于15kpa到115kpa之间时,遵循线性变换
  292.                  {                           
  293.                   int vary=getdata;                                                //y=(115-15)/(243-13)*X+15kpa                        
  294.                         press=((10.0/23.0)*vary)+9.3;                        //测试时补偿值为9.3                                                                                                         
  295.                         temp=(int)(press*10);                  //放大10倍,便于后面的计算
  296.       if(temp != ppress)
  297.       {
  298.         ppress = temp;
  299.         OverFlg = 1;
  300.       }                                                                                            
  301.                         dispbuf[3]=temp/1000;                                     //取压力值百位
  302.                         dispbuf[2]=(temp%1000)/100;                            //取压力值十位
  303.                         dispbuf[1]=((temp%1000)%100)/10;                    //取压力值个位
  304.                         dispbuf[0]=((temp%1000)%100)%10;                        //取压力值十分位
  305.                         display();
  306.       if (temp > 100)
  307.       {
  308.           if(OverFlg == 1)    //如果是新的一辆车通过
  309.           {
  310.             OverCounter++;
  311.             WIICByte(W24C04ADD,0x01,(OverCounter/0xff));    //低位
  312.             WIICByte(W24C04ADD,0x02,(OverCounter%0xff));    //高位
  313. //            ptemp = printf("%f\n",OverCounter);
  314.             OverFlg = 0;    //清除标志
  315.           }
  316.       }

  317.            }            
  318.   }
  319. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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