⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osc.c

📁 SmartARM2200开发平台光盘资料中的所有的源码和测试程序以及应用程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			osc.c
** Last modified Date:  2005-07-31
** Last Version:		1.0
** Descriptions:		Include Font and Oscilloscope Funtion
**
**------------------------------------------------------------------------------------------------------
** Created by:			Ganda
** Created date:		2005-07-31
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/

#include "config.h"

uint8   CH1[1024*4];                            // 通道1缓存深度为4K Bytes
uint8   CH2[1024*4];                            // 通道2缓存深度为4K Bytes 
uint32  CH1Avg, CH2Avg;                         // 通道1、2的电压平均值
uint32  CH1Max, CH1Min, CH1Vpp;                 // 通道1最大值、最小值、平均值
uint32  CH2Max, CH2Min, CH2Vpp;                 // 通道2最大值、最小值、平均值         
uint32  CH1Prd, CH2Prd, CH1Fre, CH2Fre;         // 通道1、2的周期、频率
uint32  CH1Tpt1, CH1Tpt2;                       // 通道1符合触发条件对应的2个采样序号
uint32  CH2Tpt1, CH2Tpt2;                       // 通道2符合触发条件对应的2个采样序号
uint32  CH1TptVal, CH2TptVal;                   // 通道1、2的触发条件数值


void OSC_Initail(void)
{   uint32 dat;

    PINSEL0 = 0x00080000;		                // 设置PWM6连接到P0.9管脚
    //PINSEL1 = 0x01400000;						// 设置P0.27、P0.28连接到AIN0、AIN1
    PINSEL1 = 1<<28;    
    
    UART0_Init();   
    TftInit();
    GUI_PrtPic(0, 0, 239, 319, gImage_root01);

    GUI_Line(224, 268, 224, 315, 0xffff);
    GUI_Line(184, 268, 184, 315, 0xffff);
    GUI_Line(144, 268, 144, 315, 0xffff);
    GUI_Line(104, 268, 104, 315, 0xffff);
    GUI_Line( 64, 268,  64, 315, 0xffff);
    GUI_Line( 24, 268,  24, 315, 0xffff);
    WaveTrackCnt = 0;
    
    GUI_PrtStr(208, 270, "Coupling", 0xfee4, 0x0274); 
    GUI_PrtStr(188, 280, " DC ", 0x0000, 0xffff); 
    
    GUI_PrtStr(168, 273, "Volt/Div", 0xfee4, 0x0274); 
    GUI_PrtStr(148, 275, " 0.42V ", 0x0000, 0xffff); 
    
    GUI_PrtStr(128, 270, "Time/Div", 0xfee4, 0x0274); 
    GUI_PrtStr(108, 275, " 60uS ", 0x0000, 0xffff); 
    
    GUI_PrtStr( 88, 274, "TrigVolt", 0xfee4, 0x0274); 
    sprintf(UART0_StrBuff, " %1.2fV ", CH1TptVal*3.3/255);
    GUI_PrtStr( 68, 276, UART0_StrBuff, 0x0000, 0xffff); 
     
    GUI_PrtStr( 48, 280, "Invert", 0xfee4, 0x0274); 
    GUI_PrtStr( 28, 283, " Off ", 0x0000, 0xffff);  

    PWMPR  = 0x00;                              // 不分频,计数频率为Fpclk
    PWMMCR = 0x02;			                    // 设置PWMMR0匹配时复位PWMTC
    PWMMR0 = CYCLE_DATA;                        // 设置PWM周期
    PWMMR6 = DUTY_CYCLE_DATA;	                // 设置PWM占空比
   
    PWMLER = 0x41;			                    // PWMMR0、PWMMR6锁存
    PWMPCR = 0x4000;			                // 允许PWM6输出,单边PWM
    PWMTCR = 0x09;			                    // 启动定时器,PWM使能

    /* 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延) */
    ADCR = (1 << 7)                     |		// SEL = 7 ,选择通道8
           ((Fpclk / 4500000 - 1) << 8) | 		// CLKDIV = Fpclk / 4500000 - 1 ,即转换时钟为4.5MHz
           (1 << 16)                    |		// BURST = 1 ,软件控制转换操作
           (2 << 17)                    | 		// CLKS = 2 ,使用9clock转换, 8位精度
           (1 << 21)                    | 		// PDN = 1 , 正常工作模式(非掉电转换模式)
           (0 << 22)                    | 		// TEST1:0 = 00 ,正常工作模式(非测试模式)
           (1 << 24)                    | 		// START = 1 ,直接启动ADC转换
           (1 << 27);							// EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)					
    dat = ADDR;							        // 读取ADC结果,并清除DONE标志位

}

