包含:
AM2320_I2C.C文件
AM2320_I2C.h头文件
51单片机源程序如下:
- //****************************************************************//
- // AM系列读IIC使用范例
- //单片机 :AT89S52 或 STC89C52RC
- // 功能 :串口发送温湿度数据 波特率 9600
- // 晶振 :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
- // 编译环境: Keil3
- // 公司 :奥松电子
- //****************************************************************//
- #include "STC15W4K.h"
- #include "AM2320_I2C.h"
- #include <intrins.h>
- //端口位定义,可修改
- //sbit AM2320_SDA = P3^4;
- //sbit AM2320_SCL = P3^5;
- //器件地址
- #define IIC_Add 0xB8
- #define IIC_RX_Length 8
- //内部数据定义
- unsigned char idata IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令(无CRC校验)
- unsigned char idata IIC_RX_Buffer[IIC_RX_Length] = {0x00};//读回的温湿度
- unsigned char *String;
- unsigned char WR_Flag;
- //***************************************************
- void delay10us() //@18.432MHz这个延时函数 要大于5US以上
- {
- unsigned char i;
- _nop_();
- _nop_();
- i = 43;
- while (--i);
- }
- //***************************************************
- void Delay2ms() //@18.432MHz
- {
- unsigned char i, j;
- i = 36;
- j = 217;
- do{
- while (--j);
- } while (--i);
- }
- //**********************************************
- //送起始位 AM2320_SDA =1->0
- void I2C_Start()
- {
- AM2320_SDA =1;
- AM2320_SCL=1;
- delay10us();
- AM2320_SDA =0;
- delay10us();
- AM2320_SCL=0;
- }
- //************************************************
- //送停止位 AM2320_SDA =0->1
- void I2C_Stop()
- {
- AM2320_SDA =0;
- delay10us();
- AM2320_SCL=1;
- delay10us();
- AM2320_SDA =1;
- }
- //************************************************
- //主应答(包含ack:AM2320_SDA =0和no_ack:AM2320_SDA =0)
- void Ack()
- {
- AM2320_SDA =0;//设置AM2320_SDA 口为输出
- AM2320_SCL=0;
- delay10us();
- AM2320_SCL=1;
- delay10us();
- AM2320_SCL=0;
- AM2320_SDA =1;
- }
- //***************************************************
- void NoAck()
- {
- AM2320_SDA =1; //设置AM2320_SDA 口为输出
- AM2320_SCL=0;
- delay10us();
- AM2320_SCL=1;
- delay10us();
- AM2320_SDA =1;
- AM2320_SCL=0;
- }
- //***************************************************
- // 检测 AM2320_SDA 是否回ACK
- bit Test_Ack()
- { //设置AM2320_SDA 口为输入
- bit ACK_Flag=0;
- AM2320_SCL=0;
- AM2320_SDA =1;
- delay10us();
- AM2320_SCL=1;
- delay10us();
- if(AM2320_SDA ==0) ACK_Flag = 1;
- else ACK_Flag = 0;
- AM2320_SCL=0;
- return ACK_Flag;
- }
- //*************************************************
- //字节发送程序
- //发送c(可以是数据也可是地址),送完后接收从应答
- //不考虑从应答位
- void SendData(unsigned char buffer)
- {
- unsigned char BitCnt=8;//一字节8位
- //设置AM2320_SDA 口为输出
- do{
- AM2320_SCL=0;
- delay10us();
- if((buffer&0x80)==0) AM2320_SDA =0;//判断最高位是0还是1
- else AM2320_SDA =1;
- AM2320_SCL=1;
- delay10us();
- buffer=buffer<<1;//将buffer中的数据左移一位
- BitCnt--;
- }
- while(BitCnt);
- AM2320_SCL=0;
- }
- //**************************************************
- //字节接收程序
- //接收器件传来的数据,此程序应配合|主应答函数|i2c_ack_main()使用
- //return: uchar型1字节
- unsigned char ReceiveData()
- {
- unsigned char BitCnt=8,IIC_RX_Data=0;
- unsigned char temp=0;
- AM2320_SDA =1; //读入数据 设置AM2320_SDA 口为输入
- do{
- AM2320_SCL=0;
- delay10us();
- IIC_RX_Data=_crol_(IIC_RX_Data,1); //数据左移一位
- BitCnt--;
- AM2320_SCL=1;
- delay10us();
- if(AM2320_SDA ==1) IIC_RX_Data = IIC_RX_Data|0x01; //低位置1
- else IIC_RX_Data = IIC_RX_Data&0x0fe; //低位清0
- }
- while(BitCnt);
- AM2320_SCL=0;
- return IIC_RX_Data;
- }
- //***************************************************
- bit WriteNByte(unsigned char sla,unsigned char *ss,unsigned char nn)
- {
- unsigned char ii;
-
- I2C_Start(); //启动I2C
- SendData(sla);//发送器件地址
- if(!Test_Ack()){
- WR_Flag = 1;
- return(0);
- }
- for(ii=0;ii<nn;ii++){//写入8字节数据
- SendData(*(ss+ii));
- if(!Test_Ack()){
- WR_Flag = 1;
- return(0);
- }
- }
- I2C_Stop();
- return(1);
- }
- //***************************************************
- bit ReadNByte(unsigned char Sal, unsigned char *pp,unsigned char nn)
- {
- unsigned char ii;
- I2C_Start(); // 启动I2C
- SendData((Sal)| 0x01); //发送器件地址
- if(!Test_Ack()){
- WR_Flag = 1;
- return(0);
- }
- delay10us();
- delay10us();
- delay10us(); // 延时时间必须大于30us 只要大于 30us 以上的值都可以 但是最好不要太长 ,测试时,试过25MS都OK!
-
- for(ii=0;ii<nn-1;ii++){ //读取字节数据
- *(pp+ii)=ReceiveData(); //读取数据
- Ack();
- }
- *(pp+nn-1)=ReceiveData();
- NoAck();
- I2C_Stop();
- return(1);
- }
- //***************************************************
- ///计算CRC校验码
- unsigned int CRC16(unsigned char *ptr, unsigned char len)
- {
- unsigned int crc=0xffff;
- unsigned char i;
- while(len--){
- crc ^=*ptr++;
- for(i=0;i<8;i++){
- if(crc & 0x1){
- crc>>=1;
- crc^=0xa001;
- }
- else{
- crc>>=1;
- }
- }
- }
- return crc;
- }
- //***************************************************
- ///检测CRC校验码是否正确
- unsigned char CheckCRC(unsigned char *ptr,unsigned char len)
- {
- unsigned int crc;
- crc=(unsigned int)CRC16(ptr,len-2);
- if(ptr[len-1]==(crc>>8) && ptr[len-2]==(crc & 0x00ff)) return 0xff;
- else return 0x0;
- }
- //***************************************************
- void Waken()
- {
- I2C_Start(); // 启动I2C
- SendData(IIC_Add); // 发送器件地址
- Test_Ack(); // 唤醒指令时 传感器不会回ACK 但是第一定要发检测ACK的时钟 否则会出错
- Delay2ms(); // 至少延时1个Ms 说明书里,有个最大值 ,实际当中 你只要大于1MS
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
AM2320_I2C.zip
(2.68 KB, 下载次数: 156)
|