打印
[新手园地]

自己写的关于ADC差分采集电压!计算有效值 请多多指教!

[复制链接]
4463|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 chinacn1989 于 2011-5-10 16:58 编辑

自己第一次写的东东,什么都不懂。问了很多。。。
终于编译通过,但是还没有仿真!
总觉得问题很多,就发来大家看看。多提点意见!
多指教指教!:handshake
注:笑脸为大写P,不知道怎么回事儿!


主要的构架:
  定时器产生定时中断->AD,然后AD中断(数据处理)->显示

AD中断程序:
将数据采集起来,判断数据的值,是否为零点范围。如果是那么就为第一个点(i=0),记录零点值(ling=0),当ling能被2整除时(第一个零点也能被2整除),计算有效值。当不能被2整除时,ling++;不是零点范围,直接取值。
if(ling%2==0)
   {
    for(n=0;n<i;n++)
     sn=sn+v[n]*v[n];
  vm=sqrt(sn/n);

    i=0; ling=0;
    v=temp;
    i++;
    ling++;
   
   }
   else
    v=temp;
    i++;
    ling++;
   }

计算的是放在零点判断中,因为两个零点才是一个周期,当计算完成时,从第一个点重新开始,零点重新计数(i=0,ling=0)。

主要程序
#include"NUC1xx.h"
#include"stdio.h"
#include"math.h"
#include"display.c"
int i=0,ling=0;  double temp,v[],vm;

void TMR0_IRQHandler(void) // 定时器中断子程序
{
   GPIOA->;PMD.PMD2=0;  //配置ADC5和ADC6为输入引脚,
   GPIOA->;PMD.PMD3=0;
   GPIOA->SCH|=0X00020000;                 //禁止IO数字输入通道
   SYS->GPAMFP.ADC5=1;
   SYS->GPAMFP.ADC6=1;          //PA.5&PA.6作为AD输入
   SYSCLK->CLKSEL1.ADC_S=2;     //选择22M为ADC时钟频率
   SYSCLK->CLKDIV.ADC_N=1;      //ADC时钟源为:22/(ADC_N+1)=11MHz
   SYSCLK->APBCLK.ADC_EN=1;      //使能ADC时钟源
   ADC->ADCR.ADEN=1;             //使能adc模块
   ADC->ADCR.DIFF=1;            //采用差分输入模式
   ADC->ADCR.ADMD=3;         //通道采用连续扫描模式
   ADC->ADCHER.CHEN=0X60;        //选择ADC通道0和1
   ADC->ADSR.ADF=1;              //转换结束标志位清零
   ADC->ADCR.ADIE=1;              //开启AD中断使能
   NVIC_EnableIRQ(ADC_IRQn);    //使能AD中断
   ADC->ADCR.ADST=1;              //开始AD转换
}


void ADC_IRQHandler(void) // AD中断子程序
  {  
   double m,sn=0;int n;   
m=5*sin(1/128);  
    temp=ADC->ADDR[1].RSLT;
if(-m<temp && temp<m)
  {
  if(ling%2==0)
   {
    for(n=0;n<i;n++)
     sn=sn+v[n]*v[n];
  vm=sqrt(sn/n);
    i=0; ling=0;
    v=temp;
    i++;
    ling++;
   
   }
   else
    v=temp;
    i++;
    ling++;
   }
else
   v=temp;
   i++;
  }


int main(void)
{  
   
NVIC_DisableIRQ(TMR0_IRQn); //关闭TIME0中断
outpw(&TIMER0->TCSR ,0 ); //关闭 Timer0                              
/* Step 1. Enable and Select Timer clock source */         
SYSCLK->CLKSEL1.TMR0_S = 4; //设置TIME0时钟频率为22MHz
    SYSCLK->APBCLK.TMR0_EN =1; //使能时钟模块
/* Step 2. Select Operation mode */
TIMER0->TCSR.MODE=1;  //设定定时器工作模式为周期溢出模式
/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
TIMER0->TCSR.PRESCALE=0; // 不进行时钟预分频(设定值:0-255 )
TIMER0->TCMPR = 3456;  // 溢出标志位设定,溢出周期计算
        // (1/22118400)*(0+1)*(3456)= 156.25us  / 6.4KHz=50Hz*128
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1;   //使能time0定时器中断
TIMER0->TISR.TIF = 1;  //定时器中断位清零  
NVIC_EnableIRQ(TMR0_IRQn); //使能定时器中断
/* Step 5. Enable Timer module */
TIMER0->TCSR.CRST = 1;  //计数器重置
TIMER0->TCSR.CEN = 1;  //使能定时器
   TIMER0->TCSR.TDR_EN=1;  //使能time0数据寄存器

    display(vm);
  
  }



display.c


#include "nuc1xx.h"
#include "stdio.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#define w GPIOA->DOUT
#define da GPIOB->DOUT
void delay(int i)              //延时函数
{
   int j,k;
  for(j=0;j<i;j++)
   for(k=0;k<255;j++);
}
void display(double x)             //显示函数
{
   unsigned char num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //定义共阴极数码管字形编码0-9
unsigned char num1[]={0xbf,0x86,0xcb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};  //定义共阴极数码管字型编码0.-9.
int a,b,c,d,e,m;
  
*((volatile unsigned int *)((uint32_t)&GPIOB->;PMD))= (*((volatile unsigned int *)((uint32_t)&GPIOB->;PMD))) | 0X5555;  //定义PB0-PB7为输出端口
GPIOA->;PMD.PMD8=1;            //PB8-11为输出端口
GPIOA->;PMD.PMD9=1;
GPIOA->;PMD.PMD10=1;
GPIOA->;PMD.PMD11=1;
GPIOB->SCH|=0X00000000;            // 使能数字输入
SYS->GPAMFP.I2C0_SDA=0;            //配置GPA8-11为IO口
SYS->GPAMFP.I2C0_SCL=0;
SYS->GPAMFP.I2C1_SDA=0;
SYS->GPAMFP.I2C1_SCL=0;
*((volatile unsigned int *)((uint32_t)&SYS->GPBMFP))= (*((volatile unsigned int *)((uint32_t)&SYS->GPBMFP))) & 0X00;       //GPB为IO输出
m=1000*x;                //将要显示的数据分离成单独的位
    a=m/10000;
    b=(m-a*10000)/1000;
    c=(m-a*10000-b*1000)/100;
    d=(m-a*10000-b*1000-c*100)/10;
    e=m%10;
   
   if(x<10)
     while(1)
  {
     w|=0X0100;  da=num[e]; delay(20);
  w<<1;      da=num[d]; delay(20);
  w<<1;      da=num[c]; delay(20);
  w<<1;    da=num1; delay(20);
  }
   else
     while(1)
        {
     w|=0X0100;  da=num[d]; delay(20);
  w<<1;      da=num[c]; delay(20);
  w<<1;      da=num; delay(20);
  w<<1;    da=num1[a]; delay(20);
  }
   }

附件为接口电路图!

nuc100-64接口图.JPG (692.83 KB )

nuc100-64接口图.JPG

相关帖子

沙发
mcs8098| | 2011-12-20 13:45 | 只看该作者
:lol

使用特权

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

本版积分规则

6

主题

272

帖子

0

粉丝