LPC2478(7)ADC

目录

1、开发环境

2、原理图

3、相关寄存器

3.1、A/D控制寄存器( AD0CR - 0xE003 4000)

3.2、A/D全局数据寄存器( AD0GDR - 0xE003 4004)

3.3、A/D状态寄存器( ADSTAT - 0xE003 4030)

3.4、A/D中断使能寄存器( ADINTEN - 0xE003 400C)

3.5、A/D数据寄存器( ADDR0~ADDR7 - 0xE003 4010~0xE003 402C)

4、触发方式

5、代码实现


1、开发环境

LPC-2478STK+IAR+JINK

2、原理图

对应的是ADC0[7]-> P0[13],PINSEL0应设置为11

3、相关寄存器

A/D 转换器的基本时钟由 APB 时钟(PCLK)提供。 每个转换器包含一个可编程的分频器,它可将这个时钟调整为逐次逼近转换所需的 4.5MHz(最大)。完全满足精度要求的转换需要 11 个这样的时钟。

3.1、A/D控制寄存器( AD0CR - 0xE003 4000)

3.2、A/D全局数据寄存器( AD0GDR - 0xE003 4004)

3.3、A/D状态寄存器( ADSTAT - 0xE003 4030)

3.4、A/D中断使能寄存器( ADINTEN - 0xE003 400C)

3.5、A/D数据寄存器( ADDR0~ADDR7 - 0xE003 4010~0xE003 402C)

4、触发方式

如果 ADCR 的 BURST 位为 0 且 START 字段的值包含在 010-111 之内,那么当所选管脚或定时器匹配信号发生跳变时 A/D 转换器启动一次转换。也可选择在 4 个匹配信号中任何一个的指定边沿转换,或者在 2 个捕获/匹配管脚中任何一个的指定边沿转换。将所选端口的管脚状态或所选的匹配信号与 ADCR 的位 27 异或来作为边沿检测逻辑。

5、代码实现

#include <nxp/iolpc2478.h>
#include <intrinsics.h>
typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int  u64;
typedef unsigned long  u32;

#ifndef NULL
#define NULL ((void*)0)
#endif

/* P1[13] 低电平导通 */
#define led1            13
/* P1[18] 低电平导通 */
#define led2            18
/* P2[19] 按下低电平,悬空高电平 */
#define but1            19
/* P2[21] 按下低电平,悬空高电平 */
#define but2            21

#define led1_on         (FIO1CLR |= 0x01 << led1)
#define led1_off        (FIO1SET |= 0x01 << led1)
#define led2_on         (FIO1CLR |= 0x01 << led2)
#define led2_off        (FIO1SET |= 0x01 << led2)

void enable_fast_port()
{
  SCS |= 1 << 0;
}
void gpio_init()
{
  PINSEL2 &= ~(0x03 << led1*2);  
  FIO1DIR &= ~(0x01 << led1);  
  FIO1DIR |=   0x01 << led1;   
  led1_off;   
  PINSEL3 &= ~(0x03 << ((led2 % 16)*2));  
  FIO1DIR &= ~(0x01 << led2);  
  FIO1DIR |=   0x01 << led2;   
  led2_off; 
  
  PINSEL5 &= ~(0x03 << ((but1 % 16)*2));  
  PINSEL5 |=   (0x0 << ((but1 % 16)*2));  
  FIO2DIR &= ~(0x01 << but1); 
  
  PINSEL5 &= ~(0x03 << ((but2 % 16)*2));  
  PINSEL5 |=   (0x0 << ((but2 % 16)*2));  
  FIO2DIR &= ~(0x01 << but2); 
}
void led1_reverse(void)
{   
  if ((FIO1SET & (0x01 << led1)) == 0) 
    led1_off;
  else
    led1_on;						
}

void led2_reverse(void)
{   
  if ((FIO1SET & (0x01 << led2)) == 0)
    led2_off;
  else 
    led2_on;
}

