打印

关于2440 内部AD中断程序

[复制链接]
3043|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Rain_ning|  楼主 | 2010-10-11 13:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
写了s3c2440内部ad  中断方式 采集模拟量的代码 结果串口老是打印不出信息  着急啊
大伙帮忙看看  我菜鸟啊 写的可能很多错误 见谅啊

目的:从AIN2采集模拟量 转换后 打印到串口
#define EnableIrq(bit)  rINTMSK &= ~(bit)
#define DisableIrq(bit)  rINTMSK |= (bit)
#define BIT_ADC   (0x1<<31)
static void __irq ADC_ISR(void)
{
int i;
if(rINTPND==BIT_ADC)
{
  ClearPending(BIT_ADC);
  i= (int)rADCDAT0 & 0x3ff;
  Uart_Printf("AIN2=%4d",i);
}
}

__inline void ClearPending(int bit)
{
rSRCPND = bit;
rINTPND = bit;
}

void main(void)
{
     ClearPending(BIT_ADC);
     pISR_ADC=(U32)ADC_ISR;
     EnableIrq(BIT_ADC);
     
     Uart_Printf( "\nADC INPUT Test, press ESC key to exit !\n" ) ;
     preScaler = ADC_FREQ;
     Uart_Printf("ADC conv. freq. = %dHz\n",preScaler);
     preScaler = 50000000/ADC_FREQ -1;
   
     Uart_Printf("PCLK/ADC_FREQ - 1 = %d\n",preScaler);
     
     rADCCON = (1<<14)|(preScaler<<6)|(2<<3);  //setup channel
     rADCCON|=0x1;         //start ADC
     
     
     while( Uart_GetKey() != ESC_KEY ) ;
  DisableIrq(BIT_ADC);
}

相关帖子

沙发
hbicecream| | 2010-10-11 13:32 | 只看该作者
虽然我不用2440,谁便说说
1.你先别管ADC,先让串口打印特定信息再说,然后再加入ADC数据
2.你的Uart_Printf有具体实现吗?包含库了吗?
3.你的ADC使用方式对吗?ADC采样转换时间注意了么?

使用特权

评论回复
板凳
Rain_ning|  楼主 | 2010-10-11 15:09 | 只看该作者
本帖最后由 Rain_ning 于 2010-10-11 15:11 编辑

1.我用的TQ2440开发板   Uart_Printf函数肯定是没有问题的 在main中的那部分可以正常打印
2. 我估计是我中断的问题 我哪里设置的不对啊 中断那部分打印不出来信息
3.我是在官方的程序基础上修改的 他用的是查询方式  我想实验AD的中断方式
这是他的查询方式的代码:
//====================================================================
// File Name : Adc.c
// Function  : TQ2440 ADC Test
// Version   : 1.0
//====================================================================
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#define REQCNT 100
#define ADC_FREQ 2500000
#define LOOP 10000
volatile U32 preScaler;
//==================================================================================  
int ReadAdc(int ch)
{
int i;
static int prevCh=-1;
rADCCON = (1<<14)|(preScaler<<6)|(ch<<3);  //setup channel
if(prevCh!=ch)
{
  rADCCON = (1<<14)|(preScaler<<6)|(ch<<3); //setup channel
  for(i=0;i<LOOP;i++);       //delay to set up the next channel
  prevCh=ch;
}
rADCCON|=0x1;         //start ADC
while(rADCCON & 0x1);       //check if Enable_start is low
while(!(rADCCON & 0x8000));      //check if EC(End of Conversion) flag is high
return ( (int)rADCDAT0 & 0x3ff );
}
//==================================================================================
void Test_Adc(void)
{
int a2=0; //Initialize variables
U32 rADCCON_save = rADCCON;
   
Uart_Printf( "\nADC INPUT Test, press ESC key to exit !\n" ) ;
preScaler = ADC_FREQ;
Uart_Printf("ADC conv. freq. = %dHz\n",preScaler);
preScaler = 50000000/ADC_FREQ -1;
   
Uart_Printf("PCLK/ADC_FREQ - 1 = %d\n",preScaler);
   
while( Uart_GetKey() != ESC_KEY )
{
  a2=ReadAdc(2);  
  Uart_Printf( "AIN2: %04d\n", a2);
  Delay( 200 ) ;
  Delay( 700 ) ;
}
   
rADCCON = rADCCON_save;
Uart_Printf("\nrADCCON = 0x%x\n", rADCCON);
}

2# hbicecream

使用特权

评论回复
地板
hbicecream| | 2010-10-11 16:06 | 只看该作者
晕,刚才没仔细看,你竟然在中断处理程序里串口打印?
你不知道Uart_Printf的函数实现是很复杂的吗?不知道串口收发也要用中断吗?你准备搞中断嵌套?
你把ADC值保存好,出了中断再打印不行吗?

使用特权

评论回复
5
hbicecream| | 2010-10-11 16:07 | 只看该作者
库函数用多了,害人不浅啊

使用特权

