搜索
bottom↓
回复: 7

跪求,帮忙看一下,MSP430的程序哪里不对啊。

[复制链接]

出0入0汤圆

发表于 2014-7-31 13:24:39 | 显示全部楼层 |阅读模式
我测一个波谷在2.5到1.7v,波峰2.5到3.3V变化的交流信号,频率为50HZ,采用MSP430内部AD,取3个周期,每个周期取500个点,在500个点中取六个最大值取平均,最后把3个周期的最大值取平均之后输出,但是液晶显示不对啊,我怀疑是AD中断的问题,调了好几天,始终发现不料问题,希望大神们帮忙看看,MSP430的初学者,我恳请大家帮帮忙,小弟在这里谢过了。


#include <MSP430.h>
#include "cry1602.h"
typedef unsigned int  uint;
typedef unsigned char uchar;
#define CYCLE  500//一个周期采集数据点数
#define POLE 6           //在峰值采集的点数
uchar shuzi[]={"0123456789"};
uint results[500]={0};
uint index = 0;

/*******************************
        延时函数
*******************************/
void delay1(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}

/***********************************************************
采集一个周期 20ms 的数据,取出六个最大值然后在取平均
***********************************************************/
uint OneCycDate(void)
{
         uint results[CYCLE];
         uint temp;
         uint sum = 0;
         uint j;
         uchar i=0;
         ADC12CTL0 |= ADC12SC;// 开始转换
          _EINT();            //允许全局中断
         delay1(500);
/******************************************************************
         从CYCLE个数据中选取6个峰值,再取平均值
*****************************************************************/         
   for(i=0; i<POLE; i++)
    {
      for(j=i+1; j<CYCLE; j++)//则查找后面的第一个正值与之交换
      {
        if((results[j] >=0x800)& (results < results[j]))
        {
          temp = results;
          results = results[j];
          results[j] = temp;

        }
      }
       sum+=results;
     }
     sum=sum/POLE;
     return sum;
}
/************************************
    取3个周期中的最大值再平均
*************************************/
uint NumCycData(void)
{
         uchar i ;
         uint peak[3];
         
         unsigned long  int tem=0;
         for(i=0; i<3; i++)
         {
          peak = OneCycDate();
          tem+=peak;
         }
         tem=tem/3;
         return tem;
}

/*******************************************
       AD进入转换中断函数
********************************************/

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR (void)
{
  results[index++] = ADC12MEM0;
  if(index == 500)
  {
    ADC12IE = 0x00;
  }
  
}

/***********************************************
将十六进制数据发送到1602,转换成电流显示
***********************************************/
void Trans_val(uint Hex_Val)
{
    uint caltmp;
    uchar ptr[4];
    caltmp = Hex_Val;
    ptr[0] =caltmp/1000;                  
    ptr[1] = caltmp%1000/100;
    ptr[2] = caltmp%100/10;
    ptr[3] =caltmp%10;
    Disp1Char(6,1,shuzi[ptr[0]]);

    Disp1Char(7,1,shuzi[ptr[1]]);

    Disp1Char(8,1,shuzi[ptr[2]]);

    Disp1Char(9,1,shuzi[ptr[3]]);
   }
/************************主函数****************************/
void main(void)
{
  uint ad_data = 0;
  WDTCTL = WDTPW+WDTHOLD;                      //关闭看门狗
  LcdReset();                                 //1602液晶初始化
  P6SEL = 0x00;                              // 使能ADC通道
  ADC12CTL0 = ADC12ON+SHT0_4+MSC;           // 打开ADC,设置采样时间
  ADC12CTL1 = SHP+CONSEQ_2;
  ADC12MCTL0=INCH_0+SREF_0;                 // 使用采样定时器
  
  while(1)
  {
    ADC12IE = 0x01;                           // 使能ADC中断
    ADC12CTL0 |= ENC;                         // 使能转换
    ad_data = NumCycData();
    Trans_val(ad_data);
  }
}

出0入14汤圆

发表于 2014-7-31 23:56:48 来自手机 | 显示全部楼层
这个光看程序能看出来的都是大牛……我一般这种问题都是慢慢试的,你先确定单个测试ad没问题,然后再做复杂的
这种情况不对除去硬件问题,我觉得有两个
1.基本的ad测量就有问题,不过可能性小。
2.时间来不及,50hz取500个点,也就是1ms要取25个ad,从ad的转换速度来说勉强够了,不过加上其他的运算就难说,更不要说整个程序,你要知道你的程序做一个循环花费的时间是多少…
3.算法有问题,这个可能性也看下

出0入0汤圆

发表于 2014-8-1 10:38:17 | 显示全部楼层
--!  不知道LZ想干吗...连续采集的500个点没任何意义啊...怎么不用定时器等间隔采样...

出0入0汤圆

发表于 2014-8-1 10:43:51 | 显示全部楼层
而且  波谷在2.5到1.7v,波峰2.5到3.3V变化的信号  一直大于0的信号怎么可能是交流信号啊...

