이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 8951|회답: 0

지그비 여정 (7): 여러 중요한 CC2430 기본 실험 - DMA 전송

[링크 복사]
게시됨 2014. 10. 30. 오후 11:22:16 | | | |
1. 상하층 연결

이전 섹션에서는 ADC의 사용에 대해 이야기하고 온칩 온도 센서를 샘플링했습니다. 실제 프로젝트에서는 센서 수가 많고 변환 데이터가 대량으로 처리됩니다. 이 데이터를 옮기면 CPU에 큰 부담이 가해집니다. CPU를 비우고 다른 용도로 에너지를 공급하려면 DMA(직접 메모리 접근)가 유용할 수 있습니다~

다음 소개는 Zigbee 기술 실습 튜토리얼에서 발췌한 것입니다:

DMA는 직접 메모리 접근(direct memory access)의 약자로, "직접 메모리 접근(direct memory access)"의 약자입니다. 이는 ADC/UART/RF 트랜시버와 메모리와 같은 주변 장치들이 "DMA 컨트롤러"의 제어 하에 CPU 개입 없이 직접 데이터를 교환할 수 있는 고속 데이터 전송 모드입니다. 데이터 전송의 시작과 종료에 약간의 처리 외에도, CPU는 전송 중에 다른 작업도 수행할 수 있습니다. 이렇게 하면 CPU와 이러한 데이터 상호작용이 대부분 병렬로 작동합니다. 그 결과 시스템의 전반적인 효율성이 크게 향상될 수 있습니다.

소개에서 보시다시피, DMA는 다양한 상황에서 사용할 수 있습니다. 이 실험은 가장 단순한 DMA 전송만을 포함하며, DMA의 일반적인 사용을 입증하는 것을 목표로 합니다. DMA의 다른 시나리오 적용에 대해서는 향후 종합 실험에 구현될 예정입니다.

2. DMA 전송 실험(1) 실험 소개

배열 문자출처스트링내용은 DMA를 통해 문자 배열로 전송됩니다destString변환 결과는 시리얼 포트를 통해 PC에 표시됩니다.

(2) 프로그램 플로우차트

(3) 실험적 소스 코드 및 분석/*
    실험적 설명: 문자 배열 sourceString의 내용은 DMA를 통해 문자 배열 destString으로 전송되며, 변환 결과는 직렬 포트를 통해 PC에 표시됩니다.
*/

#include

#define 이끄는 1 P1_0         
#define led2 P1_1         
#define led3 P1_2         
#define led4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma 비트필드=반전
타입 방지 구조
{
  서명 없음 차어SRCADDRH;           //源地址高8位
  서명 없음 차어SRCADDRL;           //源地址低8位
  서명 없음 차어DESTADDRH;         //目的地址高8位
  서명 없음 차어DESTADDRL;         //目的地址低8位
  서명 없음 차어블렌 :3;     //长度域模式选择
  서명 없음 차어LENH :5;     //传输长度高字节
  서명 없음 차어LENL :8;     //传输长度低字节
  서명 없음 차어단어 크기 :1;     //字节(byte)或字(word)传输
  서명 없음 차어TMODE :2;     //传输模式选择
  서명 없음 차어트릭 :5;     //触发事件选择
  서명 없음 차어SRCINC :2;     //源地址增量:-1/0/1/2
  서명 없음 차어DESTIC :2;     //目的地址增量:-1/0/1/2
  서명 없음 차어IRQMASK :1;     //中断屏蔽
  서명 없음 차어M8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  서명 없음 차어우선순위:2;     //优先级
}DMA_CFG;
#pragma 비트필드=기본

/*系统时钟初始化
-------------------------------------------------------*/
공허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 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  LED4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
공허Uart0Init(서명 없음 차어스톱비트,서명 없음 차어패리티)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  첫 번째 선택적 위치로 UART0를 선택하는데, 즉 RXD에서 P0.2, TXD에서 P0.3으로 변환합니다
   
   U0CSR =0xC0;                    UART 모드로 설정하고 수용기를 활성화합니다
   
   U0GCR =11;
   U0보드 =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| 패리티;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
