找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC单片机读取LM75A温度的代码,以及ADC读取电压。给大家分享一下把

[复制链接]
ID:475845 发表于 2020-4-29 09:31 | 显示全部楼层 |阅读模式

我用的是STC8A8K64S4A12这一款单片机,模拟I2C读取温度,以及ADC读取电阻分压后电压计算

LM75A


  1. #include"main.h"

  2. char xdata temp_[3];   //
  3. char xdata test[15];

  4. bit        temp_flag;

  5. void Delay_us(int i)   //iic延时            
  6. {
  7. int j;
  8. for(j=0;j<i;j++);
  9. }

  10. void IIC_init(void)    //iic初始化
  11. {
  12.                 SCL = 1;
  13.                 Delay_us(5);
  14.                 SDA = 1;
  15.                 Delay_us(5);
  16. }

  17. void iic_start(void)         //iic通信起始信号
  18. {
  19.             SDA = 1;
  20.           Delay_us(2);
  21.       SCL = 1;
  22.           Delay_us(2);
  23.       SDA = 0;
  24.           Delay_us(2);  
  25. }

  26. void iic_stop(void)                 //iic通信终止信号
  27. {
  28.                         SDA = 0;
  29.           Delay_us(2);
  30.       SCL = 1;
  31.           Delay_us(2);
  32.       SDA =1;
  33. }

  34. void iic_ack(void)     //发送应答信号函数                 
  35. {
  36.                         SCL = 0;
  37.       SDA = 0;
  38.           Delay_us(2);
  39.       SCL = 1;
  40.           Delay_us(2);  
  41.       SCL = 0;
  42.           Delay_us(1);
  43.       SDA = 1;
  44. }

  45. void read_ack(void)    //iic应答函数                  
  46. {  
  47.       SCL = 0;
  48.           Delay_us(2);   
  49.       SDA = 1;
  50.       SCL = 1;
  51.           Delay_us(2);
  52.       SCL = 0;  
  53. }

  54. void iic_nack()        //iic非应答函数               
  55. {   
  56.       SDA = 1;
  57.           Delay_us(2);      
  58.       SCL = 1;
  59.           Delay_us(2);      
  60.                         SCL = 0;
  61. }

  62. u8 get_byte(void)         //输入一个字节                           
  63. {
  64.     u8 dd;
  65.     int i;
  66.    
  67.     dd=0;
  68.            SDA = 1;
  69.         for (i=0; i<8; i++)
  70.     {
  71.                  Delay_us(1);
  72.          SCL = 0;
  73.                  Delay_us(5);
  74.          SCL = 1;
  75.                  Delay_us(2);
  76.          dd<<=1;
  77.                  if (SDA)
  78.                     dd|=0x01;
  79.                  Delay_us(1);
  80.     }         
  81.     SCL = 0;
  82.         Delay_us(1);
  83.         return dd;
  84. }

  85. void out_byte(u8 dd)      //输出一个字节              
  86. {
  87.     u8 i;

  88.     for(i=0;i<8;i++)
  89.     {  
  90.           SCL = 0;
  91.                   Delay_us(0);                        
  92.           SDA = (dd & 0x80)>>7;
  93.                   Delay_us(2);         
  94.           SCL = 1;
  95.                   Delay_us(3);
  96.           dd <<= 1;
  97.     }
  98.         SCL = 0;   
  99. }

  100. //写入器件地址和所需读取寄存器的地址
  101. void iic_write_addr(u8 addr,u8 data_addr)
  102. {
  103.             iic_start();
  104.       out_byte(addr);
  105.       read_ack();   
  106.       out_byte(data_addr);
  107.       read_ack();            
  108. }

  109. //iic总线读取多个数据
  110. void IICA_Read(u8 id, u8 addr, u8 *p, u16 len)
  111. {                                                   
  112.          int i;
  113.          bit EA_SAVE = EA;

  114.              EA = 0;
  115.               iic_write_addr(id|0,addr);  
  116.               iic_start();
  117.               out_byte(id|1);
  118.               read_ack();     
  119.               for (i=0;i<len;i++)
  120.                {
  121.                          *p++ = get_byte();
  122.                           if (i!=(len-1))
  123.                                          iic_ack();                 
  124.                }      
  125.              iic_nack();        
  126.                iic_stop();
  127.               EA = EA_SAVE;
  128. }

  129. //读取并计算当前温度
  130. void readTemperature()
  131. {
  132.         u8 id=0x90;          //设备地址
  133.         u8 addr=0x00;        //温度寄存器地址
  134.         u32        temp_high;        //储存高字节
  135.         u8        temp_low;         //储存低字节
  136.         u8 temp[2]={0};      

  137.   u8 a = 0;
  138.         
  139.         IICA_Read(id,addr,temp,2);      //将温度的两个字节存到temp中

  140.         temp_high = temp[0];                                //温度高
  141.         temp_low = temp[1];                                //温度低
  142.         
  143.         temp_high = (temp_high << 8) + temp_low;
  144.         temp_high = temp_high >> 5;
  145.         
  146.         memset(test,0,sizeof(test));
  147.         
  148.         if((temp_high & 0x0400) == 0x0400)
  149.                 test[a++] = '-';
  150.         else
  151.                 test[a++] = '+';
  152.         
  153.         temp_high = temp_high * 125;
  154.         
  155.         if(temp_high >= 25500)
  156.                 temp_flag = 1;
  157.         
  158.         if(temp_high >= 100000)
  159.                 test[a++] = temp_high / 100000 % 10 + '0';
  160.         
  161.         test[a++] = temp_high / 10000 % 10 + '0';
  162.         test[a++] = temp_high / 1000 % 10 + '0';
  163.         test[a++] = '.';
  164.         test[a++] = temp_high / 100 % 10 + '0';
  165.         test[a++] = temp_high % 100 / 10 + '0';
  166.         test[a++] = temp_high % 10 + '0';
  167.         test[a++] = 'C'; //℃
  168. }

