⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 mcs51,2051,x86系列MCU
💻 C
📖 第 1 页 / 共 2 页
字号:
      return ERR_BADINPUT;
                                             /*Set registers to correct channel*/
   addrDMAByc0_1 = (nChannel == DMA_Channel0 ? DMA0BYC0_1 : DMA1BYC0_1);
   addrDMAByc2 = (nChannel == DMA_Channel0 ? DMA0BYC2 : DMA1BYC2);


   _SetEXRegByte(DMACLRBP, 0x0);             /* Clear the byte pointer flip-flop */
                                             /* Write count, bits 0-7 */
   _SetEXRegByte(addrDMAByc0_1, (BYTE) ( lCount & 0xFF)); 
                                             /* Write count, bits 8-15 */
   _SetEXRegByte(addrDMAByc0_1, (BYTE) ((lCount >> 8)  & 0xFF)); 
                                             /* Write count, bits 16-23 */
   _SetEXRegByte(addrDMAByc2, (BYTE) ((lCount >> 16) & 0xFF)); 

   return ERR_NONE;
}


/*******************************************************************************
   FUNCTION:  void InitDMA()

   DESCRIPTION:
      This function enables the DMA and initializes settings independent of the
      two channels:

         bus arbitration--set to no rotation, external bus master request(HOLD)
               assigned to lowest priority level
         EOP# sampling--set to asynch. (no effect when DMA is used with internal
               peripherals)
         DRQn sampling--set to synch. (no effect when DMA is used with internal
               peripherals)

   PARAMETERS: (none)

   RETURN: (none)

   SYNTAX/USAGE:  
      InitDMA();                             //Initialize DMA peripheral
   
   ASSUMPTIONS:

   REAL/PROTECTED MODE:
*******************************************************************************/
void InitDMA(void)
{
   _SetEXRegByte(DMACLR, 0x0);               /*Resets DMA peripheral*/
   _SetEXRegByte(DMACMD1, 0x0);              /*DMACMD1[7:5]=0: reserved*/
                                             /*DMACMD1[4]=0: disable priority rotation enable*/
                                             /*DMACMD1[2]=0: enable channel's 0 and 1*/
                                             /*DMACMD1[1:0]=0: reserved*/

   _SetEXRegByte(DMACMD2, 0x8);              /*DMACMD2[7:4]=0: reserved*/
                                             /*DMACMD2[3:2]=2: assign HOLD to the lowest*/
                                             /*    priority level*/
                                             /*DMACMD2[1]=0:  EOP# samples input async.*/
                                             /*DMACMD2[0]=0:  DRQn samples input async.*/
}