공허  Uart0Send(서명 없음 차어데이터)
{
  반면(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = data;
}

/*UART0发送字符串
-------------------------------------------------------*/
공허Uart0SendString(서명 없음 차어*s)
{
  반면(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
공허주요(공허)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  서명 없음 차어sourceString[]="나는 소스스트링이야!";      //源字符串
  서명 없음 차어destString[크기(출처 스트링)] ="내가 destString이야!";  //目的字符串
  
  차어나는;
  차어오류=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(서명 없음 차어)((서명 없음 지능)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(서명 없음 차어)((서명 없음 지능)&sourceString);
   
  dmaConfig.DESTADDRH=(서명 없음 차어)((서명 없음 지능)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(서명 없음 차어)((서명 없음 지능)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(서명 없음 차어)((서명 없음 지능)크기(출처스트링) >>8);  //传输长度
  dmaConfig.LENL=(서명 없음 차어)((서명 없음 지능)크기(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            트리거 없음 (수동 트리거로 이해할 수 있음)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(서명 없음 차어)((서명 없음 지능)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(서명 없음 차어)((서명 없음 지능)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  반면(! (DMAIRQ&0x01));               //等待传输结束
  
  에 대해(i=0; 나는 <크기(sourceString); i++)   //校验传输的正确性
  {
    만약(출처 문자열!=destString)
      error++;
  }
  
  만약(오류==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("정답!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  그렇지 않으면
    Uart0SendString("에러!");

  반면(1);
}

DMA 사용의 기본 과정은 다음과 같습니다:DMA 구성설정 활성화DMA 전송 → 완료될 때까지 기다립니다.다음은 각각 다음과 같습니다:

  (1) DMA 구성: 우선 DMA는 구성되어야 하지만, DMA의 구성은 특수합니다: 일부 SFR에 직접 값을 할당하는 대신, 외부에서 구조를 정의하고 값을 할당한 뒤, 이 구조의 첫 주소에서 상위 8비트를 할당합니다DMA0CFGH이 숫자는 8자리 이하 숫자가 됩니다DMA0CFGL。 (구성 구조에 대한 자세한 설명은 CC2430 중국어 매뉴얼을 참고하시기 바랍니다)

CC2430 팁
위 소스 코드에서 구성 구조체의 정의에 대해 명확히 할 두 가지 사항이 있습니다:
(1) 비트 도메인
이 구조체를 정의할 때는 많은 콜론(:)이 사용되고, 그 뒤에 숫자가 붙는데, 이를 "비트 필드"라고 부릅니다:
비트 도메인이란 정보가 저장할 때 전체 바이트를 차지할 필요가 없고, 몇 개 또는 하나의 이진 비트만 차지한다는 뜻입니다. 예를 들어, 스위칭 양을 저장할 때는 0과 1 두 가지 상태만 존재하며, 1비트 이진법을 사용할 수 있습니다. 저장 공간을 절약하고 처리를 용이하게 하기 위해 C는 "비트 필드" 또는 "비트 필드"라는 데이터 구조를 제공합니다. 이른바 '비트 필드'는 바이트 내 이진수를 여러 영역으로 나누고 각 영역의 비트 수를 설명합니다. 각 도메인은 도메인 이름을 가지고 있어 프로그램 내에서 도메인 이름에 따른 작업을 할 수 있습니다. 이로 인해 여러 가지 다른 객체를 바이트 이진 비트필드로 표현할 수 있습니다.
(2) 추상적 공통 함수
주의 깊은 독자라면 struct에 값을 할당할 때 종종 16비트 부호 없는 int 타입 값을 두 개의 8비트 부호 없는 char 타입 값에 할당하는 것을 알게 될 것입니다.
dmaConfig.SRCADDRH=(서명 없음 차어)((서명 없음 지능)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(서명 없음 차어)((서명 없음 지능)&sourceString);

이러한 자주 사용되는 함수의 경우, 다음과 같이 일반 함수로 추상화하는 것이 낫습니다:
#define SET_WORD(destH, destL, 단어)
    하다{
       destH=(서명 없음 차어)((서명 없음 지능)단어 >>8);     
       destL=(서명 없음 차어)((서명 없음 지능)단어);
    }반면(0)

앞으로 비슷한 분할 연산을 수행해야 할 때는 다음과 같이 직접 호출할 수 있습니다:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) 설정 활성화: 먼저, 구조물의 첫 번째 주소&dmaConfig상위 8비트와 저음 8비트는 각각 SFR에 할당됩니다DMA0CFGH그리고DMA0CFGL(여기서 0은 채널 0의 구성을 나타내며, CC2430은 5개의 DMA 채널을 포함하며, 여기서는 채널 0을 사용합니다.) 네DMAARM.0채널 0의 구성을 가능하게 하기 위해 값을 1로 할당하여 채널 0이 작업 모드가 되도록 하세요.

  (3) DMA 전송 활성화:오른쪽DMAREQ.0채널 0의 DMA 전송을 시작하기 위해 값을 1로 할당하세요.

  (4) DMA가 전송될 때까지 기다립니다:채널 0의 DMA가 전송된 후 인터럽트가 트리거되고, 채널 0의 인터럽트 플래그가 트리거됩니다DMAIRQ.0자동으로 1로 설정됩니다. 두 문자열의 각 문자를 비교한 후 검증 결과가 PC로 전송됩니다.

(4) 실험 결과

먼저 시리얼 포트 디버깅 도구를 열고 CC2430 디버깅을 시작하면 다음 화면이 나타납니다:

당신은 찾을 것입니다destString내용이 완전히 공개되었습니다출처스트링가득 찬 채움.

끝~

3. 결론

이 섹션에서는 DMA의 사용법을 소개하는데, 매우 간단하지만 기본 용도를 이해하셨을 것이고, 앞으로 복잡한 사용 상황을 마주할 때 차분하게 분석할 수도 있습니다.

아무리 데스크톱이 좋아도 멈추고, 임베디드 시스템도 결국 정체됩니다. 다음 절에서는 체계적인 리셋의 매우 효과적인 방법인 감시견(watchdogs)을 소개할 것입니다.






이전의:Zigbee Journey (6): 여러 중요한 CC2430 기본 실험 - ADC 단일 샘플링
다음:지그비 여정 (8): 여러 중요한 CC2430 기본 실험 - 감시자
면책 조항:
Code Farmer Network에서 발행하는 모든 소프트웨어, 프로그래밍 자료 또는 기사는 학습 및 연구 목적으로만 사용됩니다; 위 내용은 상업적 또는 불법적인 목적으로 사용되지 않으며, 그렇지 않으면 모든 책임이 사용자에게 부담됩니다. 이 사이트의 정보는 인터넷에서 가져온 것이며, 저작권 분쟁은 이 사이트와는 관련이 없습니다. 위 내용은 다운로드 후 24시간 이내에 컴퓨터에서 완전히 삭제해야 합니다. 프로그램이 마음에 드신다면, 진짜 소프트웨어를 지원하고, 등록을 구매하며, 더 나은 진짜 서비스를 받아주세요. 침해가 있을 경우 이메일로 연락해 주시기 바랍니다.

Mail To:help@itsvse.com