出0入0汤圆

 楼主| 发表于 2014-8-2 09:54:21 | 显示全部楼层
isakura 发表于 2014-7-31 23:56
这个光看程序能看出来的都是大牛……我一般这种问题都是慢慢试的,你先确定单个测试ad没问题,然后再做复杂 ...

谢谢了啊。我单次周期已经调试好了。

出0入0汤圆

 楼主| 发表于 2014-8-2 09:57:21 | 显示全部楼层
qq910130528 发表于 2014-8-1 10:38
--!  不知道LZ想干吗...连续采集的500个点没任何意义啊...怎么不用定时器等间隔采样... ...

你说的有道理啊,我应该用定时器啊,这几天再弄定时器啊,还有就是我检测的信号是以2.5幅为零点的正弦信号,谢谢了,我是初学者,感谢。

出0入0汤圆

发表于 2014-8-2 11:26:11 | 显示全部楼层
定义了一个全局变量results[500],在OneCycDate又定义了同名局部变量,这样可以吗

uint results[500]={0};

uint OneCycDate(void)
{
         uint results[CYCLE];

还有这句      if((results[j] >=0x800)& (results < results[j]))
这个无下标的results又会是什么

出0入0汤圆

 楼主| 发表于 2014-8-2 19:49:38 | 显示全部楼层
sf49ers 发表于 2014-8-2 11:26
定义了一个全局变量results[500],在OneCycDate又定义了同名局部变量,这样可以吗

uint results[500]={0}; ...

恩恩,谢谢。我再修改,现在可以出结果了,但是还是有许多疑问,如果您方便的话我把程序发给论坛上您看看。要对一个50HZ的交流信号进行最大值的测量,零点是2.5v,幅值是0到5伏。用到430AD.我想去三个周期,每个周期取300个点,然后取平均,显示。大概是1秒踩1500个点,我用的是单通道多次转换。我的疑问是我的程序现在是对的,改变电压液晶显示也有变化,但是的疑问是我的程序是不是只是转换一个周期的信号还是一直在转换啊,如果我想控制三个周期就需要让AD到300个点的时候停,我该怎么控制呢,我选择的是脉冲取样模式。我用的中断是不是转换一次进一次中断啊,希望帮忙解答一下,别的大神也可以,小弟谢谢了。
   

#include<msp430.h>
#include"cry1602.h"
typedef unsigned int  uint;
typedef unsigned char uchar;
#define   Num_of_Results  300
static uint index = 0;

uchar shuzi[] = {"0123456789"};

static uint results[Num_of_Results];    //保存ADC转换结果的数组                          
void Trans_val(uint Hex_Val);
void delay1(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}

/************************主函数****************************/
void main(void)
{
WDTCTL = WDTPW+WDTHOLD;                   //关闭看门狗
LcdReset();                               //复位1602液晶
P6SEL = 0x00;                            // 使能ADC通道
ADC12CTL0 = ADC12ON+SHT0_4+MSC;           // 打开ADC,设置采样时间
ADC12CTL1 = SHP+CONSEQ_2;
ADC12MCTL0=INCH_0+SREF_0;           // 使用采样定时器
ADC12IE = 0x01;                           // 使能ADC中断
ADC12CTL0 |= ENC;                         // 使能转换
ADC12CTL0 |= ADC12SC;                     // 开始转换
_EINT();
LPM0;
}

/*******************************************
函数名称:ADC12ISR
功    能:ADC中断服务函数,取6个最大值,在这里用多次平均的
        计算P6.0口的模拟电压数值
参    数:无      
返回值  :无
********************************************/

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR (void)
{

results[index++] = ADC12MEM0;               // Move results
if(index == Num_of_Results)
{
      uint i;
      uint j;
      uint temp;
      unsigned long sum = 0;
      index = 0;
       for(i=0;i<6;i++)
    {
                  for(j=i+1;j<300;j++)//则查找后面的第一个正值与之交换
             {
                    if((results[j]>0x800)&&(results<results[j]))
                    {
                                    temp=results;
                                    results=results[j];
                                    results[j]=temp;
                    }
             }      
             sum+=results;
      }        
      Trans_val(sum/6);
      delay1(50);
}
}

/*******************************************
     显示函数
********************************************/
void Trans_val(uint Hex_Val)
{
   unsigned long caltmp;
   uchar ptr[4];
   caltmp = Hex_Val;
   ptr[0] =caltmp/1000;
   ptr[1] = caltmp%1000/100;
   ptr[2] = caltmp%100/10;
   ptr[3] =caltmp%10;
   //在液晶上显示变换后的结果
     Disp1Char(6,1,shuzi[ptr[0]]);
     delay1(500);
     Disp1Char(7,1,shuzi[ptr[1]]);
     delay1(500);
     Disp1Char(8,1,shuzi[ptr[2]]);
     delay1(500);
     Disp1Char(9,1,shuzi[ptr[3]]);
     delay1(500);
     
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 11:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表