實驗平臺:普中A2開發板,STC89C51RC芯片,11.0592M晶振,
文章目錄
- 前言
- 一、模塊圖
- 二、代碼
- 1.main.c
- 2.PCF8591.c
- 3.PCF8591.h
- 總結
前言
本文就介紹PCF8591模塊的使用,
PCF8591使用IIC通信協議,模塊上自帶“可調電阻輸入、光敏電阻輸入、熱敏電阻輸入”,
一、模塊圖

引腳說明:
- INPUT0:與可調電阻相連
- INPUT1:與光敏電阻相連
- INPUT3:與熱敏電阻相連
- AIN0:芯片的模擬量輸入口0,地址0x40
- AIN1:芯片的模擬量輸入口1,地址0x41
- AIN2:芯片的模擬量輸入口2,地址0x42
- AIN3:芯片的模擬量輸入口3,地址0x43
使用模塊上模擬量作為輸入:
- 當選擇用數碼管顯示可調電阻的模擬電壓值時,需要用跳線帽將AIN0與INPUT0短接;
使用外部模擬量作為輸入:
- 若4個通道都使用外部模擬量輸入,則將4個外部模擬量接在AIN0—AIN3上即可,
二、代碼
1.main.c
代碼如下:
/**************************************************************************************
實驗平臺:普中A2開發板(STC89C51RC芯片)
PCF8591模塊
試驗現象:數碼管顯示采集到的模擬量(范圍0-255)
***************************************************************************************/
#include "reg52.h" //此檔案中定義了單片機的一些特殊功能暫存器
#include <SelfDef.h>
#include <PCF8591.h>
#include <LedDisplay.h>
/*******************************************************************************
* 函 數 名 : main
* 函式功能 : 主函式
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void main()
{
u8 dat=0;
u8 disp[8];
while(1)
{
//0x40、0x41、0x42、0x43,分別為四個模擬量通道地址
dat=ReadPCF8591(0x43);
datapros(disp,dat);
DigDisplay(disp);
}
}
2.PCF8591.c
代碼如下:
/***************************************************************************************/
/**此部分為I2C總線的驅動程式*********************************/
/**適用平臺:普中A2開發板,STC89CXX芯片,晶振11.0592M*********/
/**模塊使用說明:INPUT0、INPUT1、INPUT2分別為可調電阻、光敏、熱敏電阻
AIN0、AIN1、AIN2、AIN3分別為地址0x40-0x43的地址輸入
當使用可調電阻作為模擬量輸入時,需將AIN0與INPUT0用跳線帽短接即可*/
#include <PCF8591.h>
bit ack; /*應答標志位*/
u8 disp[8];
/*******************************************************************************
* 函式名 : Delay6us()
* 函式功能 : 軟體延時
*******************************************************************************/
void Delay6us() //@11.0592MHz
{
_nop_();
}
/*******************************************************************************
* 函式名 : Start_I2c()
* 函式功能 : 啟動I2C總線,即發送I2C起始條件.
* 備注 : 起始之后SDA和SCL都為0
*******************************************************************************/
void Start_I2c()
{
SDA=1; /*發送起始條件的資料信號*/
Delay6us();
SCL=1;
Delay6us(); /*起始條件建立時間大于4.7us,延時*/
SDA=0; /*發送起始信號*/
Delay6us();
SCL=0; /*鉗住SCL總線,準備發送或接收資料 */
Delay6us();
}
/*******************************************************************************
* 函式名 : Stop_I2c()
* 函式功能 : 結束總線函式
*******************************************************************************/
void Stop_I2c()
{
SDA=0; /*發送結束條件的資料信號*/
Delay6us();
SCL=1; /*結束條件建立時間>4μs*/
Delay6us();
SDA=1; /*發送I2C總線結束信號*/
Delay6us(); /*保持時間>4.7μs*/
}
/*******************************************************************************
* 函式名 : SendByte(u8 c)
* 函式功能 : 位元組資料發送函式
* 輸入 : 要發送的位元組chr
* 注意 :將資料c發送出去,可以是地址,也可以是資料,發完后等待應答,并對
此狀態位進行操作(不應答或非應答都使ack=0,發送資料正常,ack=1)
注意此函式對延時精度要求較高,多檢查此處
*******************************************************************************/
void SendByte(u8 chr)
{
u8 i;
for(i=0;i<8;i++) /*要傳送的資料長度為8位*/
{
if((chr<<i)&0x80)
SDA=1; /*判斷發送位*/
else
SDA=0;
Delay6us();
SCL=1; /*置時鐘線為高,通知被控器開始接收資料位*/
Delay6us(); /*保證時鐘高電平周期大于4μs*/
SCL=0;
}
Delay6us();
SDA=1; /*8位發送完后釋放資料線,準備接收應答位*/
Delay6us();
SCL=1;
Delay6us();
if(SDA==1)
ack=0;
else
ack=1; /*判斷是否接收到應答信號,1表示收到應答*/
SCL=0;
Delay6us();
}
/*******************************************************************************
* 函式名 : RcvByte()
* 函式功能 : 位元組資料接收函式
*******************************************************************************/
u8 RcvByte()
{
u8 retc;
u8 i;
retc=0;
SDA=1; /*置資料線為輸入方式*/
for(i=0;i<8;i++)
{
SCL=0; /*置時鐘線為低,準備接收資料位*/
Delay6us(); /*時鐘低電平周期大于4.7μs*/
SCL=1; /*置時鐘線為高使資料線上資料有效*/
Delay6us();
retc=retc<<1;
if(SDA==1)
retc=retc+1; /*讀資料位,接收的資料位放入retc中 */
Delay6us();
}
SCL=0;
Delay6us();
return retc;
}
/********************************************************************
*函式名 : void Ack_I2c(bit a);
*函式功能 : 應答子函式,主控器進行應答信號
(可以是應答或非應答信號,由位引數a決定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)
SDA=0; /*在此發出應答或非應答信號 */
else
SDA=1;
Delay6us();
SCL=1;
Delay6us(); /*時鐘低電平周期大于4μs*/
SCL=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/
Delay6us();
}
/*******************************************************************************
* 函式名 : ISendByte(u8 sla,u8 c)
* 函式功能 : ADC發送位元組[命令]資料函式
*******************************************************************************/
bit ISendByte(u8 sla,u8 c)
{
Start_I2c(); //啟動總線
SendByte(sla); //發送器件地址
if(ack==0)
return 0;
SendByte(c); //發送資料
if(ack==0)
return 0;
Stop_I2c(); //結束總線
return 1;
}
/*******************************************************************************
* 函式名 : IRcvByte(u8 sla)
* 函式功能 : ADC讀位元組資料函式
*******************************************************************************/
u8 IRcvByte(u8 sla)
{
u8 c;
Start_I2c(); //啟動總線
SendByte(sla+1); //發送器件地址
if(ack==0)
return 0;
c=RcvByte(); //讀取資料0
Ack_I2c(1); //發送非就答位
Stop_I2c(); //結束總線
return c;
}
/*******************************************************************************
* 函式名 : ReadPCF8591(u8 address)
* 函式功能 : 讀取PCF8591資料 ,address為要讀取的地址
* 注意 :0x40、0x41、0x42、0x43分別為可調電阻、光敏電阻、熱敏電阻、懸空
*******************************************************************************/
u8 ReadPCF8591(u8 address)
{
ISendByte(PCF8591,address);
return IRcvByte(PCF8591);
}
/***********************************驅動程式結束****************************************/
3.PCF8591.h
代碼如下:
#ifndef __PCF8591_H_
#define __PCF8591_H_
#include <reg52.h>
#include <SelfDef.h>
#include <intrins.h>
#define PCF8591 0x90 //PCF8591 地址
sbit SCL=P2^0; //I2C 時鐘
sbit SDA=P2^1; //I2C 資料
void Start_I2c();
void Stop_I2c();
void Ack_I2c(bit a);
void SendByte(u8 c);
bit ISendByte(u8 sla,u8 c);
u8 RcvByte();
u8 IRcvByte(u8 sla);
u8 ReadPCF8591(u8 address);
#endif
該處使用的url網路請求的資料,
總結
提示:這里對文章進行總結:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/413605.html
標籤:其他
上一篇:【樹莓派筆記】USB口供電能力
