Este artigo é um artigo espelhado de tradução automática, por favor clique aqui para ir para o artigo original.

Vista: 8951|Resposta: 0

Zigbee Journey (7): Vários experimentos básicos importantes do CC2430 - transmissão DMA

[Copiar link]
Publicado em 30/10/2014 23:22:16 | | | |
1. Conectando os níveis superior e inferior

Na seção anterior, falamos sobre o uso de ADCs e amostramos o sensor de temperatura no chip. Em projetos reais, o número de sensores costuma ser grande e uma grande quantidade de dados de conversão deve ser processada. Mover esses dados vai colocar muita pressão na CPU. Para liberar a CPU e dar energia para fazer outras coisas, o DMA (Acesso Direto à Memória) pode ser útil~

A introdução a seguir é um trecho do Tutorial de Prática de Tecnologia Zigbee:

DMA é uma abreviação de acesso direto à memória, que é "acesso direto à memória". Este é um modo de transmissão de dados de alta velocidade no qual unidades periféricas como transceptores ADC/UART/RF e memória podem trocar dados diretamente sob o controle do "controlador DMA" sem pouca intervenção da CPU. Além de fazer um pouco de processamento no início e no fim da transferência de dados, a CPU pode realizar outros trabalhos durante a transferência. Dessa forma, a CPU e essas interações de dados estão trabalhando em paralelo na maior parte do tempo. Como resultado, a eficiência geral do sistema pode ser muito melhorada.

Como você pode ver na introdução, DMA pode ser usado em muitos cenários. Este experimento envolve apenas a transmissão mais simples de DMA e visa demonstrar o uso geral do DMA. Quanto à aplicação da DMA em outros cenários, ela será implementada em experimentos abrangentes no futuro.

2. Experimento de transmissão DMA(1) Introdução ao experimento

Caracteres do arraysourceStringO conteúdo é transferido para o array de caracteres via DMAdestString, o resultado da conversão é exibido no PC através da porta serial.

(2) Fluxograma de programas

(3) Código-fonte experimental e análise/*
    Descrição Experimental: O conteúdo do sourceString do array de caracteres é transferido para o array de caracteres destString via DMA, e o resultado da conversão é exibido no PC pela porta serial.
*/

#include

#define liderou1 P1_0         
#define P1_1 liderado2         
#define liderou 3 P1_2         
#define P1_3 Led4

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma campos de bits=invertido
typedef struct
{
  sem assinatura CharSRCADDRH;           //源地址高8位
  sem assinatura CharSRCADDRL;           //源地址低8位
  sem assinatura CharDESTADDRH;         //目的地址高8位
  sem assinatura CharDESTADDRL;         //目的地址低8位
  sem assinatura CharVLEN:3;     //长度域模式选择
  sem assinatura CharLENH:5;     //传输长度高字节
  sem assinatura CharLENL:8;     //传输长度低字节
  sem assinatura CharTAMANHO DA PALAVRA:1;     //字节(byte)或字(word)传输
  sem assinatura CharTMODE:2;     //传输模式选择
  sem assinatura CharTRIG:5;     //触发事件选择
  sem assinatura CharSRCINC:2;     //源地址增量:-1/0/1/2
  sem assinatura CharDESTINC:2;     //目的地址增量:-1/0/1/2
  sem assinatura CharIRQMASK :1;     //中断屏蔽
  sem assinatura CharM8:1;     //7或8bit传输长度,仅在字节传输模式下适用
  sem assinatura CharPRIORIDADE:2;     //优先级
}DMA_CFG;
#pragma bitfields=padrão