void OSC_PCM(void)
{   uint32 i, dat;

    /* 示波器数据采集 */
    for(i=0; i<1024*2; i++)
    {
        while( (ADDR&0x80000000)==0 );          // 等待转换结束
        dat = ADDR;                             // 读取ADC结果
        CH1[i] = (dat>>8) & 0xFF;               // 提取AD转换值 
    }
}

/* 触发点锁定 */
uint8 OSC_LockTrigerPoint(void)
{   uint32 i;
    uint32 Avg0, Avg1;


    CH1Tpt1 = 0;
    for(i=250; i<1250; i++)
    {
        Avg0 = (CH1[i+3]+CH1[i+2]+CH1[i+1]+CH1[i+0]) >> 2;  // 对采样值滤波
        Avg1 = (CH1[i+7]+CH1[i+6]+CH1[i+5]+CH1[i+4]) >> 2;  // 对采样值滤波             
        if( (Avg1 - Avg0)>0 )                               // 比较2个采样点,判断是否为上升沿       
        {
            CH1TptVal = 80;
            if((Avg1>CH1TptVal) && (Avg0<CH1TptVal))        // 是否为触发点
            {
                CH1Tpt1 = i;                                // 保存触发点对应的采样序号
                i = 0xffff;                                 // 破坏循环条件,退出for循环       
            }
        }
        i++;                                                // 没有找到触发点则向上继续收缩
    }
    if(i == 1250)                                           // 如果搜索到1240意味无法找到触发点
    {
        CH1Tpt1 = 250;                                      // 给定一个初始值用于显示
        return(0);
    } 
    else
    {
        return(1);
    }
}

/* 寻找周期 */
uint8 OSC_FindPeriod(void)
{   uint32 i;
    uint32 Avg0, Avg1;
    
    if(CH1Tpt1 > 240)                                       // 已经锁定触发点,可以寻找周期
    {
        for(i=CH1Tpt1+8; i<1250; i++)
        {
            Avg0 = (CH1[i+3]+CH1[i+2]+CH1[i+1]+CH1[i+0]) >> 2;
            Avg1 = (CH1[i+7]+CH1[i+6]+CH1[i+5]+CH1[i+4]) >> 2;            
            if( (Avg1 - Avg0)>0 )  
            {
                //CH1TptVal = 128;
                if((Avg1>CH1TptVal) && (Avg0<CH1TptVal))    // 是否为触发点
                {
                    CH1Tpt2 = i;
                    i = 0xffff;
                }
            }
            i++;
        }
    }
    
    if(i == 1250) 
    {
        CH1Tpt2 = 250;                                      // 给定一个初始值用于显示
        return(0);
    } 
    else
    {
        CH1Fre = 422880/(CH1Tpt2-CH1Tpt1);
        return(1);
    }
}

/* 寻找最大值最小值 */
void OSC_CH1MaxMin(void)
{   uint32 i;
    uint32 Max, Min;
    Max = CH1[CH1Tpt1-125];
    Min = CH1[CH1Tpt1-125];
    for(i=CH1Tpt1-125; i<CH1Tpt1+125; i++)    
    {
        if(CH1[i]>Max)
        {
            Max = CH1[i];
        }

        if(CH1[i]<Min)
        {
            Min = CH1[i];
        }
    }
    CH1Max = Max;
    CH1Min = Min;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -