|
物聯(lián)網(wǎng)相關(guān)實(shí)驗(yàn)代碼
源程序:
- /**********************************************************************************************************************************************************
- * 文 件 名:HumiTempLight.c
- ×
- * 功 能:實(shí)驗(yàn)十 SHT10溫濕度讀取、光照強(qiáng)度讀取
- *
- * SHT10 是一款高度集成的溫濕度傳感器芯片, 提供全標(biāo)定的數(shù)字輸出。它采用專利的CMOSens技術(shù),確保產(chǎn)品具有極高的可靠性與卓
- * 越的長期穩(wěn)定性。傳感器包括一個(gè)電容性聚合體測濕敏感元件、一個(gè)用能隙材料制成的測溫元件,并在同一芯片上,與14 位的A/D 轉(zhuǎn)
- * 換器以及串行接口電路實(shí)現(xiàn)無縫連接。
- *
- * SHT10引腳特性如下:
- * 1. VDD,GND SHT10 的供電電壓為2.4~5.5V。傳感器上電后,要等待11ms 以越過“休眠”狀態(tài)。在此期間無需發(fā)送任何指令。
- * 電源引腳(VDD,GND)之間可增加一個(gè)100nF 的電容,用以去耦濾波。
- * 2. SCK 用于微處理器與SHT10 之間的通訊同步。由于接口包含了完全靜態(tài)邏輯,因而不存在最小SCK頻率。
- * 3. DATA 三態(tài)門用于數(shù)據(jù)的讀取。DATA 在SCK 時(shí)鐘下降沿之后改變狀態(tài),并僅在SCK 時(shí)鐘上升沿有效。數(shù)據(jù)傳輸期間,
- * 在SCK 時(shí)鐘高電平時(shí),DATA必須保持穩(wěn)定。為避免信號沖突,微處理器應(yīng)驅(qū)動(dòng)DATA 在低電平。需要一個(gè)外部的上拉電阻
- * (例如:10kΩ)將信號提拉至高電平。上拉電阻通常已包含在微處理器的I/O 電路中。
- *
- * 向SHT10發(fā)送命令:
- * 用一組“ 啟動(dòng)傳輸”時(shí)序,來表示數(shù)據(jù)傳輸?shù)某跏蓟Kǎ寒?dāng)SCK 時(shí)鐘高電平時(shí)DATA 翻轉(zhuǎn)為低電平,緊接著SCK變?yōu)榈碗娖剑?br />
- * 隨后是在SCK 時(shí)鐘高電平時(shí)DATA 翻轉(zhuǎn)為高電平。后續(xù)命令包含三個(gè)地址位(目前只支持“000”),和五個(gè)命令位。SHT10會(huì)以下
- * 述方式表示已正確地接收到指令:在第8 個(gè)SCK 時(shí)鐘的下降沿之后,將DATA 拉為低電平(ACK 位)。在第9 個(gè)SCK 時(shí)鐘的下降沿
- * 之后,釋放DATA(恢復(fù)高電平)。
- *
- * 測量時(shí)序(RH 和 T):
- * 發(fā)布一組測量命令(‘00000101’表示相對濕度RH,‘00000011’表示溫度T)后,控制器要等待測量結(jié)束。這個(gè)過程需要大約
- * 11/55/210ms,分別對應(yīng)8/12/14bit 測量。確切的時(shí)間隨內(nèi)部晶振速度,最多有±15%變化。SHTxx 通過下拉DATA 至低電平并
- * 進(jìn)入空閑模式,表示測量的結(jié)束。控制器在再次觸發(fā)SCK 時(shí)鐘前,必須等待這個(gè)“數(shù)據(jù)備妥”信號來讀出數(shù)據(jù)。檢測數(shù)據(jù)可以
- * 先被存儲(chǔ),這樣控制器可以繼續(xù)執(zhí)行其它任務(wù)在需要時(shí)再讀出數(shù)據(jù)。
- * 接著傳輸2 個(gè)字節(jié)的測量數(shù)據(jù)和1 個(gè)字節(jié)的CRC 奇偶校驗(yàn)。uC 需要通過下拉DATA 為低電平,以確認(rèn)每個(gè)字節(jié)。所有的數(shù)據(jù)從
- * MSB 開始,右值有效(例如:對于12bit 數(shù)據(jù),從第5 個(gè)SCK 時(shí)鐘起算作MSB; 而對于 8bit 數(shù)據(jù), 首字節(jié)則無意義)。用
- * CRC 數(shù)據(jù)的確認(rèn)位,表明通訊結(jié)束。如果不使用CRC-8 校驗(yàn),控制器可以在測量值LSB 后,通過保持確認(rèn)位ack 高電平, 來中
- * 止通訊。在測量和通訊結(jié)束后,SHTxx 自動(dòng)轉(zhuǎn)入休眠模式。
- *
- * 通訊復(fù)位時(shí)序:
- * 如果與 SHTxx 通訊中斷,下列信號時(shí)序可以復(fù)位串口:當(dāng)DATA 保持高電平時(shí),觸發(fā)SCK 時(shí)鐘9 次或更多。在下一次指令前,發(fā)送
- * 一個(gè)“傳輸啟動(dòng)”時(shí)序。這些時(shí)序只復(fù)位串口,狀態(tài)寄存器內(nèi)容仍然保留。
- *
- * 更多SHT10信息,請參考相應(yīng)文檔。
- *
- * 光照強(qiáng)度采集:
- * 光照采集主要是通過用CC2530內(nèi)部的ADC來得到OURS-CC2530開發(fā)板上的光照傳感器輸出電壓。傳感器輸出電壓(連接到CC2530的AIN0)
- *
- * 本實(shí)驗(yàn)將使用CC2530讀取溫濕度傳感器SHT10的溫度和濕度數(shù)據(jù),并通過ADC得到光照傳感器的數(shù)據(jù)。最后將采樣到的數(shù)據(jù)轉(zhuǎn)換然后在LCD上顯示。
- *
- * 在\include\hal.h文件中包含了和ADC相關(guān)的一些宏,用戶使用這些宏
- * 可以簡化對ADC的操作,提高代碼的可讀性,本實(shí)驗(yàn)中就使用了其中的一些宏。
- *
- * 注 意:本實(shí)驗(yàn)所需硬件資源:
- * OURS-CC2530RF板
- * 帶LCD的智能主板
- * 溫濕度+光照傳感器板
- *
- *
- * 版 本:V1.0
- * 作 者:wuxianhai
- * 日 期:2011.2.14
- * 奧爾斯科技主頁:www.ourselec.com
- **********************************************************************************************************************************************************/
- #include "hal.h"
- #include "LCD.h"
- #include "stdio.h"
- #define noACK 0
- #define ACK 1
- #define STATUS_REG_W 0x06
- #define STATUS_REG_R 0x07
- #define MEASURE_TEMP 0x03
- #define MEASURE_HUMI 0x05
- #define RESET 0x1e
- #define SCL P1_0 //SHT10時(shí)鐘
- #define SDA P1_1 //SHT10數(shù)據(jù)線
- unsigned char d1,d2,d3,d4,d5,d6,d7;
- void Wait(unsigned int ms);
- void QWait(void) ;
- char s_write_byte(unsigned char value);
- char s_read_byte(unsigned char ack);
- void s_transstart(void);
- void s_connectionreset(void);
- char s_measure( unsigned char *p_checksum, unsigned char mode);
- void initIO(void);
- /**************************************************************************************************
- * 函數(shù)名稱:Wait
- *
- * 功能描述:延時(shí)函數(shù)(不精確延時(shí))
- *
- * 參 數(shù):ms -- 延時(shí)時(shí)間
- *
- * 返 回 值:無
- **************************************************************************************************/
- void Wait(unsigned int ms)
- {
-
- unsigned char g,k;
- while(ms)
- {
-
- for(g=0;g<=167;g++)
- {
- for(k=0;k<=48;k++);
- }
- ms--;
- }
- }
- /**************************************************************************************************
- * 函數(shù)名稱:QWait
- *
- * 功能描述:延時(shí)函數(shù)(大約1us的延時(shí))
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- **************************************************************************************************/
- void QWait()
- {
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");
- }
- /**************************************************************************************************
- * 函數(shù)名稱:initIO
- *
- * 功能描述:SHT10串行通信IO初始化
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- **************************************************************************************************/
- void initIO(void)
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT);
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- P1INP |= 0x03;
- SDA = 1; SCL = 0;
- }
- /**************************************************************************************************
- * 函數(shù)名稱:s_write_byte
- *
- * 功能描述:從SHT10寫一個(gè)字節(jié)
- *
- * 參 數(shù):value -- 需寫入的字節(jié)值
- *
- * 返 回 值:error -- 操作是否成功
- **************************************************************************************************/
- char s_write_byte(unsigned char value)
- {
- unsigned char i,error=0;
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //時(shí)鐘和數(shù)據(jù)IO設(shè)置為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- for (i=0x80;i>0;i/=2) //將一個(gè)字節(jié)的8位逐一輸出
- {
- if (i & value)
- SDA=1;
- else
- SDA=0;
- SCL = 1;
- QWait();QWait();QWait();QWait();QWait();
- SCL = 0;
- asm("NOP"); asm("NOP");
- }
- SDA = 1;
- IO_DIR_PORT_PIN(1, 1, IO_IN); //將數(shù)據(jù)線設(shè)置為輸入,以準(zhǔn)備接收SHT10的ACK
- SCL = 1; asm("NOP");
- error = SDA;
- QWait();QWait();QWait();
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //將數(shù)據(jù)線恢復(fù)為輸出狀態(tài)
- SDA = 1;
- SCL = 0;
-
- return error;
- }
- /**************************************************************************************************
- * 函數(shù)名稱:s_read_byte
- *
- * 功能描述:從SHT10讀取一個(gè)字節(jié)
- *
- * 參 數(shù):ack -- 讀取數(shù)據(jù)后,向SHT10發(fā)送ACK
- *
- * 返 回 值:val -- 讀取的字節(jié)值
- **************************************************************************************************/
- char s_read_byte(unsigned char ack)
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //時(shí)鐘和數(shù)據(jù)IO設(shè)置為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- unsigned char i,val=0;
- SDA= 1;
- IO_DIR_PORT_PIN(1, 1, IO_IN); //將數(shù)據(jù)線設(shè)置為輸入,以準(zhǔn)備接收SHT10的數(shù)據(jù)
- for (i=0x80;i>0;i/=2)
- {
- SCL = 1;
- if (SDA)
- val = (val | i);
- else
- val = (val | 0x00);
- SCL = 0;
- QWait();QWait();QWait();QWait();QWait();
- }
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //將數(shù)據(jù)線恢復(fù)為輸出狀態(tài)
- SDA = !ack;
- SCL = 1;
- QWait();QWait();QWait();QWait();QWait();
- SCL = 0;
- SDA = 1;
-
- return val; //返回讀取的值
- }
- /**************************************************************************************************
- * 函數(shù)名稱:s_transstart
- *
- * 功能描述:啟動(dòng)SHT10,開始與SHT10通信
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- **************************************************************************************************/
- void s_transstart(void)
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT);
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- SDA = 1; SCL = 0;
- QWait();QWait();
- SCL = 1;QWait();QWait();
- SDA = 0;QWait();QWait();
- SCL = 0;QWait();QWait();QWait();QWait();QWait();
- SCL = 1;QWait();QWait();
- SDA = 1;QWait();QWait();
- SCL = 0;QWait();QWait();
- }
- /**************************************************************************************************
- * 函數(shù)名稱:s_connectionreset
- *
- * 功能描述:與SHT10通信復(fù)位
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- **************************************************************************************************/
- void s_connectionreset(void)
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT);
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- unsigned char i;
- SDA = 1; SCL= 0;
- for(i=0;i<9;i++)
- {
- SCL = 1;QWait();QWait();
- SCL = 0;QWait();QWait();
- }
- s_transstart();
- }
- /**************************************************************************************************
- * 函數(shù)名稱:s_measure
- *
- * 功能描述:發(fā)送命令、讀取SHT10溫度或濕度數(shù)據(jù)
- *
- * 參 數(shù):*p_checksum -- 校驗(yàn)和
- * mode -- 讀取數(shù)據(jù)類型(3為溫度,5為濕度)
- *
- * 返 回 值:er -- 操作結(jié)果
- **************************************************************************************************/
- char s_measure( unsigned char *p_checksum, unsigned char mode)
- {
- unsigned er=0;
- unsigned int i,j;
- s_transstart(); //啟動(dòng)傳輸
- switch(mode)
- {
- case 3 :er+=s_write_byte(3);break; //發(fā)送溫度讀取命令
- case 5 :er+=s_write_byte(5);break; //發(fā)送濕度讀取命令
- default :break;
- }
- IO_DIR_PORT_PIN(1, 1, IO_IN); //將數(shù)據(jù)線設(shè)置為輸入,以準(zhǔn)備接收SHT10的ACK
- for(i=0;i<65535;i++)
- {
- for(j=0;j<65535;j++)
- {if(SDA == 0)
- {break;}}
- if(SDA == 0)
- {break;}
- }
-
- if(SDA) //SDA沒有拉低,錯(cuò)誤信息加1
-
- {er += 1;}
- d1 = s_read_byte(ACK); //數(shù)據(jù)讀取
- d2 = s_read_byte(ACK);
- d3 = s_read_byte(noACK);
- return er;
- }
- /**************************************************************************************************
- * 函數(shù)名稱:th_read
- *
- * 功能描述:調(diào)用相應(yīng)函數(shù),讀取溫度和數(shù)據(jù)數(shù)據(jù)并校驗(yàn)和計(jì)算
- *
- * 參 數(shù):*t -- 溫度值
- * *h -- 濕度值
- *
- * 返 回 值:無
- **************************************************************************************************/
- void th_read(int *t,int *h )
- {
- unsigned char error,checksum;
- float humi,temp;
- int tmp;
- initIO();
-
- s_connectionreset(); //啟動(dòng)傳輸
- error=0;
- error+=s_measure(&checksum,5); //讀取濕度數(shù)據(jù)并校驗(yàn)
- humi = d1*256+d2;
-
- error+=s_measure(&checksum,3); //讀取溫度數(shù)據(jù)并校驗(yàn)
- temp = d1*256+d2;
- if(error!=0) s_connectionreset(); //讀取失敗,通信復(fù)位
- else //讀取成功,計(jì)算數(shù)據(jù)
- {
- temp = temp*0.01 - 44.0 ;
- humi = (temp - 25) * (0.01 + 0.00008 * humi) -0.0000028 * humi * humi + 0.0405 * humi-4;
- if(humi>100)
- {humi = 100;}
- if(humi<0.1)
- {humi = 0.1;}
- }
-
- tmp=(int)(temp*10)%10;
-
- if(tmp>4)
- {
- temp=temp+1;
- }
- else
- {
- temp=temp;
- }
-
- *t=(int)temp;
-
- tmp=(int)(humi*10)%10;
-
- if(humi>4)
- {
- humi=humi+1;
- }
- else
- {
- humi=humi;
- }
-
- *h=(int)humi;
-
- }
- /**************************************************************************************************
- * 函數(shù)名稱:main
- *
- * 功能描述:讀取溫度、濕度和光照強(qiáng)度數(shù)據(jù),并同過LCD顯示
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- **************************************************************************************************/
- void main()
- {
- int tempera;
- int humidity;
- char s[16];
- UINT8 adc0_value[2];
- float num = 0;
- SET_MAIN_CLOCK_SOURCE(CRYSTAL); // 設(shè)置系統(tǒng)時(shí)鐘源為32MHz晶體振蕩器
-
- GUI_Init(); // GUI初始化
- GUI_SetColor(1,0); // 顯示色為亮點(diǎn),背景色為暗點(diǎn)
- GUI_PutString5_7(25,6,"OURS-CC2530"); //顯示 OURS-CC2530
- GUI_PutString5_7(10,22,"Temp:");
- GUI_PutString5_7(10,35,"Humi:");
- GUI_PutString5_7(10,48,"Light:");
- LCM_Refresh();
-
- while(1)
- {
- th_read(&tempera,&humidity); //讀取溫度和濕度
- sprintf(s, (char*)"%d%d C", ((INT16)((int)tempera / 10)), ((INT16)((int)tempera % 10))); //將溫度結(jié)果轉(zhuǎn)換為字符串
- GUI_PutString5_7(48,22,(char *)s); //顯示結(jié)果
- LCM_Refresh();
- sprintf(s, (char*)"%d%d %%", ((INT16)((int)humidity / 10)), ((INT16)((int)humidity % 10)));//將濕度結(jié)果轉(zhuǎn)換為字符串
- GUI_PutString5_7(48,35,(char *)s); //顯示結(jié)果
- LCM_Refresh();
-
- /* AIN0通道采樣 */
- ADC_ENABLE_CHANNEL(ADC_AIN0); // 使能AIN0為ADC輸入通道
- /* 配置ADCCON3寄存器以便在ADCCON1.STSEL = 11(復(fù)位默認(rèn)值)且ADCCON1.ST = 1時(shí)進(jìn)行單一轉(zhuǎn)換 */
- /* 參考電壓:AVDD_SOC引腳上的電壓 */
- /* 抽取率:512 */
- /* ADC輸入通道:AIN0 */
- ADC_SINGLE_CONVERSION(ADC_REF_AVDD | ADC_14_BIT | ADC_AIN0);
- ADC_SAMPLE_SINGLE(); // 啟動(dòng)一個(gè)單一轉(zhuǎn)換
- while(!ADC_SAMPLE_READY()); // 等待轉(zhuǎn)換完成
- ADC_ENABLE_CHANNEL(ADC_AIN0); // 禁止AIN0
- adc0_value[0] = ADCL; // 讀取ADC值
- adc0_value[1] = ADCH; // 讀取ADC值
- adc0_value[0] = adc0_value[0]>>2;
-
- num = (adc0_value[1]*256+adc0_value[0])*3.3/8192; //有一位符號位,取2^13;
- num /= 4;
- num=num*913; //轉(zhuǎn)換為Lx
- sprintf(s, (char*)"%d%d%d%d lx", ((INT16)((int)num/1000)), ((INT16)((int)num%1000/100)),((INT16)((int)num%100/10)),((INT16)((int)num%10))); //將光照結(jié)果轉(zhuǎn)換為字符串
- GUI_PutString5_7(48,48,(char *)s); //顯示結(jié)果
- LCM_Refresh();
- }
- }
復(fù)制代碼
- /**********************************************************************************************************
- * 文 件 名:iic.C
- * 功 能:實(shí)驗(yàn)二 GPIO控制實(shí)驗(yàn)
- * 該實(shí)驗(yàn)采用CC2530的I/O口(P1.0和P1.1)模擬IIC總線的SCL和SDA,然后通過IIC總線形式控制GPIO擴(kuò)展芯片
- * PCA9554,最后通過擴(kuò)展的IO來控制LED的亮滅。
- *
- * 硬件連接:將OURS的CC2530RF模塊插入到普通電池板或智能電池板上。
- *
- * P1.0 ------ SCL
- * P1.1 ------ SDA
- *
- * 版 本:V1.0
- * 作 者:WUXIANHAI
- * 日 期:2011.1.18
- * 奧爾斯電子主頁:www.ourselec.com
- **************************************************************************************************************/
- #include "ioCC2530.h"
- #include "hal_mcu.h"
- #define SCL P1_0 //IIC時(shí)鐘線
- #define SDA P1_1 //IIC數(shù)據(jù)線
- #define ON 0x01 //LED狀態(tài)
- #define OFF 0x00
- //定義IO方向控制函數(shù)
- #define IO_DIR_PORT_PIN(port, pin, dir) \
- do { \
- if (dir == IO_OUT) \
- P##port##DIR |= (0x01<<(pin)); \
- else \
- P##port##DIR &= ~(0x01<<(pin)); \
- }while(0)
- #define OSC_32KHZ 0x00 //使用外部32K晶體振蕩器
- //時(shí)鐘設(shè)置函數(shù)
- #define HAL_BOARD_INIT() \
- { \
- uint16 i; \
- \
- SLEEPCMD &= ~OSC_PD; /* 開啟 16MHz RC 和32MHz XOSC */ \
- while (!(SLEEPSTA & XOSC_STB)); /* 等待 32MHz XOSC 穩(wěn)定 */ \
- asm("NOP"); \
- for (i=0; i<504; i++) asm("NOP"); /* 延時(shí)63us*/ \
- CLKCONCMD = (CLKCONCMD_32MHZ | OSC_32KHZ); /* 設(shè)置 32MHz XOSC 和 32K 時(shí)鐘 */ \
- while (CLKCONSTA != (CLKCONCMD_32MHZ | OSC_32KHZ)); /* 等待時(shí)鐘生效*/ \
- SLEEPCMD |= OSC_PD; /* 關(guān)閉 16MHz RC */ \
- }
- #define IO_IN 0 //輸入
- #define IO_OUT 1 //輸出
- uint8 ack; //應(yīng)答標(biāo)志位
- uint8 PCA9554ledstate = 0; //所有LED當(dāng)前狀態(tài)
- /******************************************************************************
- * 函數(shù)名稱:QWait
- *
- * 功能描述:1us的延時(shí)
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *****************************************************************************/
- void QWait()
- {
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");asm("NOP");
- asm("NOP");
- }
- /******************************************************************************
- * 函數(shù)名稱:Wait
- *
- * 功能描述:ms的延時(shí)
- *
- * 參 數(shù):ms - 延時(shí)時(shí)間
- *
- * 返 回 值:無
- *****************************************************************************/
- void Wait(unsigned int ms)
- {
- unsigned char g,k;
- while(ms)
- {
-
- for(g=0;g<=167;g++)
- {
- for(k=0;k<=48;k++);
- }
- ms--;
- }
- }
- /******************************************************************************
- * 函數(shù)名稱:Start_I2c
- *
- * 功能描述:啟動(dòng)I2C總線,即發(fā)送I2C起始條件.
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *****************************************************************************/
- void Start_I2c()
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //設(shè)置P1.0為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //設(shè)置P1.1為輸出
-
- SDA=1; /*發(fā)送起始條件的數(shù)據(jù)信號*/
- asm("NOP");
- SCL=1;
- QWait(); /*起始條件建立時(shí)間大于4.7us,延時(shí)*/
- QWait();
- QWait();
- QWait();
- QWait();
- SDA=0; /*發(fā)送起始信號*/
- QWait(); /* 起始條件鎖定時(shí)間大于4μs*/
- QWait();
- QWait();
- QWait();
- QWait();
- SCL=0; /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
- asm("NOP");
- asm("NOP");
- }
- /******************************************************************************
- * 函數(shù)名稱:Stop_I2c
- *
- * 功能描述:結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *****************************************************************************/
- void Stop_I2c()
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //設(shè)置P1.0為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //設(shè)置P1.1為輸出
- SDA=0; /*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
- asm("NOP"); /*發(fā)送結(jié)束條件的時(shí)鐘信號*/
- SCL=1; /*結(jié)束條件建立時(shí)間大于4μs*/
- QWait();
- QWait();
- QWait();
- QWait();
- QWait();
- SDA=1; /*發(fā)送I2C總線結(jié)束信號*/
- QWait();
- QWait();
- QWait();
- QWait();
- }
- /******************************************************************************
- * 函數(shù)名稱:SendByte
- *
- * 功能描述:將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對
- * 此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0 假)
- * 發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應(yīng)答或損壞。
- *
- * 參 數(shù):c - 需發(fā)送的數(shù)據(jù)
- *
- * 返 回 值:無
- *****************************************************************************/
- void SendByte(uint8 c)
- {
- uint8 BitCnt;
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //設(shè)置P1.0為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //設(shè)置P1.1為輸出
- for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數(shù)據(jù)長度為8位*/
- {
- if((c<<BitCnt)&0x80)SDA=1; /*判斷發(fā)送位*/
- else SDA=0;
- asm("NOP");
- SCL=1; /*置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
- QWait();
- QWait(); /*保證時(shí)鐘高電平周期大于4μs*/
- QWait();
- QWait();
- QWait();
- SCL=0;
- }
- QWait();
- QWait();
- QWait();
- SDA=1; /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
- asm("NOP");
- IO_DIR_PORT_PIN(1, 1, IO_IN);
- SCL=1;
- QWait();
- QWait();
- QWait();
- QWait();
- if(SDA==1)ack=0;
- else ack=1; /*判斷是否接收到應(yīng)答信號*/
- SCL=0;
- QWait();
- QWait();
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- }
- /******************************************************************************
- * 函數(shù)名稱:RcvByte
- *
- * 功能描述:用來接收從器件傳來的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號),
- * 發(fā)完后請用應(yīng)答函數(shù)。
- *
- * 參 數(shù):無
- *
- * 返 回 值:retc - 從器件傳來的數(shù)據(jù)
- *****************************************************************************/
- uint8 RcvByte()
- {
- uint8 retc;
- uint8 BitCnt;
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //設(shè)置P1.0為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //設(shè)置P1.1為輸出
- retc=0;
- SDA=1; /*置數(shù)據(jù)線為輸入方式*/
- IO_DIR_PORT_PIN(1, 1, IO_IN);
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- asm("NOP");
- SCL=0; /*置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
- QWait();
- QWait(); /*時(shí)鐘低電平周期大于4.7μs*/
- QWait();
- QWait();
- QWait();
- SCL=1; /*置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
- QWait();
- QWait();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; /*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 */
- QWait();
- QWait();
- }
- SCL=0;
- QWait();
- QWait();
- IO_DIR_PORT_PIN(1, 1, IO_OUT);
- return(retc);
- }
- /******************************************************************************
- * 函數(shù)名稱:Ack_I2c
- *
- * 功能描述:主控器進(jìn)行應(yīng)答信號,(可以是應(yīng)答或非應(yīng)答信號)
- *
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *****************************************************************************/
- void Ack_I2c(uint8 a)
- {
- IO_DIR_PORT_PIN(1, 0, IO_OUT); //設(shè)置P1.0為輸出
- IO_DIR_PORT_PIN(1, 1, IO_OUT); //設(shè)置P1.1為輸出
- if(a==0)SDA=0; /*在此發(fā)出應(yīng)答或非應(yīng)答信號 */
- else SDA=1;
- QWait();
- //QWait();
- //QWait();
- SCL=1;
- QWait();
- QWait(); /*時(shí)鐘低電平周期大于4μs*/
- QWait();
- QWait();
- QWait();
- SCL=0; /*清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收*/
- QWait();
- //QWait();
- }
- /******************************************************************************
- * 函數(shù)名稱:ISendByte
- *
- * 功能描述:從啟動(dòng)總線到發(fā)送地址,數(shù)據(jù),結(jié)束總線的全過程,從器件地址sla.
- * 如果返回1表示操作成功,否則操作有誤。
- *
- *
- * 參 數(shù):sla - 從器件地址
- * c - 需發(fā)送的數(shù)據(jù)
- *
- * 返 回 值:0 -- 失敗
- * 1 -- 成功
- *****************************************************************************/
- uint8 ISendByte(uint8 sla,uint8 c)
- {
- Start_I2c(); /*啟動(dòng)總線*/
- SendByte(sla); /*發(fā)送器件地址*/
- if(ack==0)return(0);
- SendByte(c); /*發(fā)送數(shù)據(jù)*/
- if(ack==0)return(0);
- Stop_I2c(); /*結(jié)束總線*/
- return(1);
- }
- /******************************************************************************
- * 函數(shù)名稱:ISendStr
- *
- * 功能描述:從啟動(dòng)總線到發(fā)送地址,子地址,數(shù)據(jù),結(jié)束總線的全過程,從器件
- * 地址sla,子地址suba,發(fā)送內(nèi)容是s指向的內(nèi)容,發(fā)送no個(gè)字節(jié)。
- * 如果返回1表示操作成功,否則操作有誤。
- *
- *
- * 參 數(shù):sla - 從器件地址
- * suba - 從器件子地址
- * *s - 數(shù)據(jù)
- * no - 數(shù)據(jù)字節(jié)數(shù)目
- *
- * 返 回 值:0 -- 失敗
- * 1 -- 成功
- *
- * 注 意:使用前必須已結(jié)束總線。
- *****************************************************************************/
- uint8 ISendStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
- {
- uint8 i;
- Start_I2c(); /*啟動(dòng)總線*/
- SendByte(sla); /*發(fā)送器件地址*/
- if(ack==0)return(0);
- SendByte(suba); /*發(fā)送器件子地址*/
- if(ack==0)return(0);
- for(i=0;i<no;i++)
- {
- SendByte(*s); /*發(fā)送數(shù)據(jù)*/
- if(ack==0)return(0);
- s++;
- }
- Stop_I2c(); /*結(jié)束總線*/
- return(1);
- }
- /******************************************************************************
- * 函數(shù)名稱:IRcvByte
- *
- * 功能描述:從啟動(dòng)總線到發(fā)送地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件地
- * 址sla,返回值在c. 如果返回1表示操作成功,否則操作有誤。
- *
- *
- * 參 數(shù):sla - 從器件地址
- * *c - 需發(fā)送的數(shù)據(jù)
- *
- * 返 回 值:0 -- 失敗
- * 1 -- 成功
- *
- *注 意:使用前必須已結(jié)束總線。
- *****************************************************************************/
- uint8 IRcvByte(uint8 sla,uint8 *c)
- {
- Start_I2c(); /*啟動(dòng)總線*/
- SendByte(sla+1); /*發(fā)送器件地址*/
- //SendByte(sla);
- if(ack==0)return(0);
- *c=RcvByte(); /*讀取數(shù)據(jù)*/
- Ack_I2c(1); /*發(fā)送非就答位*/
- Stop_I2c(); /*結(jié)束總線*/
- return(1);
- }
- /******************************************************************************
- * 函數(shù)名稱:IRcvStr
- *
- * 功能描述:從啟動(dòng)總線到發(fā)送地址,子地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件
- * 地址sla,子地址suba,讀出的內(nèi)容放入s指向的存儲(chǔ)區(qū),讀no個(gè)字節(jié)。
- * 如果返回1表示操作成功,否則操作有誤。
- *
- *
- * 參 數(shù):sla - 從器件地址
- * suba - 從器件子地址
- * *s - 數(shù)據(jù)
- * no - 數(shù)據(jù)字節(jié)數(shù)目
- *
- * 返 回 值:0 -- 失敗
- * 1 -- 成功
- *
- * 注 意:使用前必須已結(jié)束總線。
- *****************************************************************************/
- uint8 IRcvStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
- {
- Start_I2c(); /*啟動(dòng)總線*/
- SendByte(sla); /*發(fā)送器件地址*/
- if(ack==0)return(0);
- SendByte(suba); /*發(fā)送器件子地址*/
- // if(ack==0)return(0);
- // SendByte(sla+1);
- if(ack==0)return(0);
- while(no > 0)
- {
- *s++ = RcvByte();
- if(no > 1) Ack_I2c(0); /*發(fā)送就答位*/
- else Ack_I2c(1); /*發(fā)送非應(yīng)位*/
- no--;
- }
- Stop_I2c(); /*結(jié)束總線*/
- return(1);
- }
- /******************************************************************************
- * 函數(shù)名稱:ctrPCA9554LED
- *
- * 功能描述:通過IIC總線控制PCA9554的輸出,進(jìn)而控制相應(yīng)的LED。
- *
- *
- * 參 數(shù):LED - 所控制的LED
- * operation - 開或關(guān)操作
- *
- * 返 回 值:無
- *
- *
- * 注 意:PCA9554的地址為:0x40
- *****************************************************************************/
- void ctrPCA9554LED(uint8 led,uint8 operation)
- {
- uint8 output = 0x00;
- uint8 *data = 0;
- if(ISendStr(0x40,0x03,&output,1)) //配置PCA9554寄存器
- {
- switch(led)
- {
- case 0: //LED0控制
- if (operation)
- {
- output = PCA9554ledstate & 0xfe;
- }
- else
- {
- output = PCA9554ledstate | 0x01;
- }
- break;
- case 1: //LED1控制
- if (operation)
- {
- output = PCA9554ledstate & 0xfd;
- }
- else
- {
- output = PCA9554ledstate | 0x02;
- }
- break;
- case 2: //LED2控制
- if (operation)
- {
- output = PCA9554ledstate & 0xf7;
- }
- else
- {
- output = PCA9554ledstate | 0x08;
- }
- break;
- case 3: //LED3控制
- if (operation)
- {
- output = PCA9554ledstate & 0xfb;
- }
- else
- {
- output = PCA9554ledstate | 0x04;
- }
- break;
- case 4: //LED4控制
- if (operation)
- {
- output = PCA9554ledstate & 0xdf;
- }
- else
- {
- output = PCA9554ledstate | 0x20;
- }
- break;
- case 5: //LED5控制
- if (operation)
- {
- output = PCA9554ledstate & 0xef;
- }
- else
- {
- output = PCA9554ledstate | 0x10;
- }
- break;
- default:break;
- }
- if(ISendStr(0x40,0x01,&output,1)) //寫PCA9554輸出寄存器
- {
- if(IRcvByte(0x40,data)) //讀PCA9554輸出寄存器
- {
- PCA9554ledstate = *data;
- }
- }
- }
- }
- /******************************************************************************
- * 函數(shù)名稱:PCA9554ledInit
- *
- * 功能描述:初始化6個(gè)LED,即關(guān)閉所有的LED
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *
- *****************************************************************************/
- void PCA9554ledInit()
- {
- uint8 output = 0x00;
- uint8 *data = 0;
- if(ISendStr(0x40,0x03,&output,1)) //配置PCA9554寄存器
- {
- output = 0xbf;
- if(ISendStr(0x40,0x01,&output,1)) //寫輸出寄存器
- {
- if(IRcvByte(0x40,data)) //讀輸出寄存器
- {
- PCA9554ledstate = *data;
- }
- }
- }
- }
- /******************************************************************************
- * 函數(shù)名稱:main
- *
- * 功能描述:6個(gè)LED輪流開啟和關(guān)閉
- *
- * 參 數(shù):無
- *
- * 返 回 值:無
- *
- *****************************************************************************/
- void main()
- {
- uint8 i;
- HAL_BOARD_INIT(); //時(shí)鐘設(shè)置
- PCA9554ledInit();
-
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
完整代碼下載:
第一次實(shí)驗(yàn)課代碼.rar
(124.65 KB, 下載次數(shù): 68)
2017-5-10 15:28 上傳
點(diǎn)擊文件名下載附件
實(shí)驗(yàn)代碼
|
評分
-
查看全部評分
|