CC2541 adc 采样没有问题,dma也没有问题,但是在编写dma代码的时候cc2541的开发文档上有句话很容易被忽略,
且配置信息和dma目标数据必须存在XDATA区域,因此在定义dma配置信息结构体时使用需要使用下面的方法
// Place the bitfield members from the most significant bit to the least significant bit.
#pragma bitfields=reversed
typedef struct {
uint8 SRCADDRH;
uint8 SRCADDRL;
uint8 DESTADDRH;
uint8 DESTADDRL;
uint8 VLEN : 3;
uint8 LENH : 5;
uint8 LENL : 8;
uint8 WORDSIZE : 1;
uint8 TMODE : 2;
uint8 TRIG : 5;
uint8 SRCINC : 2;
uint8 DESTINC : 2;
uint8 IRQMASK : 1;
uint8 M8 : 1;
uint8 PRIORITY : 2;
} DMA_DESC;
#pragma bitfields=default
static __xdata DMA_DESC pDesc[2];
static __xdata uint16 adc_dma0[20];
static __xdata uint16 adc_dma1[20];
然后通过下面的函数配置为单次触发,重复批量采样
void dma_channel_init ( DMA_DESC __xdata *dma_p,
uint16 __xdata *dest_adr,
uint8 lenl,
uint8 trig )
{
// Setup DMA configuration.-
dma_p->SRCADDRH = (uint16)(&X_ADCL) >> 8;
dma_p->SRCADDRL = (uint16)(&X_ADCL) & 0x00FF;
dma_p->DESTADDRH = ((uint16)dest_adr) >> 8;
dma_p->DESTADDRL = ((uint16)dest_adr);
dma_p->VLEN = 0;
dma_p->LENH = 0;
dma_p->LENL = lenl; // Tranfer Count
dma_p->WORDSIZE = 1;
dma_p->TMODE = 2;
dma_p->TRIG = trig; // Channel trigger
dma_p->SRCINC = 0;
dma_p->DESTINC = 1;
dma_p->IRQMASK = 0;
dma_p->M8 = 0;
dma_p->PRIORITY = 2;
}
adc 序列采样设置方法
APCFG = (1<<5)|(1<<7);//IO口配置为ADC
ADCCON2 = 0x80|0x30|0x07;//ref AVDD5 12bitENOB AIN7
ADCCON1 &= ~(0x30); //Clear STSEL bits
ADCCON1 |= 0x20; //Set STSEL to Timer 1 channel 0
//ADCCON1 |= 0x13;
timer1_init();
系统使用定时器2 所以触发使用定时器1
void timer1_init(void)
{
T1CTL = 0;
T1CTL = (0x03)<<2;
T1CTL |= 0x02;
T1CCTL0 = 0;
T1CCTL0 = (0x10);
T1CCTL0 |=0x04;
T1CC0H = (0x03);
T1CC0L = (0xe0);
T1CCTL0 |= 0x40;
T1CNTL = (0x01);
}