|
1. 상하층 연결 이 글에서는 CC2430의 수면 기능과 기상 방법에 대해 논의하겠습니다. 실제 사용 시 CC2430 노드는 일반적으로 배터리로 전원을 공급받기 때문에 전력 소비 제어가 매우 중요합니다. 다음은 CC2430의 4가지 전력 소비 모드 도입을 위한 CC2430 중국 매뉴얼의 발췌문입니다:
위 표에서 볼 수 있듯이, CC2430은 총 4가지 전원 모드를 가지고 있습니다:PM0(완전히 깨어난 상태),PM1(조금 졸린 듯),PM2(반쯤 깨어 있고 반쯤 잠든 상태),PM3(아주 깊이 잠들었어요). 뒤쪽에 있을수록 더 많은 기능이 꺼지고, 전력 소비는 점점 낮아집니다. 이들 간의 변환 관계는 다음과 같습니다:
풋PM1, PM2일어나세요PM0, 세 가지 방법이 있습니다: 리셋, 외부 중단, 절전 타이머 중단; 하지만PM3일어나세요PM0, 방법은 두 가지뿐입니다: 리셋, 외부 인터럽트(이는PM3모든 발진기가 작동을 멈췄고, 당연히 절전 타이머도 꺼져 있었어요~) 잠전 모드에 들어가는 방법과 깨우는 방법을 소개하는 작은 실험을 해봅시다PM0국가. 2. 체계적인 수면 및 중단된 각성 실험(1) 실험 소개시스템 초기화,PM0
→ 들어오세요PM1
→ 1초 후 절면 타이머로 깨어나기PM0
→ 들어오세요PM2
→ 2초 후 수면 타이머에 깨어났다PM0
→ 들어오세요PM3
→ S1 키를 누르면 외부 인터럽트가 발생하고 깨어나기를 기다립니다PM0
(2) 프로그램 플로우차트
(참고: 위 이미지의 둥근 상자는 시스템의 상태 상태를 나타냅니다)
(3) 실험적 소스 코드 및 분석 (다음 박스를 클릭하실 수 있습니다~)헤더 파일 및 매크로 정의[url=]
[/url]
/* 실험적 설명: 세 가지 수면 모드에서 각성을 도입하는 중단 기상 수면 실험
*/
#include #define LED_ON 0 #define LED_OFF 1#defineLED1 P1_0
#defineLED2 P1_1
#defineLED3 P1_2
#defineLED4 P1_3 [url=] [/url]
하위 기능[url=] [/url]
/*시스템 클럭 초기화 -------------------------------------------------------*/
공허xtal_init(공허)
{ 잠 &= ~0x04; //모두 전원이 공급됩니다
반면(! (잠 그리고0x40)); //크리스탈 오실레이터는 켜져 있고 안정적입니다
CLKCON &= ~0x47; //32MHz 크리스털 발진기를 선택하세요
잠 |=0x04;
}
/*LED 초기화 -------------------------------------------------------*/
공허led_init(공허)
{ P1SEL =0x00; //P1은 일반 I/O 포트입니다
P1DIR |=0x0F; //P1.0 P1.1 P1.2 P1.3 출력
led1 = LED_OFF; //모든 LED를 꺼
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*외부 인터럽트 초기화 -------------------------------------------------------*/
공허io_init(공허)
{ P0INP &= ~0X02; //P0.1에는 풀업과 풀다운이 있습니다
EA =1; //완전한 중단 허용
IEN1 |= 0X20; //P0IE = 1, P0 인터럽트가 활성화됩니다
PICTL |= 0X09; //P0.1은 인터럽트와 드롭 엣지 트리거를 허용합니다
P0IFG &= ~0x02; //P0.1 인터럽트 마크 clear0
}
/*절전 타이머 인터럽트 초기화 -------------------------------------------------------*/
공허sleepTimer_init(공허)
{ STIF=0; //슬립 타이머 중단 마크가 클리어되었습니다 0
STIE=1; //수면 타이머 켜세요 방해
EA=1; //완전한 중단을 열어
}
/*수면 타이머의 예정된 간격을 설정하세요 -------------------------------------------------------*/
공허setSleepTimer(unsign)지능SEC)
{ 서명 없음길게수면 타이머 =0;
sleepTimer |= ST0; //현재 수면 타이머의 카운트 값을 얻으세요
sleepTimer |= (부호 없음)길게) ST1 <<8; sleepTimer |= (부호 없음)길게) ST2 <<16;
sleepTimer += ((서명 없음)길게)SEC * (서명 없음)길게)32768); //게다가 필요한 타이밍 시간도 포함됩니다
ST2 = (부호 없음)차어(슬립타이머 >>16); //슬립 타이머의 비교 값을 설정하세요
ST1 = (부호 없음)차어(슬립타이머 >>8); ST0 = (부호 없음)차어)sleepTimer;
}
/*전원 모드 선택 -------------------------------------------------------*/
공허PowerMode(서명 없음)차어모드)
{
만약(모드 <4) { 잠 &=0xfc; //SLEEP.MODE 설정을 0으로 지우세요
SLEEP |= 모드; //전원 모드 선택
PCON |=0x01; //이 전원 모드를 활성화하세요
}
}
/*지연 함수 -------------------------------------------------------*/
공허지연(부호 없음)지능n)
{ 서명 없음지능i,j;
에 대해(i=0; i<n; i++)
에 대해(j=0; j <1000; j++);
}
[url=] [/url]
주요 기능[url=] [/url]
/*주요 기능 -------------------------------------------------------*/
공허주요(공허)
{ xtal_init(); led_init();
//PM0 상태, 불 켜지고 지연
led1 = LED_ON; //밝기 LED1은 시스템이 PM0 모드로 작동하고 있음을 나타냅니다
지연(10);
//PM1 상태, 불 꺼짐
setSleepTimer(1); //수면 타이머의 시간 간격을 1초로 설정하세요
sleepTimer_init(); //수면 타이머 켜세요 방해
led1 = LED_OFF; 파워모드(1); //전원 모드를 PM1로 설정하세요
//1이 끝난 후 PM1이 PM0에 들어가고, 불이 켜지고 지연됩니다.
led1 = LED_ON; 지연(50);
//PM2, 불 꺼
setSleepTimer(2); //수면 타이머의 시간 간격을 2초로 설정하세요
led1 = LED_OFF; 파워모드(2); //전원 모드를 PM2로 설정하세요
//2초 후 PM2가 PM0에 들어가 불이 켜지고 지연됩니다
LED1=0; 지연(50);
//PM3, 불 꺼짐
io_init(); //외부 인터럽트를 초기화합니다
led1 = LED_OFF; 파워모드(3); //전원 모드를 PM3로 설정하세요
//외부 중단이 발생하면 PM3가 PM0에 진입하여 불이 켜집니다
led1 = LED_ON;
반면(1);
}
[url=] [/url]
인터럽트 서비스 절차[url=] [/url]
/*외부 인터럽트 서비스 프로그램 -------------------------------------------------------*/
#pragma벡터 = P0INT_VECTOR __interrupt공허P0_ISR(공허)
{ EA =0; //문이 끊긴다
지연(50);
만약((P0IFG &0x02) >0) //열쇠가 끊긴다
{ P0IFG &= ~0x02; //P0.1 인터럽트 마크 clear0
} P0IF =0; //P0 인터럽트 마크 클리어0
EA =1; //오픈 인터럽트
}
/*슬립 타이머가 서비스 프로그램을 중단시킵니다 -------------------------------------------------------*/
#pragma벡터= ST_VECTOR __interrupt공허sleepTimer_IRQ(공허)
{ EA=0; //문이 끊긴다
STIF=0; //슬립 타이머 중단 마크가 클리어되었습니다 0
EA=1; //오픈 인터럽트
}
[url=] [/url]
슬립 타이머를 사용해 시스템을 깨우는 방법은 다음과 같이 요약할 수 있습니다:오픈 슬립 타이머 인터럽트→ 슬립 타이머의 타이밍 간격을 설정→ 전원 모드를 설정하세요 (참고: "절전 타이머 간격 설정" 단계는 "전원 모드 설정" 전에 해야 하며, 이는 시스템이 절전 후 프로그램을 계속 실행하지 않기 때문입니다) 다음으로, 수면 타이머 간격을 설정하는 부분 함수에 집중해 보겠습니다:setSleepTimer 우선, 슬립 타이머에 대해 간단히 소개하자면: 이 타이머는 계속 작동한다32.768kHz의24위시스템이 실행 중일 때 타이머PM3 외에도모든 전원 모드에서 절전 타이머는 다음과 같습니다중단 없는 운영。 절전 타이머가 사용하는 레지스터는 다음과 같습니다:ST0,ST1,ST2。 다음은 CC2430 중국 매뉴얼에서 해당 기능에 대한 상세한 소개입니다:
이들의 기능은 두 가지 측면을 포함한다는 것을 알 수 있습니다:읽기,쓰기。 읽기: 현재 타이머의 카운트 값을 읽기 위해 사용되며, 측정 순서를 따라야 합니다:ST0을 읽고, ST1→ 읽고, ST2→ 읽어보세요. 쓰기: 타이머의 비교 값을 설정하는 데 사용되며(타이머의 카운트 값 = 비교 값이 발생할 때 인터럽트가 발생), 쓰기 순서는 다음과 같이 따라야 합니다:ST2를 쓰→ ST1을 쓰→ ST0를 쓰세요 좋아요, 소스 코드와 함께 설명해 봅시다: (1) 먼저, 현재 수면 타이머의 카운트 값을 받기 위해 부호 없는 긴 변수(32비트) 슬립타이머를 정의합니다: 서명 없음길게수면 타이머 =0;
sleepTimer |= ST0; //현재 수면 타이머의 카운트 값을 얻으세요
sleepTimer |= (부호 없음)길게) ST1 <<8; sleepTimer |= (부호 없음)길게) ST2 <<16;
(2) 그 다음 필요한 시간 간격을 더한다: sleepTimer += ((서명 없음)길게)SEC * (서명 없음)길게)32768); //게다가 필요한 타이밍 시간도 포함됩니다
간단한 설명을 드리자면: 왜 1이 32768을 나타내나요? 타이머가 32.768kHz 이하로 작동하기 때문에, 타이머에 1이 추가될 때마다 1/32768초가 걸립니다; 32768을 더하면 1이 필요하다; (3) 마지막으로, sleepTimer의 값이 타이머의 비교 값으로 사용됩니다: ST2 = (부호 없음)차어(슬립타이머 >>16); //슬립 타이머의 비교 값을 설정하세요
ST1 = (부호 없음)차어(슬립타이머 >>8); ST0 = (부호 없음)차어)sleepTimer;
이렇게 하면 타이머의 타이밍 주기를 성공적으로 설정할 수 있습니다~ (참고: 소스 코드의 다른 부분에 대해서는, 상세한 주석과 함께 쉽게 이해하실 수 있으니 여기서는 반복하지 않겠습니다.) (4) 실험 결과프로그램을 실행하며 LED1을 관찰할 때, 현상은 다음과 같습니다:LED1이 깜빡이고(즉, 켜> 끄는 것을 1번 반복하고), 1초 후 다시 깜빡이고, 2초 후에 다시 깜빡이고, 꺼진 상태로 남아 있다가 S1을 누르면 LED1이 켜집니다. 이 실험 현상은 기대와 완전히 일치한다. 오버~
3. 결론오~ 이틀 동안 시간을 내고 드디어 이 기록을 받았어요. 특히 '독자 친화적' 블로그 글을 쓰는 일은 정말 육체적인 작업이라는 걸 알게 됐어요: 엄격함, 미학, 논리성... 모든 것은 배려에 달려 있습니다. 코드를 올릴 때마다 너무 길다고 생각하지만, 블로그 가든에 딸려오는 접기 도구를 쓰는 게 꺼려집니다. 그래서 이 블로그 글에서는 저자가 코드를 부드럽게 접기 위해 JQuery 요소를 조심스럽게 추가했고, 여전히 작은 성취감이 느껴집니다, 헤헤 (JQuery 신참, 마스터를 비웃지 마세요~). 하지만 이것이 글의 가독성을 정말 높여주는지는 잘 모르겠고, 독자나 친구들도 댓글 달아주세요:) 이번 달에는 저자가 블로그 정원에 뿌리를 내리기로 결심해서, 저는 여가 시간을 많이 블로그 글을 썼습니다. 처음 블로그를 썼을 때, 댓글은 적었지만 대부분의 글 클릭률이 500건을 넘었고, 저에게는 작은 격려였습니다! 블로그 정원에서 마이크로컨트롤러에 관한 내용을 올리는 데는 용기가 필요하지만, 저는 계속 그렇게 하겠습니다~ 처음부터 현재까지 9개의 블로그 글은 CC2430 칩에서 기본 하드웨어 모듈의 사용에 초점을 맞추고 있습니다. 지금까지 CC2430의 대부분의 주변기기를 살펴보았지만, 플래시 접근, 난수 생성기, AES 코프로세서, RF 통신 등 아직 다루지 않은 부분들이 남아 있습니다. 하지만 Zigbee 여정은 끝나지 않았으며, 저자는 다음 주제(Z-Stack 프로토콜 구현)에서 이러한 누락을 선별적으로 채우려 합니다. 다음 블로그 글에서는 Zigbee의 첫 여행을 조금 더 포괄적이고 확장된 실험인 '온도 모니터링 시스템'으로 마무리하고, 이전에 배운 지식들을 포괄적으로 적용하는 방법을 설명할 계획입니다. 사실, 그것은 ""설명초보자로서 저자는 서로를 격려하고 박사 논문 작성 과정에서 함께 진전을 이루길 바랄 뿐입니다! </n; i++)
|