/*******************************************************************************
   FUNCTION:  void InitDMA1ForSSIXmitterToMem()

   DESCRIPTION:  
      This function prepares DMA channel 1 for transfers between the async. 
      serial port transmitter (channel 0) and memory.  After calling this 
      function, a DMA transfer can be initiated by setting the Target address,
      setting the transfer count, and clearing the hardware request mask
      for this DMA channel.

   PARAMETERS: (none)

   RETURN: (none)

   SYNTAX/USAGE:  
      static char lpsz[]="Hello World";

      InitDMA();                             //Initialize DMA peripheral
      InitDMA1ForSerialXmitter();            //Initialize DMA channel 1
      .
      .
      .
      SetDMATargMemAddr(DMA_Channel1, lpsz); //Set target memory address
                                             //Set transfer count
      SetDMAXferCount(DMA_Channel1, strlen(lpsz) );
      EnableDMAHWRequests(DMA_Channel1);     //Begin transfer at SIO request
      
   
   ASSUMPTIONS:
      InitDMA() has been called to enable the peripheral.
   
   REAL/PROTECTED MODE:
*******************************************************************************/
void InitDMA1ForSerialXmitter(void)
{
   BYTE regDMACfg;
   BYTE regDMAIE;
   BYTE regDMAOvfE;
   
   DisableDMAHWRequests(DMA_Channel1);       /*Disable channel 1 Hardware requests*/
   
   regDMACfg = (_GetEXRegByte(DMACFG) & 0x0F) | 0xA0;
   _SetEXRegByte(DMACFG, regDMACfg);         /*DMACFG[7]=1: mask DMA Acknowledge for channel 1*/
                                             /*DMACFG[6:4]=3: set channel request to SIO*/
                                             /*   channel 0's transmit buffer empty signal*/
                                             /*DMAMSK[3:0]=unmodified: channel 0 settings*/

   _SetEXRegByte(DMAMOD1, 0x9);              /*DMAMOD1[7:6]=0: set to demand data-xfer mode*/
                                             /*DMAMOD1[5]=0: increment target*/
                                             /*DMAMOD1[4]=0: disable autoinitialize buffer-xfer*/
                                             /*   mode*/
                                             /*DMAMOD1[3:2]=2: data is xfer'd from targ. to req.*/
                                             /*DMAMOD1[1]=0: reserved*/
                                             /*DMAMOD1[0]=1: selections for bits 7-2 affect */
                                             /*    channel 1*/
                                             
   _SetEXRegByte(DMAMOD2, 0xD1);             /*DMAMOD2[7]=1: Select 2-cycle data xfer*/
                                             /*DMAMOD2[6]=1: Requestor is in I/O space*/
                                             /*DMAMOD2[5]=0: Target is in memory space*/
                                             /*DMAMOD2[4]=1: Requestor is held constant thru xfer*/
                                             /*DMAMOD2[3]=x: Req. Inc/Dec...see DMAMOD2[4]*/
                                             /*DMAMOD2[2]=0: Target address is modified...see*/
                                             /*   DMAMOD1[5]*/
                                             /*DMAMOD2[1]=0: reserved*/
                                             /*DMAMOD2[0]=1: selections for bits 7-2 affect */
                                             /*    channel 1*/
                                             
   _SetEXRegByte(DMABSR, 0x51);              /*DMABSR[7]=0: reserved*/
                                             /*DMABSR[6]=1: sets req.'s bus size to 8-bit*/
                                             /*DMABSR[5]=0: reserved*/
                                             /*DMABSR[4]=1: sets targ.'s bus size to 8-bit*/
                                             /*DMABSR[3:2]=0: reserved*/
                                             /*DMABSR[0]=1: selections for bits 7-2 affect */
                                             /*    channel 1*/

   _SetEXRegByte(DMACHR, 0x1);               /*DMACHR[7:3]=0: reserved*/
                                             /*DMACHR[2]=0: disable chaining buffer-xfer mode*/
                                             /*DMACHR[1]=0: reserved*/
                                             /*DMACHR[0]=1: selections for bits 7-2 affect */
                                             /*    channel 1*/
   
   regDMAIE = _GetEXRegByte(DMAIEN) & 0xFD;
   _SetEXRegByte(DMAIEN, regDMAIE);          /*DMAIE[7:2]=untouched: reserved*/
                                             /*DMAIE[1]=0: masks channel 1's transfer complete*/
                                             /*   signal from interrupt controller*/
                                             /*DMAIE[0]=untouched:  channel 0 setting*/
                                             
   regDMAOvfE = _GetEXRegByte(DMAOVFE) | 0xC;
   _SetEXRegByte(DMAOVFE, regDMAOvfE);       /*DMAOVFE[7:4]=untouched: reserved*/
                                             /*DMAOVFE[3]=1: all bits of channel 1 req. address */
                                             /*   are inc/dec (see DMAMOD[4])*/
                                             /*DMAOVFE[2]=1: all bits of channel 1 targ. address*/
                                             /*   are inc/dec*/
                                             /*DMAOVFE[1:0]=untouched: channel 0 settings*/                                             

   SetDMAReqIOAddr(DMA_Channel1, TBR0);      /*Sets Req. I/O address to Serial Receiver*/
}


/*******************************************************************************
   FUNCTION:  void interrupt far DMAInterrupt(void)

   DESCRIPTION:  
      This function is called by the DMA unit when it either completes a 
      transfer or (in chaining xfer mode) when a new requester, target, and
      byte count should be written to the device.

   PARAMETERS: (none)

   RETURN: (none)

   SYNTAX/USAGE:  
      regDMAIE = _GetEXRegByte(DMAIEN) | 0x2;   //Enable tc interrupt for channel 0
      _SetEXRegByte(DMAIEN, regDMAIE);          
                                                //Set interrupt routine
      SetIRQVector(DMAInterrupt, 12, INTERRUPT_ISR);
      Enable8259Interrupt(0, IR4);              //Enable slave IR4, DMA interrupt
                  
      NonSpecificEOI();                         //Clear all interrupts

   
   ASSUMPTIONS:
   
   REAL/PROTECTED MODE:
*******************************************************************************/
void interrupt far DMAInterrupt(void)
{
   WORD regDMAIS;
   
   regDMAIS = _GetEXRegByte(DMAIS);          /*Get interrupt status register*/
   
   if (regDMAIS & 0x10)
   {                                         /*Transfer Complete, channel 0*/

      _SetEXRegByte(DMACLRTC, 0x00);         /*Clear transfer complete signal*/
   }


   if (regDMAIS & 0x20)
   {                                         /*Transfer Complete, channel 1*/
      _SetEXRegByte(DMACLRTC, 0x00);         /*Clear transfer complete signal*/
   }
   
   if (regDMAIS & 0x1)
   {                                         /*Chaining Interrupt, channel 0*/

   }

   if (regDMAIS & 0x2)
   {                                         /*Chaining Interrupt, channel 1*/

   }

   NonSpecificEOI();                         /*Send End-Of-Interrupt Signal to Master/Slave*/
}

/* APB_BLOCK_END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -