在线时间0 小时
UID2081288
注册时间2014-3-24
NXP金币0
该用户从未签到
新手上路

- 积分
- 7
- 最后登录
- 1970-1-1
|
下面是参考MPC5554 微处理器揭秘写的MPC5644A ADC代码
原例程是定义了CQUEUE0[4] 四个转换通道,现在是要转换6个通道,即定义了CQUEUE0[6],结果存放在
RQUEUE0[24]中,DMA中有做相应更改,但读取结果很奇怪,按道理RQUEUE0中应只有12个结果(包含时间戳),
而最终得到的结果是满的。
求高手解答,折腾几天了
附件是原书上例程,结果正确
#include "typedefs.h"
#include "MPC5644A.h"
//CFIFO0_PUSH 寄存器为32位宽
#define CFIFO0_PUSH 0xFFF80010
//RFIFO0_POP 寄存器地址为其低16位的地址,这是因为低16位才是结果数据,高16位为0000,不包含任何数据
#define RFIFO0_POP 0xFFF80032
volatile unsigned int CQUEUE0[6]={0u ,0u ,0u ,0u ,0u ,0u }; /* 32位CFIFO 0的队列变量定义 */
volatile unsigned short int RQUEUE0[24]={0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u ,0u };
/* 16位 RFIFO 0的队列变量定义 */
void SysClock_Init(void);
void EDMA_Init_fcn(void);
void EQADC_Init_fcn(void);
/*---------------------------------------------------------------------------------*/
/* EDMA Control Register (EDMA_CR) */
/*---------------------------------------------------------------------------------*/
void SysClock_Init(void)
{
FMPLL.ESYNCR1.B.CLKCFG = 0X7; /* Change clk to PLL normal mode from crystal */
/*工作在原模式 */
/* ----------------------------------------------------------- */
/* FMPLL Synthesizer Status Register (FMPLL_SYNSR) */
/* ----------------------------------------------------------- */
FMPLL.SYNCR.R = 0x16080000; /* Initial values: PREDIV=1, MFD=12, RFD=1 */
while (FMPLL.SYNSR.B.LOCK != 1) {}; /* Wait for FMPLL to LOCK */
FMPLL.SYNCR.R = 0x16000000; /* Final value for 64 MHz: RFD=0 */
}
void EDMA_Init_fcn(void)
{ EDMA.CR.R = 0x0000E400;
//DMA使能请求寄存器(DMAERQH,DMAERQL)
EDMA.ERQRH.R = 0x00000000; //DMA使能请求寄存器高(Channels 32-63)
EDMA.ERQRL.R = 0x000000FF; //DMA使能请求寄存器低(Channels 0-31)
//DMA使能错误中断寄存器(DMAEEIH,DMAEEIL)
EDMA.EEIRH.R = 0x00000000; //DMA错误中断使能寄存器高(Channels 32-63)
EDMA.EEIRL.R = 0x00000000; //DMA错误中断使能寄存器低(Channels 0-31)
/*---------------------------------------------------------------------------------*/
/* Transfer control descriptor (TCD)
* 传输控制描述符,包含明说明了开始和完成一次数据传输所需要的全部属性 (32字节)
* Datasheet P166 书 P16 */
/*---------------------------------------------------------------------------------*/
//CFIFO 00对应的传输控制描述符 - CH0
EDMA.TCD[0].SADDR = (volatile unsigned int) &CQUEUE0; // 取CQUEUE0[6]首地址作为源数据读入的位置
EDMA.TCD[0].DADDR = CFIFO0_PUSH; // 目标数据写入的位置
EDMA.TCD[0].SMOD = 0x00; // 源地址模数
EDMA.TCD[0].DMOD = 0x00; // 目标地址模数
EDMA.TCD[0].DSIZE = 0x02; // 目标传输大小:32位
EDMA.TCD[0].SSIZE = 0x02; // 源传输大小:32位
EDMA.TCD[0].SOFF = 0x4; // 有符号源偏移量为4,下一个源地址等于(SADDR+4)
EDMA.TCD[0].NBYTES = 0x00000004; // 一次内层次要循环传输的字节数
EDMA.TCD[0].SLAST = 0xFFFFFFE8; // 末级有符号源地址调整值 -24
EDMA.TCD[0].DOFF = 0x0; // 有符号目标地址偏移量
EDMA.TCD[0].DLAST_SGA = 0x0; // 末级有符号目标地址调整值
EDMA.TCD[0].BITER = 0x0006; // 主循环迭代计数初始值
EDMA.TCD[0].CITER = 0x0006; // 主循环迭代计数当前值
EDMA.TCD[0].BWC = 0x00; // 带宽控制:无DMA传输暂停
EDMA.TCD[0].MAJORLINKCH = 0x00; // 主链接通道号
EDMA.TCD[0].MAJORE_LINK = 0x0; // 主通道链接操作:禁止
EDMA.TCD[0].DONE = 0x00; // 通道服务完成
EDMA.TCD[0].ACTIVE = 0x00; // 通道活跃
EDMA.TCD[0].E_SG = 0x0; // 分散/聚合操作:禁止
EDMA.TCD[0].D_REQ = 0x0; // 主循环完成时,禁止通道请求
EDMA.TCD[0].INT_HALF = 0x0; // 次要循环计数中断:禁止
EDMA.TCD[0].INT_MAJ = 0x0; // 主循环完成中断:禁止
EDMA.TCD[0].START = 0x00; // 通道START位
//RFIFO 00对应的传输控制描述符 - CH1
EDMA.TCD[1].SADDR = RFIFO0_POP; // 源数据读入的位置
EDMA.TCD[1].DADDR = (volatile unsigned int) &RQUEUE0; // 目标数据写入的位置
EDMA.TCD[1].SMOD = 0x00; // 源地址模数
EDMA.TCD[1].DMOD = 0x00; // 目标地址模数
EDMA.TCD[1].DSIZE = 0x01; // 目标传输大小:16位
EDMA.TCD[1].SSIZE = 0x01; // 源传输大小:16位
EDMA.TCD[1].SOFF = 0x0; // 有符号源偏移量为4,下一个源地址等于(SADDR+4)为4为4,下一个源地址等于(SADDR+4)
EDMA.TCD[1].NBYTES = 0x00000002; // 一次内层次要循环传输的字节数
EDMA.TCD[1].SLAST = 0x0; // 末级有符号源地址调整值
EDMA.TCD[1].DOFF = 0x2; // 有符号目标地址偏移量
EDMA.TCD[1].DLAST_SGA = 0xFFFFFFD0; // 末级有符号目标地址调整值 -36=-18*2
EDMA.TCD[1].BITER = 0x0018; // 主循环迭代计数初始值
EDMA.TCD[1].CITER = 0x0018; // 主循环迭代计数当前值
EDMA.TCD[1].BWC = 0x00; // 带宽控制:无DMA传输暂停
EDMA.TCD[1].MAJORLINKCH = 0x00; // 主链接通道号
EDMA.TCD[1].MAJORE_LINK = 0x0; // 主通道链接操作:禁止
EDMA.TCD[1].DONE = 0x00; // 通道服务完成
EDMA.TCD[1].ACTIVE = 0x00; // 通道活跃
EDMA.TCD[1].E_SG = 0x0; // 分散/聚合操作:禁止
EDMA.TCD[1].D_REQ = 0x0; // 主循环完成时,禁止通道请求
EDMA.TCD[1].INT_HALF = 0x0; // 次要循环计数中断:禁止
EDMA.TCD[1].INT_MAJ = 0x0; // 主循环完成中断:禁止
EDMA.TCD[1].START = 0x00; // 通道START位
}
void EQADC_Init_fcn(void)
{
CQUEUE0[0] = 0x00022A00; //通道42 VRH
CQUEUE0[1] = 0x00022900; //通道40 VRH-BRL/2
CQUEUE0[2] = 0x00022A00;
CQUEUE0[3] = 0x00022900;
CQUEUE0[4] = 0x00022A00; //通道41 VRL
CQUEUE0[5] = 0x80022900; //通道17 外部可测
/* -------- EQADC Module Configuration Register (EQADC_MCR)-------------------*/
EQADC.MCR.R = 0x00000000;
/* EQADC SSI is : Disabled*/
/* Serial Transmission Mode : Disabled*/
/* 先禁止,设置其他寄存器后再启用*/
/* -------- EQADC External Trigger Digital Filter Register (EQADC_ETDFR) -----*/
EQADC.ETDFR.R = 0x00000004;
/* 系统时钟64M 分频系数17*/
/* Digital Filter Length : 265.6 ns */
/* FilterPeriod=(SystemClockPeriod×2DFL)+1(SystemClockPeriod)*/
/* The DFL field specifies the minimum number of system clocks that must be counted by the
digital filter counter to recognize a logic state change.*/
/* -------- NULL Message Send Format Register (EQADC_NMSFR) ------------------*/
EQADC.NMSFR.R = 0x00000000;
/* Null Message Format value : 0 */
/* 设置空消息的格式为0u*/
/* -------- EQADC SSI Control Register (EQADC_SSICR)--------------------------*/
EQADC.SSICR.R = 0x0000070F; //默认的值,控制SDS发送
/* (MDT[0:2])Minimum Delay after Transmission is : 8 FCK */
/* (BR[0:3])System Clock Divide Factor is : 16 */
/* MDT和BR场必须在EQADC SSI(控制位在EQADC.MCR寄存器中)禁止后才能写入*/
/* ---------------------------------------------------------------------------*/
/* EQADC ADC0/1 ON Chip Register Setup */
/*---------------------------------------------------------------------------------*/
/* ---------------------------------------------------------------------------*/
/* EQADC CFIFO Control Registers (EQADC_CFCR) */
/* [MODE1(Software Trigger,Single Scan软件触发,单次扫描)下的配置] */
/*----------------------------------------------------------------------------*/
EQADC.CFCR[0].R = 0x0010;
/* 0:2--保留: 000 */
/* 3--CFEE0: 0 CFIFO0有正常的入口值(不包含扩展模式下的定义入口) */
/* 4--STRME0: 0 禁止CFIFO0进入Streaming模式(该模式下可以重复FIFO的一些命令序列) */
/* 5--SSE0: 0 单次扫描模式下对SSE0写1可置位EQADC_FISR的SSS0位,表明已触发,写0无效 */
/* 6--CFINV0: 0 写1会使相关CFIFO的入口无效 */
/* 7--保留: 0 */
/* 8:11--MODE0: 0001 Software Trigger, Single Scan */
/* 12:15--AMODE0: 0000 禁止CFIFO0 Advance Trigger Operation Mode 0 */
/*----------------------------------------------------------------------------*/
/* Interrupt & DMA Setup */
/*----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/* EQADC Interrupt and DMA Control Registers (EQADC_IDCR) */
/* 数据手册P1030页是将EQADC_IDCR分成3个32位,而MPC5644A.h文件中将IDCR分成6个16位数组 */
/*---------------------------------------------------------------------------------*/
EQADC.IDCR[0].R = 0x0000;
EQADC.CFPR[0].B.CFPUSH = 0x00000802; // Initialize the Time Stamp Control Register
/* --------- EQADC ADC Time Base Counter Register (ADC_TBCR) 地址为0x03------------------*/
/* ADC_TBCR = 0x0000;*/
/* Time base counter value =0 */
/* Writes to TBC_VALUE register load the written data to the counter. 即重置时间基计数值为0 */
EQADC.CFPR[0].B.CFPUSH = 0x00000003; //Initialize the Time Base Counter Register
/*---------EQADC ADC0 Control Register (ADC0_CR) Enable ADC0 地址为0x01-------------------*/
// 0--ADCx_EN: 1 使能ADC,并准备执行AD转换
// 0 禁止ADC
// 1:3--保留: 000
// 4--ADCx_EMUX: 1 使能外部多路复用器
// 0 禁止外部多路复用器
// 5--保留: 0
// 6:7--ADCx_TBSEL: 00 选择内部产生的时间基作为时间戳
// 8--ADCx_ODD_PS: 1 选择奇数分子
// 0 选择偶数分子
// 9--ADCx_CLK_DTY: 1 在奇数分子下,clock high pulse is longer 1 clock cycle than low portion.
// 0 在奇数分子下,clock low interval is longer 1 clock cycle than high pulse.
// 10--ADCx_CLK_SEL: 1 选择系统时钟
// 0 选择分频输出时钟
// 11:15--ADCx_CLK_PS: 11111 默认值,64分频
/* ADC0_CR = 0x801F; 选择分频时钟,Bits 11-15 Clock Prescaler: 64 */
/* Bit 4 External Mux Enable: Disabled(0) */
/* Bit 0 ADC0 Enable ADC0 Ready to Start: Enabled(1) */
EQADC.CFPR[0].B.CFPUSH = 0x00801F01; //Initialize the ADC Control Register 0
/*---------EQADC ADC1 Control Register (ADC1_CR) Enable ADC1 地址也为0x01-------------------*/
/* ADC1_CR = 0x801F; 选择分频时钟,Bits 11-15 Clock Prescaler: 64 */
/* Bit 4 External Mux Enable: Disabled(0) */
/* Bit 0 ADC0 Enable ADC0 Ready to Start: Enabled(1) */
EQADC.CFPR[0].B.CFPUSH = 0x82801F01; //Initialize the ADC Control Register 1
//命令被发送至内部缓冲器1
//分两次分别配置ADC0和ADC1
//This is the last command
EQADC.CFCR[0].B.SSE = 0x01; //对SSE写1 将置位EQADC_FISR的SSS0位,触发CFIFO0 配置ADCx
/*--------EQADC CFIFO Status Register (EQADC_CFSR)---------------------------------*/
/* CFIFO状态 CFSR.B.CFSx值
* 空闲 0b00 0x0
* 保留 0b01 0x1
* 等待触发 0b10 0x2
* 被触发 0b11 0x3
*/
/*-----------------------------------------------------------------------------------*/
// CFIFO0
while(EQADC.CFSR.B.CFS0 == 0x3)
{}
/* Wait for Triggered State to end so we know queue is done */
EQADC.FISR[0].B.EOQF = 0x01;
/* Clear the end of queue flag for the configuration command sets */
//读值为1,表明Entry with asserted EOQ bit was transferred from CFIFOx.
//写1,清除EOQF标志位
EQADC.CFCR[0].R = 0x0000;
/* Disable the queue in preparation for queue mode change */
while(EQADC.CFSR.B.CFS0 != 0x0)
{}
/* Wait for queue to go to IDLE before setting mode to user setting */
/*----------------------------------------------------------------------------*/
/* Interrupt & DMA Setup */
/*----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/* EQADC Interrupt and DMA Control Registers (EQADC_IDCR) */
/* 数据手册P1030页是将EQADC_IDCR分成3个32位,而MPC5644A.h文件中将IDCR分成6个16位数组 */
/*---------------------------------------------------------------------------------*/
EQADC.IDCR[0].R = 0x0303;
EQADC.CFCR[0].R = 0x0010;
}
void main(void)
{
volatile unsigned int i = 0;
SysClock_Init();
EDMA_Init_fcn();
EQADC_Init_fcn();
EQADC.CFCR[0].B.SSE = 0x01; //对SSE写1 将置位EQADC_FISR的SSS0位,触发CFIFO0 配置ADCx
i++;
i++;
i++;
while(1)
{
i++;
}
}
|
|