找回密码
 立即注册

QQ登录

只需一步,快速开始

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

AM2320_I2C温湿度51单片机程序

  [复制链接]
跳转到指定楼层
楼主

包含:
AM2320_I2C.C文件
AM2320_I2C.h头文件

51单片机源程序如下:
  1. //****************************************************************//
  2. //               AM系列读IIC使用范例
  3. //单片机 :AT89S52 或 STC89C52RC
  4. // 功能  :串口发送温湿度数据  波特率 9600
  5. // 晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
  6. // 编译环境:  Keil3
  7. // 公司  :奥松电子   
  8. //****************************************************************//

  9. #include "STC15W4K.h"
  10. #include "AM2320_I2C.h"
  11. #include <intrins.h>

  12. //端口位定义,可修改
  13. //sbit AM2320_SDA = P3^4;
  14. //sbit AM2320_SCL = P3^5;
  15. //器件地址
  16. #define IIC_Add 0xB8
  17. #define IIC_RX_Length 8
  18. //内部数据定义
  19. unsigned char idata IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令(无CRC校验)
  20. unsigned char idata IIC_RX_Buffer[IIC_RX_Length] = {0x00};//读回的温湿度

  21. unsigned char *String;
  22. unsigned char WR_Flag;

  23. //***************************************************
  24. void delay10us()                //@18.432MHz这个延时函数 要大于5US以上
  25. {
  26.         unsigned char i;

  27.         _nop_();
  28.         _nop_();
  29.         i = 43;
  30.         while (--i);
  31. }
  32. //***************************************************
  33. void Delay2ms()                //@18.432MHz
  34. {
  35.         unsigned char i, j;

  36.         i = 36;
  37.         j = 217;
  38.         do{
  39.                 while (--j);
  40.         } while (--i);
  41. }
  42. //**********************************************
  43. //送起始位 AM2320_SDA =1->0
  44. void I2C_Start()
  45. {
  46.   AM2320_SDA =1;
  47.   AM2320_SCL=1;
  48.   delay10us();
  49.   AM2320_SDA =0;
  50.   delay10us();
  51.   AM2320_SCL=0;
  52. }
  53. //************************************************
  54. //送停止位 AM2320_SDA =0->1
  55. void I2C_Stop()
  56. {
  57.    AM2320_SDA =0;
  58.    delay10us();
  59.    AM2320_SCL=1;
  60.    delay10us();
  61.    AM2320_SDA =1;
  62. }
  63. //************************************************
  64. //主应答(包含ack:AM2320_SDA =0和no_ack:AM2320_SDA =0)
  65. void Ack()
  66. {  
  67.    AM2320_SDA =0;//设置AM2320_SDA  口为输出
  68.    AM2320_SCL=0;
  69.    delay10us();
  70.    AM2320_SCL=1;
  71.    delay10us();        
  72.    AM2320_SCL=0;
  73.    AM2320_SDA =1;
  74. }
  75. //***************************************************
  76. void NoAck()
  77. {  
  78.    AM2320_SDA =1;  //设置AM2320_SDA  口为输出
  79.    AM2320_SCL=0;
  80.    delay10us();
  81.    AM2320_SCL=1;
  82.    delay10us();
  83.    AM2320_SDA =1;
  84.    AM2320_SCL=0;
  85. }
  86. //***************************************************
  87. // 检测 AM2320_SDA 是否回ACK
  88. bit Test_Ack()
  89. {  //设置AM2320_SDA 口为输入
  90.    bit ACK_Flag=0;
  91.    AM2320_SCL=0;
  92.    AM2320_SDA =1;   
  93.    delay10us();
  94.    AM2320_SCL=1;
  95.    delay10us();
  96.    if(AM2320_SDA ==0) ACK_Flag = 1;
  97.    else ACK_Flag = 0;
  98.    AM2320_SCL=0;
  99.    return ACK_Flag;
  100. }
  101. //*************************************************
  102. //字节发送程序
  103. //发送c(可以是数据也可是地址),送完后接收从应答
  104. //不考虑从应答位
  105. void SendData(unsigned char buffer)
  106. {
  107.    unsigned char BitCnt=8;//一字节8位
  108.    //设置AM2320_SDA  口为输出
  109.    do{
  110.            AM2320_SCL=0;
  111.           delay10us();
  112.       if((buffer&0x80)==0) AM2320_SDA =0;//判断最高位是0还是1
  113.       else AM2320_SDA =1;
  114.       AM2320_SCL=1;
  115.           delay10us();
  116.       buffer=buffer<<1;//将buffer中的数据左移一位
  117.       BitCnt--;
  118.    }
  119.    while(BitCnt);
  120.    AM2320_SCL=0;        
  121. }
  122. //**************************************************
  123. //字节接收程序
  124. //接收器件传来的数据,此程序应配合|主应答函数|i2c_ack_main()使用
  125. //return: uchar型1字节
  126. unsigned char ReceiveData()
  127. {
  128.   unsigned char BitCnt=8,IIC_RX_Data=0;
  129.   unsigned char temp=0;
  130.   AM2320_SDA =1;           //读入数据 设置AM2320_SDA  口为输入
  131.   do{
  132.      AM2320_SCL=0;
  133.          delay10us();  
  134.          IIC_RX_Data=_crol_(IIC_RX_Data,1);   //数据左移一位
  135.          BitCnt--;         
  136.          AM2320_SCL=1;
  137.          delay10us();
  138.      if(AM2320_SDA ==1) IIC_RX_Data = IIC_RX_Data|0x01;  //低位置1
  139.      else IIC_RX_Data = IIC_RX_Data&0x0fe; //低位清0            
  140.    }
  141.    while(BitCnt);
  142.    AM2320_SCL=0;
  143.    return IIC_RX_Data;
  144. }
  145. //***************************************************
  146. bit WriteNByte(unsigned char sla,unsigned char *ss,unsigned char nn)
  147. {
  148.    unsigned char ii;
  149.    
  150.    I2C_Start();  //启动I2C
  151.    SendData(sla);//发送器件地址
  152.    if(!Test_Ack()){        
  153.       WR_Flag = 1;
  154.           return(0);
  155.    }
  156.    for(ii=0;ii<nn;ii++){//写入8字节数据
  157.       SendData(*(ss+ii));
  158.           if(!Test_Ack()){
  159.             WR_Flag = 1;
  160.                 return(0);
  161.           }
  162.    }
  163.    I2C_Stop();
  164.    return(1);
  165. }
  166. //***************************************************
  167. bit ReadNByte(unsigned char Sal, unsigned char *pp,unsigned char nn)
  168. {
  169.   unsigned char ii;

  170.   I2C_Start();    // 启动I2C
  171.   SendData((Sal)| 0x01); //发送器件地址
  172.   if(!Test_Ack()){
  173.           WR_Flag = 1;
  174.         return(0);
  175.   }
  176.   delay10us();  
  177.   delay10us();
  178.   delay10us(); // 延时时间必须大于30us 只要大于 30us 以上的值都可以 但是最好不要太长 ,测试时,试过25MS都OK!
  179.         
  180.   for(ii=0;ii<nn-1;ii++){  //读取字节数据
  181.      *(pp+ii)=ReceiveData(); //读取数据
  182.      Ack();
  183.   }
  184.   *(pp+nn-1)=ReceiveData();        
  185.   NoAck();
  186.   I2C_Stop();
  187.   return(1);         
  188. }
  189. //***************************************************
  190. ///计算CRC校验码        
  191. unsigned int CRC16(unsigned char *ptr, unsigned char len)
  192. {
  193.    unsigned int crc=0xffff;
  194.    unsigned char i;
  195.    while(len--){
  196.        crc ^=*ptr++;
  197.        for(i=0;i<8;i++){
  198.                if(crc & 0x1){
  199.                       crc>>=1;
  200.                           crc^=0xa001;
  201.                    }
  202.                    else{
  203.                       crc>>=1;
  204.                    }
  205.            }
  206.    }
  207.    return crc;
  208. }
  209. //***************************************************
  210. ///检测CRC校验码是否正确
  211. unsigned char CheckCRC(unsigned char *ptr,unsigned char len)
  212. {
  213.   unsigned int crc;
  214.         crc=(unsigned int)CRC16(ptr,len-2);
  215.         if(ptr[len-1]==(crc>>8) && ptr[len-2]==(crc & 0x00ff)) return 0xff;
  216.         else return 0x0;
  217. }
  218. //***************************************************
  219. void Waken()
  220. {

  221.         I2C_Start();       // 启动I2C
  222.         SendData(IIC_Add); // 发送器件地址
  223.         Test_Ack();               // 唤醒指令时 传感器不会回ACK 但是第一定要发检测ACK的时钟 否则会出错
  224.         Delay2ms();       // 至少延时1个Ms        说明书里,有个最大值 ,实际当中 你只要大于1MS
  225. ……………………

  226. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
AM2320_I2C.zip (2.68 KB, 下载次数: 155)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:228391 发表于 2017-8-19 14:32 | 只看该作者
谢谢分享3333333333333
回复

使用道具 举报

板凳
ID:246282 发表于 2017-12-15 20:27 | 只看该作者
谢谢分享,用89C52RC可以,但是换了12C5A60S2或者STC15就是怎么也不行,正好对照一下试试。
回复

使用道具 举报

地板
ID:195568 发表于 2017-12-27 11:43 | 只看该作者
谢谢分享,我学习一下
回复

使用道具 举报

5#
ID:267777 发表于 2017-12-27 15:39 | 只看该作者
谢谢分享,学习了 哈哈哈
回复

使用道具 举报

6#
ID:156204 发表于 2018-5-10 16:29 | 只看该作者
下载不了了,币也扣了
回复

使用道具 举报

7#
ID:437789 发表于 2018-12-23 15:32 | 只看该作者
学习了。
回复

使用道具 举报

8#
ID:471763 发表于 2019-1-22 18:06 | 只看该作者
好好学习一下
回复

使用道具 举报

9#
ID:364538 发表于 2019-2-24 10:46 | 只看该作者
程序不完整样的。
回复

使用道具 举报

10#
ID:484008 发表于 2019-3-4 08:46 | 只看该作者
谢谢分享
回复

使用道具 举报

11#
ID:581122 发表于 2019-7-9 18:38 | 只看该作者
谢谢分享,很有用的资源
回复

使用道具 举报

12#
ID:407603 发表于 2019-8-6 15:06 | 只看该作者
下来看看 正好有要用到
回复

使用道具 举报

13#
ID:970754 发表于 2021-10-9 15:58 | 只看该作者
为什么发送和接收数据要左移
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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