评论回复
6
Rain_ning|  楼主 | 2010-10-11 17:19 | 只看该作者
本帖最后由 Rain_ning 于 2010-10-11 17:37 编辑

遵照你刚才说的Uart_printf去掉了 发现我的问题在于进不了中断  我在中断函数里面写了一个变量a=8
在main里面打印a 发现打印出来是a=0  程序根本就没有进到中断服务里面:L

这是我改进后的程序
#define EnableIrq(bit)  rINTMSK &= ~(bit)
#define DisableIrq(bit)  rINTMSK |= (bit)
#define BIT_ADC   (0x1<<31)
volatile U32 ADresult=0;

static void __irq ADC_ISR(void)
{
if(rINTPND==BIT_ADC)
{
  ClearPending(BIT_ADC);
  ADresult= (int)rADCDAT0 & 0x3ff;
}
}

__inline void ClearPending(int bit)
{
rSRCPND = bit;
rINTPND = bit;
}

void main(void)
{
  Uart_Printf( "\nADC INPUT Test, press ESC key to exit !\n" ) ;
  preScaler = ADC_FREQ;
  Uart_Printf("ADC conv. freq. = %dHz\n",preScaler);
  preScaler = 50000000/ADC_FREQ -1;
     
  Uart_Printf("  PCLK/ADC_FREQ - 1 = %d\n",preScaler);
     
   rADCCON = (1<<14)|(preScaler<<6)|(2<<3);  //setup channel
  rADCCON|=0x1;         //start ADC

  ClearPending(BIT_ADC);
  pISR_ADC=(U32)ADC_ISR;
  EnableIrq(BIT_ADC);
  
  Uart_Printf("AIN2=%4d",ADresult);

   while( Uart_GetKey() != ESC_KEY ) ;
     DisableIrq(BIT_ADC);
}

4# hbicecream

使用特权

评论回复
7
Rain_ning|  楼主 | 2010-10-11 19:23 | 只看该作者
经过不懈的努力  发现自己的错误在于不知道ADC的中断有两个子中断  2440的ADC中断包括INT_ADC_S和INT_TC  需要先处理一下子中断INT_ADC_C  再处理INT_ADC
另外要感谢hbicecream的帮助  我才想起来Uart_Printf函数也是需要中断的
所以最好不要在中断服务程序中使用Uart_Printf
最终整理的程序如下:
使用的板子为TQ2440
#define        EnableIrq(bit)                rINTMSK &= ~(bit)
#define        DisableIrq(bit)                rINTMSK |= (bit)
#define        EnableSubIrq(bit)        rINTSUBMSK &= ~(bit)
#define        DisableSubIrq(bit)        rINTSUBMSK |= (bit)
#define BIT_ADC                        (0x1<<31)
#define BIT_SUB_ADC                (0x1<<10)

__inline void ClearPending(int bit)
{
        rSRCPND = bit;
        rINTPND = bit;
}

__inline void ClearSubPending(int bit)
{
        rSUBSRCPND |= bit;       
}

volatile U32 ADresult=0;//该变量做测试用 看能不能进入中断服务程序
volatile U32 ADping=0;

static void __irq ADC_ISR(void)
{
        ADping=8;

        if(rINTPND==BIT_ADC)
        {
                ClearSubPending(BIT_SUB_ADC);
                ClearPending(BIT_ADC);
                ADresult= (int)rADCDAT0 & 0x3ff;
        }
}


__inline void ClearPending(int bit)
{
        rSRCPND = bit;
        rINTPND = bit;
}


void main(void)
{
        while(1)
        {        Uart_Printf( "\nADC INPUT Test, press ESC key to exit !\n" ) ;

                ClearSubPending(BIT_SUB_ADC);//清子中断处理寄存器  因为AD有两个子中断 一个INT_ADC_S  一个INT_TC(即触摸屏中断)
                ClearPending(BIT_ADC);//清中断处理寄存器
               
                EnableSubIrq(BIT_SUB_ADC);//开AD子中断
                EnableIrq(BIT_ADC);//开AD中断
               
                preScaler = ADC_FREQ;//设置AD工作时钟
                Uart_Printf("ADC conv. freq. = %dHz\n",preScaler);
                preScaler = 50000000/ADC_FREQ -1;
            
                Uart_Printf("PCLK/ADC_FREQ - 1 = %d\n",preScaler);
            
                   rADCCON = (1<<14)|(preScaler<<6)|(2<<3);                //setup channel
                  rADCCON|=0x1;        //start ADC                                                                //start ADC
       

       
                pISR_ADC=(U32)ADC_ISR;//设置中断服务程序
               

               
                Uart_Printf("AIN2=%4d/n",ADresult);//打印转换结果
                Uart_Printf("ADping=%4d",ADping);//该变量是我做测试用的 看有没有进入中断服务程序       
       
                 while( Uart_GetKey() != ESC_KEY ) ;//当按下ESC键以后 会停止中断
                        DisableIrq(BIT_ADC);
                        DisableSubIrq(BIT_SUB_ADC);       
        }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:低调 低调~

0

主题

78

帖子

1

粉丝