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