/*系统时钟初始化
-------------------------------------------------------*/
vazioxtal_init(vazio)
{
  SONO &= ~0x04;            //都上电
  enquanto(! (SONO &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Escolha um oscilador de cristal de 32MHz
  SONO |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
vazioled_init(vazio)
{
  P1SEL =0x00;         P1 é a porta normal de E/S
  P1DIR |=0x0F;         Saída P1.0 P1.1 P1.2 P1.3
  
  liderado1 =1;               //关闭所有LED
  liderado2 =1;
  Liderado3 =1;
  liderado4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
vazioUart0Init(sem assinatura CharStopBits,sem assinatura CharParidade)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Selecione UART0 como a primeira posição opcional, ou seja, RXD para P0.2 e TXD para P0.3
   
   U0CSR =0xC0;                    Coloque no modo UART e ative o aceitador
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Paridade;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
vazio  Uart0Send(sem assinatura Chardados)
{
  enquanto(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = data;
}

/*UART0发送字符串
-------------------------------------------------------*/
vazioUart0SendString(sem assinatura Char*s)
{
  enquanto(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
vaziomain(vazio)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  sem assinatura CharsourceString[]="Eu sou a FonteString!";      //源字符串
  sem assinatura ChardestString[Tamanhode(sourceString)] ="Eu sou o destString!";  //目的字符串
  
  Chareu;
  Charerro=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(sem assinatura Char)((sem assinatura int)&fonteString >>8);     //源地址
  dmaConfig.SRCADDRL=(sem assinatura Char)((sem assinatura int)&sourceString);
   
  dmaConfig.DESTADDRH=(sem assinatura Char)((sem assinatura int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(sem assinatura Char)((sem assinatura int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(sem assinatura Char)((sem assinatura int)Tamanhode(fonteString) >>8);  //传输长度
  dmaConfig.LENL=(sem assinatura Char)((sem assinatura int)Tamanhode(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Sem gatilho (pode ser entendido como acionamento manual)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(sem assinatura Char)((sem assinatura int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(sem assinatura Char)((sem assinatura int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  enquanto(! (DMAIRQ&0x01));               //等待传输结束
  
  para(i=0; eu <Tamanhode(sourceString); i++)   //校验传输的正确性
  {
    se(sourceString!=destString)
      error++;
  }
  
  se(erro==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Correto!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  senão
    Uart0SendString("Erro!");

  enquanto(1);
}

O processo básico de uso da DMA é:Configurar DMAHabilitar configuraçãoComece a transferência DMA → Espere a transferência DMA terminar.Os seguintes são, respectivamente:

  (1) Configurar DMA: Primeiro, a DMA deve ser configurada, mas a configuração da DMA é especial: em vez de atribuir valores diretamente a alguns SFRs, ela define uma estrutura externamente, atribui valores a ela e então atribui os 8 bits superiores do primeiro endereço dessa estruturaDMA0CFGH, dando a ele 8 dígitos inferioresDMA0CFGL。 (Para instruções detalhadas na estrutura de configuração, consulte o manual chinês CC2430)

Dicas CC2430
Há dois pontos a esclarecer sobre a definição de estruturas de configuração no código-fonte acima:
(1) Domínio dos bits
Ao definir essa struct, muitos dois-pontos (:) são usados, seguidos por um número, chamado de "campo de bits":
Domínio de bits significa que a informação não precisa ocupar um byte completo quando armazenada, mas ocupa apenas alguns ou um bit binário. Por exemplo, ao armazenar uma quantidade de comutação, há apenas dois estados, 0 e 1, e você pode usar um bit binário. Para economizar espaço de armazenamento e facilitar o processamento, C fornece uma estrutura de dados chamada "campo de bits" ou "campo de bits". O chamado "campo de bits" divide os binários de um byte em várias regiões diferentes e descreve o número de bits em cada região. Cada domínio possui um nome de domínio, permitindo operações por nome de domínio no programa. Isso permite que vários objetos diferentes sejam representados em um campo binário de bytes.
(2) Funções comuns abstratas
Leitores atentos perceberão que atribuir um valor a uma estrutura frequentemente envolve a atribuição de um valor de tipo int sem sinal de 16 bits a dois valores de tipo de carvão não assinados de 8 bits, da seguinte forma:
dmaConfig.SRCADDRH=(sem assinatura Char)((sem assinatura int)&fonteString >>8);     //源地址
dmaConfig.SRCADDRL=(sem assinatura Char)((sem assinatura int)&sourceString);

Para esse tipo de função frequentemente utilizada, podemos muito bem abstraí-la como uma função geral, da seguinte forma:
#define SET_WORD(destH,destL,word)
    fazer{
       destH=(sem assinatura Char)((sem assinatura int)palavra >>8);     
       destL=(sem assinatura Char)((sem assinatura int)palavra);
    }enquanto(0)

No futuro, sempre que precisar realizar uma operação de divisão semelhante, pode chamá-la diretamente, da seguinte forma:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Habilitar configuração: Primeiro, o primeiro endereço da estrutura&dmaConfigOs 8 bits alto/baixo são atribuídos ao SFR, respectivamenteDMA0CFGHeDMA0CFGL(onde 0 representa a configuração do canal 0, CC2430 contém 5 canais DMA, e o canal 0 é usado aqui). SimDMAARM.0Atribua um valor de 1 para habilitar a configuração do canal 0, de modo que o canal 0 fique em modo de funcionamento.

  (3) Habilitar a transmissão DMA:CertoDMAREQ.0Atribua um valor 1 para iniciar a transmissão DMA do canal 0.

  (4) Aguardar a transmissão do DMA:Após a transmissão do DMA do canal 0, a interrupção será acionada e a bandeira de interrupção do canal 0 será acionadaDMAIRQ.0será automaticamente definido como 1. Cada caractere das duas cadeias é então comparado e o resultado da verificação é enviado ao PC.

(4) Resultados experimentais

Primeiro, abra a ferramenta de depuração de portas seriais, depois inicie a depuração do CC2430, e a seguinte tela aparecerá:

Você vai encontrardestStringO conteúdo foi completamente reveladosourceStringpreenchido.

Pronto~

3. Conclusão

Esta seção introduz o uso do DMA, embora seja muito simples, mas acho que você entendeu o uso básico do DMA e também pode analisá-lo com calma ao enfrentar seus cenários complexos de uso no futuro.

Não importa o quão bom seja um desktop, ele vai travar, e da mesma forma, um sistema embarcado inevitavelmente estagna. Na próxima seção, apresentaremos um método muito eficaz de reinício sistemático: os watchdogs.






Anterior:Zigbee Journey (6): Vários experimentos básicos importantes do CC2430 - ADC amostragem única
Próximo:Zigbee Journey (8): Vários experimentos básicos importantes do CC2430 - watchdogs
Disclaimer:
Todo software, material de programação ou artigos publicados pela Code Farmer Network são apenas para fins de aprendizado e pesquisa; O conteúdo acima não deve ser usado para fins comerciais ou ilegais, caso contrário, os usuários terão todas as consequências. As informações deste site vêm da Internet, e disputas de direitos autorais não têm nada a ver com este site. Você deve deletar completamente o conteúdo acima do seu computador em até 24 horas após o download. Se você gosta do programa, por favor, apoie um software genuíno, compre o registro e obtenha serviços genuínos melhores. Se houver qualquer infração, por favor, entre em contato conosco por e-mail.

Mail To:help@itsvse.com