u32 irq_result;
void adc_irq(void)
{
  irq_result = AD0GDR_bit.RESULT;
  VICADDRESS 	= 0x00;		
}
void VIC_SetVectoredIRQ(void(*pIRQSub)(), unsigned int Priority,
                        unsigned int VicIntSource)
{
unsigned long volatile *pReg;
  // load base address of vectored address registers
  pReg = &VICVECTADDR0;
  // Set Address of callback function to corresponding Slot
  *(pReg+VicIntSource) = (unsigned long)pIRQSub;
  // load base address of ctrl registers
  pReg = &VICVECTPRIORITY0;
  // Set source channel and enable the slot
  *(pReg+VicIntSource) = Priority;
  // Clear FIQ select bit
  VICINTSELECT &= ~(1<<VicIntSource);
}
__irq __arm void IRQ_Handler (void)
{
void (*interrupt_function)();
unsigned int vector;

  vector = VICADDRESS;     // Get interrupt vector.
  interrupt_function = (void(*)())vector;
  if(interrupt_function != NULL)
  {
    interrupt_function();  // Call vectored interrupt function.
  }
  else
  {
    VICADDRESS = 0;      // Clear interrupt in VIC.
  }
}
void adc_irq_init(u8 channel)
{
  if (channel > 7) 
    channel = 0;
  VIC_SetVectoredIRQ(adc_irq,0,VIC_AD0);
  VICINTENABLE |= 1 << VIC_AD0;	
  ADINTEN = (1 << channel);
  __enable_interrupt();	
}
void adc_channel_set(u8 channel)
{
  if (channel > 7) 
    channel = 0;
  switch (channel){
    case 0:PINSEL1_bit.P0_23 = 0x01;break;

    case 1:PINSEL1_bit.P0_24 = 0x01;break;
        
    case 2:PINSEL1_bit.P0_25 = 0x01;break;
        
    case 3:PINSEL1_bit.P0_26 = 0x01;break;
        
    case 4:PINSEL3_bit.P1_30 = 0x03;break;
        
    case 5:PINSEL3_bit.P1_31 = 0x03;break;
        
    case 6:PINSEL0_bit.P0_12 = 0x03;break;
        
    case 7:PINSEL0_bit.P0_13 = 0x03;break;
  }
}
void adc_software_init(u8 channel)
{
  u8 div;
  PCONP  |= 1 << 12;	
  adc_channel_set(channel);
  div = 1;/* 1MHz/1=1MHz*/
  AD0CR_bit.CLKDIV = div;
  AD0CR_bit.BURST = 0;
  AD0CR_bit.START = 0;
  AD0CR_bit.PDN = 1;
}

void adc_handware_init(u8 channel)
{
  u8 div;

  PCONP  |= 1 << 12;	
  adc_channel_set(channel);
  div = 1;/* 1MHz/1=1MHz*/
  AD0CR_bit.CLKDIV = div;
  AD0CR_bit.BURST = 1;
  AD0CR_bit.START = 0;
  AD0CR_bit.PDN = 1;
}

void adc_mat_init(u8 channel)
{
  u8 div;

  PCONP  |= 1 << 12;	
  adc_channel_set(channel);
  div = 1;/* 1MHz/1=1MHz*/
  AD0CR_bit.CLKDIV = div;
  AD0CR_bit.BURST = 0;
  AD0CR_bit.CLKS = 0;
  AD0CR_bit.START = 6;
  AD0CR_bit.PDN = 1;
  AD0CR_bit.EDGE = 1;
  AD0CR_bit.SEL = 1<<channel;
  
  PCONP |= 1 << 2;
  T1MCR = 0x02;
  T1EMR = (3 << 4);
  T1MR0 = 1000000;
  T1TCR = 0x01;
}

u32 GetADC(u8 channel)
{
	u32 result;
	if (channel > 7) 
      channel = 0;
    
	AD0CR_bit.SEL = 1 << channel;
    
	AD0CR_bit.START  = 0x01;
	
	while (!AD0GDR_bit.DONE);
	
	AD0CR_bit.START = 0x0;
	
	if (AD0GDR_bit.OVERUN == 1) 
      return 0;

	result = AD0GDR_bit.RESULT;
    
	return result;	
}
//#define adc_SW_Trigger_Enable
//#define adc_HW_Trigger_Enable
#define adc_MAT_Trigger_Enable
#define irq_enable
int main(void)
{
  enable_fast_port();
  gpio_init();
  
#ifdef adc_SW_Trigger_Enable
  adc_software_init(7);
#endif
  
#ifdef adc_HW_Trigger_Enable
  adc_handware_init(7);
#endif
  
#ifdef adc_MAT_Trigger_Enable
  adc_mat_init(7);
#endif
  
#ifdef irq_enable
  adc_irq_init(7);
  while(1){}
#else
  while(1){
    GetADC(7);
  }
#endif
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值