复制代码
ADC


  1. #include"main.h"

  2. char xdata AD1_V[7];

  3. extern bit voltage_flag;

  4. void adc_init(void)
  5. {
  6.     P1M0 &= 0x7F;                               //设置P1.7为ADC口
  7.     P1M1 |= 0x80;

  8.     ADCCFG = 0x21;                              //设置ADC时钟为系统时钟/2/16/16
  9.     ADC_CONTR = 0x80;                           //使能ADC模块
  10. }

  11. int adcread()
  12. {
  13.         int res;
  14.         ADC_CONTR |= 0x47;                      //启动AD转换P17
  15.         _nop_();
  16.         _nop_();
  17.         while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
  18.         ADC_CONTR &= ~0x20;                     //清完成标志
  19.         res = ADC_RES;
  20.         res = (res << 8) + ADC_RESL;          //读取ADC结果
  21.                
  22.         return res;
  23. }

  24. void adc_test(void)
  25. {
  26.         u32 AD1;
  27.         char a=0;
  28.         
  29.         AD1 = adcread();       //P17
  30.         
  31.         AD1 = AD1 * 86813;       //3555/4095
  32.         //AD1 = AD1 * 43596;       //3555/4095
  33.         AD1 = AD1 / 100000;
  34.         AD1 = (AD1 *115) / 15;  //11.5= R1+R2 分压
  35.         AD1 = AD1 / 10;
  36.         
  37.         if(AD1 <= 2000)        //主板供电电压小于20V报警
  38.                 voltage_flag = 1;
  39.         
  40.         memset(AD1_V,0,sizeof(AD1_V));  //清buff,防止小于10V时会出现两个V
  41.          
  42.         if(AD1 >= 1000)
  43.                 AD1_V[a++] = AD1 / 1000 % 10 + '0';

  44.         
  45.         AD1_V[a++] = AD1 / 100 % 10 + '0';
  46.         AD1_V[a++] = '.';
  47.         AD1_V[a++] = AD1 % 100 / 10 + '0';
  48.         AD1_V[a++] = AD1 % 10 + '0';
  49.         AD1_V[a++] = 'V';

  50. }
复制代码



以上代码: i2c,adc.rar (2.34 KB, 下载次数: 32)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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