CC2530 具有一個IEEE 802.15.4 兼容無線收發器。RF 內核控制模擬無線模塊。另外,它提供了MCU 和無線設備之間的一個接口,這使得可以發出命令,讀取狀態,自動操作和確定無線設備事件的順序。無線設備還包括一個數據包過濾和地址識別模塊。
CC2530 包括許多不同的外設,允許應用程序設計者開發先進的應用。
調試接口執行一個專有的兩線串行接口,用于內電路調試。通過這個調試接口,可以執行整個閃存存儲器的擦除、控制使能哪個振蕩器、停止和開始執行用戶程序、執行8051 內核提供的指令、設置代碼斷點,以及內核中全部指令的單步調試。使用這些技術,可以很好地執行內電路的調試和外部閃存的編程。
設備含有閃存存儲器以存儲程序代碼。閃存存儲器可通過用戶軟件和調試接口編程。閃存控制器處理寫入和擦除嵌入式閃存存儲器。閃存控制器允許頁面擦除和4 字節編程。
cc2530定時器
CC2530的時鐘模塊
振蕩器和時鐘
CC2530設備有一個內部系統時鐘,或者主時鐘。系統時鐘源可以是從16MHz RC振蕩器或一個32M晶體振蕩器中的一個提供。系統時鐘源是由CLKCONCMD SRF控制寄存器。
還有一個32KHz的時鐘源,來源可以是從RC 振蕩器或者32KHz的晶體振蕩器中過來,同樣是由CLKCONCMD寄存器控制。
CLKCONSTA寄存器是一個制度寄存器,用來獲得當前系統時鐘的狀態。
時鐘源可以在一個精度高的晶體振蕩器和一個功耗低的RC振蕩器中交替選擇使用。注意一點:RF的收發操作是要以32MHz的晶體振蕩器為時鐘源才行。
振蕩器
圖中給出了時鐘系統中可用的時鐘源的一個全貌圖。
設備中存在的兩個高頻振蕩器:
* 32MHz晶體振蕩器
* 16MHz的RC振蕩器
32MHz的晶體振蕩器啟動時間對于某些應用來說可能太長了;因此設備可以先運行在16MHz的RC振蕩器中運行直到晶體振蕩器穩定后在使用32MHz晶體振蕩器。16MHz的RC振
蕩器功耗低但是不是很準,所以不能為RF模塊提供服務,只能用32MHz的晶體振蕩器。
設備中存在的兩個低頻振蕩器:
* 32 KHz晶體振蕩器
* 32 KHz RC振蕩器
32KHz的XOSC被設計的工作頻率頻率是32.768KHz并且可以為一些要求時鐘準確子系統提供一個穩定的時鐘信號。32KHz的RCOSC當校準后可以運行在32.753KHz頻率下。校準
只能發生在當32MHz XOSC使能的情況下,可以通過使能SLEEPCMD.OSC32K_CALDIS位來關閉校準。32KHz RC振蕩器相對于32KHz XOSC晶體振蕩器功耗低,應該用在可以降
低成本情況下。兩個振蕩器不能同時工作。
系統時鐘
系統時鐘是由32MHz XOSC或者16MHz RCOSC兩個時鐘源驅動的。CLKCONCMD.OSC位用來選擇系統時鐘源。注意:使用RF模塊時,32MHz晶體振蕩器必須被選上并且運行穩定。
注意:改變CLKCONCMD.OSC位并不能立即導致系統時鐘源的改變。當CLKCONSTA.OSC = CLKCONCMD.OSC時時鐘源的改變才會發揮作用。這是因為設備在實際改變時鐘源之前
需要穩定的時鐘。還有就是注意CLKCONCMD.CLKSPD位反應著系統時鐘頻率,因此是CLKACONCMD.OSC位的鏡子。一旦32MHz的XOSC被選中和穩定,例如,當CLKCONSTA.OSC
位從1切換到0時。
注意:從16MHz到32MHz時鐘源的改變符合CLKCONCMD.TICKSPD設置。CLKCONCMD.TICKSPD設置的緩慢一些的話,當CLKCONCMD.OSC改變的話會導致實際的時鐘源起作用的
時間會很長。當CLKCONCMD.TICKSPD
等于000時會獲得最快的切換速度。
32KHz的振蕩器
默認的或者復位后32KHz RCOSC使能并且被設置作為32KHz的時鐘源。其功耗低,但是相對于32KHz晶體振蕩器而言精度不高,32KHz時鐘源用來驅動睡眠定時器,產生看門狗的滴答值
和作為timer 2計算睡眠定時器的一個閘門。32KHz時鐘源被寄存器CLKCONCMD.OSC32K位用來作為選擇振蕩器。CLKCONCMD.OSC32K寄存器可以在任意時間寫入,但是在16MHz RC
振蕩器是活躍的系統時鐘源之前是不會起作用的。當系統時鐘從16MHz改變為32MHz的晶體振蕩器(CLKCONCMD.OSC從1到0)一旦32KHz RC振蕩器被選中了它的的校驗就啟動了并且被執行。在校準期間,32MHz晶體振蕩器的一個分頻量會被使用。32KHzRCOSC振蕩器校準后的結果是它會工作在32.753kHz上。32kHz RC振蕩器校準時間可能要2ms時間來完成。可以設置SLEEPCMD.OSC32K_CALDIS位設置為1的話,會關閉校準。在校準結束時,會在32KHz時鐘源上產生一個額外的脈沖,會導致睡眠定時器增加1。
注意:當切換到32KHz晶體振蕩器后和從32KHz晶體振蕩器被設置的PM3模式喚醒時,振蕩器穩定到準確頻率的時間在500 ms以上。睡眠定時器、看門狗定時器和時鐘損失探測器在32KHz
晶體振蕩器穩定之前不能使用。
振蕩器和時鐘寄存器
下面是振蕩器和時鐘寄存器的描述,所有寄存器的位會在進入PM2和PM3時保持不變,除非有異常情況發生。
定時器滴答值產生器
CLKCONCMD.TICKSPD寄存器控制timer1、timer3和timer4的全局預分頻。預分頻的值設置范圍在0.25MHz和32MHz之間。
需要注意的是如果CLKCONCMD.TICKSPD顯示的頻率高于系統時鐘,則在CLKCONSTA.TICKSPD中的實際的預分頻值表明是和系統時鐘的值是一樣的。
數據滯留
在PM2和PM3電源模式中,絕大多數的內部電路關閉了,然而,SRAM中任保留它的內容,內部寄存器的值也會保留。
保留數據的寄存器是CPU的寄存器、外部寄存器和RF寄存器,除非另一些位域值設置的比較特殊。切換到PM2和PM3模式的現象對于軟件而已是透明的。
注意在PM3模式下睡眠定時器的值不會保存。
******************************************************************
/**********************************************************************************************************
* 功 能:實驗一 系統時鐘源的選擇
*
* CC2530有1個內部的系統時鐘。時鐘源可以是1個16MHz的RC振蕩器,也可以是1個32MHz的晶體
* 振蕩器。時鐘控制是通過使用CLKCON特殊功能寄
存器來執行的。系統時鐘也提供給所有的8051
* 外設。
*
* 32MHz晶體振蕩器的啟動時間對于某些應用而言太長了,因此CC2530可以運行在16MHz RC振蕩器
* 直到晶體振蕩器穩定。16MHz RC振蕩器的功耗要少于晶體振蕩器,但是由于它沒有晶體振蕩器
* 精確,因此它不適用于射頻收發器。
*
* CLKCONCMD.OSC位被用來選擇系統時鐘源。注意:要使用射頻收發器,32MHz晶體振蕩器必須被選擇
* 并且穩定。
*
* 注意:改變CLKCON.OSC位并不即刻生效。這是因為在實際改變時鐘源之前,被選擇的時鐘源要
* 首先達到穩定。還要注意:CLKCONSTA.CLKSPD位將反映系統時鐘頻率,因此它是CLKCON.OSC位的
* “鏡子”。
*
* 當SLEEPSTA.XOSC_STB為1時,表示系統報告32MHz晶體振蕩器穩定。然而,這可能并不是實際情況,
× 在選擇32MHz時鐘作為系統時鐘源之前,應該等待一個額外的64us的安全時間,可以通過增加一
* 條空指令“NOP”來實現。如果不等待,可能會造成系統崩潰。
*
* 未被選擇作為系統時鐘源的振蕩器,通過設置SLEEP.OSC_PD為1(默認狀態)將被設置為掉電模式。
* 因此,當32MHz晶體振蕩器被選擇作為系統時鐘源后,16MHz RC振蕩器可能被關閉,反之亦然。
* 當SLEEPCMD.OSC_PD為0時,這2個振蕩器都被上電并運行。
* 當32MHz晶體振蕩器被選擇作為系統時鐘源并且16MHz RC振蕩器也被上電時,根據供電電壓和運
* 行溫度,16MHZ RC振蕩器將被不斷校準以確保時鐘穩定。當16MHz RC振蕩器被選擇作為系統時鐘
* 源時,該校準不被執行。
*
* 本實驗將向用戶演示選擇不同的振蕩器作為系統時鐘源。本文件中有led閃爍的子程序,用戶
* 可以觀察在不同系統時鐘源下led的閃爍情況。
*
* 在hal.h文件中包含了和系統時鐘相關的一些宏,用戶使用這些宏可以簡化對系統時鐘的控制,
* 提高代碼的可讀性,本實驗中就使用了其中的一些宏。
*
* 注 意:本實驗可在以下目標板上進行:
*
*
*
*
*
* 版 本:V1.0 **************************************************************************************************/
#include “hal.h”
#define ON 0x01 //LED狀態
#define OFF 0x00
extern void ctrPCA9554LED(UINT8 led,UINT8 operation);
extern void PCA9554ledInit();
/**************************************************************************************************
* 函數名稱:halWait
*
* 功能描述:延時
*
* 參 數:wait - 延時時間
*
* 返 回 值:無
**************************************************************************************************/
void halWait(BYTE wait){
UINT32 largeWait;
if(wait == 0)
{return;}
largeWait = ((UINT16) (wait 《《 7));
largeWait += 114*wait;
largeWait = (largeWait 》》 CLKSPD);
while(largeWait--);
return;
}
/**************************************************************************************************
* 函數名稱:main
*
* 功能描述:反復選擇不同的振蕩器作為系統時鐘源,并調用led控制程序,閃爍LED燈。
*
* 參 數:無
*
* 返 回 值:無
**************************************************************************************************/
void main(void)
{
UINT8 i;
PCA9554ledInit();
while(1)
{
SET_MAIN_CLOCK_SOURCE(CRYSTAL); // 設置系統時鐘源為32MHz晶體振蕩器(大約用時150us),關閉16MHz RC振蕩器
for (i=0;i《10;i++)
{
ctrPCA9554LED(0,ON);
halWait(200);
ctrPCA9554LED(0,OFF);
halWait(200);
}
SET_MAIN_CLOCK_SOURCE(RC); // 選擇16MHz RC振蕩器,關閉32MHz晶體振蕩器
PCA9554ledInit();
halWait(200);
for (i=0;i《10;i++)
{
ctrPCA9554LED(1,ON);
halWait(200);
ctrPCA9554LED(1,OFF);
halWait(200);
}
}
}
/**********************************************************************************************************
* 文 件 名: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
**************************************************************************************************************/
#include “ioCC2530.h”
#include “hal_mcu.h”
#define SCL P1_0 //IIC時鐘線
#define SDA P1_1 //IIC數據線
//定義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_I
NIT() \
{ \
uint16 i; \
\
SLEEPCMD &= ~OSC_PD; /* 開啟 16MHz RC 和32MHz XOSC */ \
while (!(SLEEPSTA & XOSC_STB)); /* 等待 32MHz XOSC 穩定 */ \
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當前狀態
/******************************************************************************
* 函數名稱: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總線,即發送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; /*發送起始條件的數據信號*/
asm(“NOP”);
SCL=1;
QWait(); /*起始條件建立時間大于4.7us,延時*/
QWait();
QWait();
QWait();
QWait();
SDA=0; /*發送起始信號*/
QWait(); /* 起始條件鎖定時間大于4μs*/
QWait();
QWait();
QWait();
QWait();
SCL=0; /*鉗住I2C總線,準備發送或接收數據 */
asm(“NOP”);
asm(“NOP”);
}
/******************************************************************************
* 函數名稱:Stop_I2c
*
* 功能描述:結束I2C總線,即發送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; /*發送結束條件的數據信號*/
asm(“NOP”); /*發送結束條件的時鐘信號*/
SCL=1; /*結束條件建立時間大于4μs*/
QWait();
QWait();
QWait();
QWait();
QWait();
SDA=1; /*發送I2C總線結束信號*/
QWait();
QWait();
QWait();
QWait();
}
/******************************************************************************
* 函數名稱:SendByte
*
* 功能描述:將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
* 此狀態位進行操作。(不應答或非應答都使ack=0 假)
* 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
*
* 參 數:c - 需發送的數據
*
* 返 回 值:無
*****************************************************************************/
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; /*判斷發送位*/
else SDA=0;
asm(“NOP”);
SCL=1; /*置時鐘線為高,通知被控器開始接收數據位*/
QWait();
QWait(); /*保證時鐘高電平周期大于4μs*/
QWait();
QWait();
QWait();
SCL=0;
}
QWait();
QWait();
QWait();
SDA=1; /*8位發送完后釋放數據線,準備接收應答位*/
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
*
* 功能描述:用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
* 發完后請用應答函數。
*
* 參 數:無
*
* 返 回 值:retc - 從器件傳來的數據
*****************************************************************************/
uint8 RcvByte()
{
uint8 retc;
uint8 BitCnt;
IO_DIR_PORT_PIN(1, 0, IO_OUT); //設置P1.0為輸出
IO_DIR_P
ORT_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; /*在此發出應答或非應答信號 */
else SDA=1;
QWait();
//QWait();
//QWait();
SCL=1;
QWait();
QWait(); /*時鐘低電平周期大于4μs*/
QWait();
QWait();
QWait();
SCL=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/
QWait();
//QWait();
}
/******************************************************************************
* 函數名稱:ISendByte
*
* 功能描述:從啟動總線到發送地址,數據,結束總線的全過程,從器件地址sla.
* 如果返回1表示操作成功,否則操作有誤。
*
*
* 參 數:sla - 從器件地址
* c - 需發送的數據
*
* 返 回 值:0 -- 失敗
* 1 -- 成功
*****************************************************************************/
uint8 ISendByte(uint8 sla,uint8 c)
{
Start_I2c(); /*啟動總線*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(c); /*發送數據*/
if(ack==0)return(0);
Stop_I2c(); /*結束總線*/
return(1);
}
/******************************************************************************
* 函數名稱:ISendStr
*
* 功能描述:從啟動總線到發送地址,子地址,數據,結束總線的全過程,從器件
* 地址sla,子地址suba,發送內容是s指向的內容,發送no個字節。
* 如果返回1表示操作成功,否則操作有誤。
*
*
* 參 數:sla - 從器件地址
* suba - 從器件子地址
* *s - 數據
* no - 數據字節數目
*
* 返 回 值:0 -- 失敗
* 1 -- 成功
*
* 注 意:使用前必須已結束總線。
*****************************************************************************/
uint8 ISendStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
{
uint8 i;
Start_I2c(); /*啟動總線*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
for(i=0;i《no;i++)
{
SendByte(*s); /*發送數據*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*結束總線*/
return(1);
}
/******************************************************************************
* 函數名稱:IRcvByte
*
* 功能描述:從啟動總線到發送地址,讀數據,結束總線的全過程,從器件地
* 址sla,返回值在c. 如果返回1表示操作成功,否則操作有誤。
*
*
* 參 數:sla - 從器件地址
* *c - 需發送的數據
*
* 返 回 值:0 -- 失敗
* 1 -- 成功
*
*注 意:使用前必須已結束總線。
*****************************************************************************/
uint8 IRcvByte(uint8 sla,uint8 *c)
{
Start_I2c(); /*啟動總線*/
SendByte(sla+1); /*發送器件地址*/
//SendByte(sla);
if(ack==0)return(0);
*c=RcvByte(); /*讀取數據*/
Ack_I2c(1); /*發送非就答位*/
Stop_I2c(); /*結束總線*/
return(1);
}
/******************************************************************************
* 函數名稱:IRcvStr
*
* 功能描述:從啟動總線到發送地址,子地址,讀數據,結束總線的全過程,從器件
* 地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個字節。
* 如果返回1表示操作成功,否則操作有誤。
*
*
* 參 數:sla - 從器件地址
* suba - 從器件子地址
* *s - 數據
* no - 數據字節數目
*
* 返 回 值:0 -- 失敗
* 1 -- 成功
*
* 注 意:使用前必須已結束總線。
*****************************************************************************/
uint8 IRcvStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
{
Start_I2c(); /*啟動總線*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
// if(ack==0)return(0);
// SendByte(sla+1);
if(ack==0)return(0);
while(no 》 0)
{
*s++ = RcvByte();
if(no 》 1) Ack_I2c(0); /*發送就答位*/
else Ack_I2c(1); /*發送非應位*/
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;
}
}
}
}
cc2530-按鍵控制時鐘啟動與停止
2012-07-26 16:24:35| 分類: zigbee 2007 |舉報|字號 訂閱
/*功能:
1. 每隔0.065536秒(65536*32/32000000)切換LED顯示
2. S1控制計時器開始和暫停
*/
#include 《ioCC2530.h》
#define LED1 P1_0 //定義LED1為P1.0
#define S1 P0_1 //定義S1為P0.1
//函數實現
void INIT_LED(void)
{
P1SEL &= ~0x01; //設P1.0為普通I/O功能
P1DIR |= 0x01; //設P1.0為輸出方向
LED1 = 0; //將LED1點亮
}
void INIT_IO(void)
{
P0SEL &= ~0x02; //設P0.1(S1)為普通I/O功能
P0DIR &= ~0x02; //設P0.1(S1)為輸入
P0INP &= ~0x02; //設P0.1(S1)為上拉/下拉
P0IFG &= ~0x02; //設P0.1(S1)狀態標志寄存器清零
P0IEN |= 0x02; //設P0.1(S1)中斷使能
P2INP |= 0x60; //P0、P1的下拉
EA = 1; //總中斷EA為中斷使能
IEN1 |= 0x20; //開P0中斷
IEN2 |= 0x10; //開P1中斷
PICTL |= 0x07; //P0、P1下降沿觸發
}
void INIT_Timer1()
{
T1CTL = 0x0C; //128分頻、停止運行
T1STAT = 0x21; //通道0 本句可以取消
IRCON &= ~0x02;
}
//P0.1(S1)中斷處理函數
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
if((P0IFG&0x02) == 0x02) //P0.1(S1)狀態標志寄存器觸發 (P0IFG的值為0XFF,不解)
{
for(int i =0 ;i《8000 ;i++);
P0IFG &= ~0x02; //P0.1(S1)狀態標志寄存器清零
if(T1CTL == 0x09)
T1CTL = 0x0C; //128分頻 暫停運行
else
T1CTL = 0x09; //32分頻 自由運行
}
}
void main( void )
{
INIT_IO();
INIT_LED();
INIT_Timer1();
LED1 = 1 ;
while(1)
{
if(IRCON &= 0x02) //約0.065536秒切換LED燈閃爍
{
LED1 = !LED1;
IRCON &= ~0x02 ;
}
}
}
dongfangnh
采納率:51% 10級 2013.12.14 檢舉
#ifndef ULTRASOUND_H
#define ULTRASOUND_H
#define uchar unsigned char
#define uint unsigned int
#define TRIG P1_3 //P1_2
#define ECHO P0_7 //P0_1
extern uchar RG;
extern uchar H1;
extern uchar L1;
extern uchar H2;
extern uchar L2;
extern uchar H3;
extern uchar L3;
extern uint data;
extern float distance;
extern uchar LoadRegBuf[4];
//void Delay(uint n);
void Delay_1us(uint microSecs);
void Delay_10us(uint n);
void Delay_1s(uint n);
void SysClkSet32M();
void Init_UltrasoundRanging();
void UltrasoundRanging(uchar *ulLoadBufPtr);
__interrupt void P0_ISR(void);
#endif
××××××××××××××××××××××××××××××××××
×××××××××
//×××××××××××Ultrasound.c****************************
#include 《ioCC2530.h》
#include “Ultrasound.h”
uchar RG;
uchar H1;
uchar L1;
uchar H2;
uchar L2;
uchar H3;
uchar L3;
uint data;
float distance;
uchar LoadRegBuf[4];//全局數據,用以存儲定時計數器的值。
void Delay_1us(uint microSecs)
{ while(microSecs--)
{ /* 32 NOPs == 1 usecs 因為延時還有計算的緣故,用了31個nop*/
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”); asm(“nop”);
asm(“nop”);
}
}
void Delay_10us(uint n)
{ /* 320NOPs == 10usecs 因為延時還有計算的緣故,用了310個nop*/
uint tt,yy;
for(tt = 0;tt《n;tt++);
for(yy = 310;yy》0;yy--);
{asm(“NOP”);}
}
void Delay_1s(uint n)
{ uint ulloop=1000;
uint tt;
for(tt =n ;tt》0;tt--);
for( ulloop=1000;ulloop》0;ulloop--)
{
Delay_10us(100);
}
}
void SysClkSet32M()
{
CLKCONCMD &= ~0x40; //設置系統時鐘源為32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振穩定
CLKCONCMD &= ~0x47; //設置系統主時鐘頻率為32MHZ
//此時的CLKCONSTA為0x88。即普通時鐘和定時器時鐘都是32M。
}
void Init_UltrasoundRanging()
{
P1DIR = 0x08; //0為輸入1為輸出 00001000 設置TRIG P1_3為輸出模式
TRIG=0; //將TRIG 設置為低電平
P0INP &= ~0x80; //有上拉、下拉 有初始化的左右
P0IEN |= 0x80; //P0_7 中斷使能
PICTL |= 0x01; //設置P0_7引腳,下降沿觸發中斷
IEN1 |= 0x20; // P0IE = 1;
P0IFG = 0;
}
void UltrasoundRanging(uchar *ulLoadBufPtr)
{
SysClkSet32M();
Init_UltrasoundRanging();
EA = 0;
TRIG =1;
Delay_1us(10); //需要延時10us以上的高電平
TRIG =0;
T1CNTL=0;
T1CNTH=0;
while(!ECHO);
T1CTL = 0x09; //通道0,中斷有效,32分頻;自動重裝模式(0x0000-》0xffff);
L1=T1CNTL;
H1=T1CNTH;
*ulLoadBufPtr++=T1CNTL;
*ulLoadBufPtr++=T1CNTH;
EA = 1;
Delay_10us(60000);
Delay_10us(60000);
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
EA=0;
T1CTL = 0x00;
LoadRegBuf[2]=T1CNTL;
LoadRegBuf[3]=T1CNTH;
L2=T1CNTL;
H2=T1CNTH;
if(P0IFG&0x080) //外部ECHO反饋信號
{
P0IFG = 0;
}
T1CTL = 0x09;
T1CNTL=0;
T1CNTH=0;
P0IF = 0; //清中斷標志
EA=1;
}
××××××××××××××××××××××××××××××××××××××
#include 《ioCC2530.h》
#include “Ultrasound.h”
void main(void)
{
while(1)
{
UltrasoundRanging(LoadRegBuf);
Delay_1s(1);
data=256*H2+L2-L1-256*H1;
distance=(float)data*340/10000;
Delay
_1s(2);
};
}
評論
查看更多