0.png (41.22 KB, 下載次數: 106)
下載附件
2017-7-29 22:18 上傳
包含:
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)
2017-7-29 11:20 上傳
點擊文件名下載附件
AM2320_I2C.C;AM2320_I2C.h 下載積分: 黑幣 -5
|