芯启元 发表于 2026-6-27 11:59:12

83-老梁示波器-CDC虚拟显示,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64

83-老梁示波器-CDC虚拟显示,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64
主程序main.C代码如下(汇编版本在附件中):

/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
/* 本例程为复杂应用程序, 已测试通过, 用户自行理解领悟, 不提供技术支持      */
/*---------------------------------------------------------------------*/

/*************        功能说明        **************

本例程基于STC32G为主控芯片进行编写测试。

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

简单示波器程序。

        实验箱V9.6 2022-12-16.
        学习板、MCU购买途径: 0513-55012928,55012929
        官网1:www.STCMCUDATA.com
        官网2:www.STCAI.com
        论坛: www.STCAIMCU.com

示波器参数:
工作电压: 5.0V。
MCU:      STC32G12K128.
主频:   35MHz。
ADC:      最高采样800KHz 12位,本示波器使用最高采样率500KHz。
模拟带宽: 探头x1大于等于250mV/DIV,探头x10大于等于2.5V/DIV:100KHz。
显示屏:   虚拟显示, 通信方式 USB-CDC。
          水平16格,一格25点,一共400点,存储深度4000点。
          垂直10格,每格25点,一共250点。
时基:   1-2-5步进,50us 100us 200us 500us 1ms 2ms 5ms 10ms 20ms 50ms
                     100ms 200ms 500ms 1s 2s 5s 10s 20s 50s
垂直幅度: 探头x1:   50mV100mV250mV500mV   1V2.5V   5V10V/DIV。
          探头x10: 500mV   1V   2.5V   5V10V   25V50V100V/DIV。
最高输入电压: 探头x1: +-50V,探头x10:+-500V。
触发模式: 上升沿触发,下降沿触发。
触发方式: 自动、标准、单次。

******************************************/


#include        "inc\stc.h"
#include        "EEPROM.h"
#include        "stc.h"
#include        "usb.h"
#include        "uart.h"


/*************        本地常量声明        **************/
#define                K_BaseTimeUp        0x01
#define                K_BaseTimeDn        0x02
#define                K_VoltageUp                0x03
#define                K_VoltageDn                0x04
#define                K_RUN_STOP                 0x05
#define                K_TrigPhase                0x06
#define                K_TrigMode                0x07
#define                K_ShiftLeft                0x08
#define                K_ShiftRight        0x09
#define                K_WaveUp                0x0A
#define                K_WaveDown                0x0B
#define                K_RtnMssage                0x0C

#define                EE_ADDR                0x000000


/*************        IO口声明        **************/

sbit        P_V_A    = P0^0;        //输入增益选择
sbit        P_V_B    = P0^1;        //输入增益选择, CBA   000 001 010 011 100 101 110 111
sbit        P_V_C    = P0^2;        //输入增益选择, 倍数   2   4   101   20 20040 100
//P0.7--T4CLKO: 1000Hz方波输出
//P1.3--ADC12: 波形输入
//P1.1--PWM1N: 垂直位移PWM
//P2.3--PWM8:输出SPWM, 100Hz正弦波.

       

/*************        本地变量声明        **************/
u8        KeyCode;

u8        xdata adc_sample;
u8        edata        tmp;
u8        edata        adc_tmp;
bit        B_ADC_Busy, B_Sample_OK;
u16        adc_wr, adc_rd;
u8        adc;
u8        SampleIndex;
u16        sample_cnt;
bit        B_sample_ms;
u16        SampleTime;
bit        B_Run;
u16        LastDot;
u8        TimeScale;                //时基系数, 10: 10取1, 5: 5取1, 2: 2取1, 1: 1取1
u8        TimeScaleIndex;        //时基系数索引, 0-->10, 1-->5, 2-->2, 3-->1
bit        B_RUN_REQ;                //请求停止

bit        B_TrigPhase;        //默认上升沿触发
u8        TrigMode;

u8        InputIndex;                //幅度档位
u8        AutoTimeCnt;
u8        AutoTime;
u8        pwm1_voltage;

bit        B_Shift;        //移位标志, 停止时切换时基或移位
u16        Shift;                //移位点数
u8        Current_TimeBase;
u8        WriteDelay;        //写入延时

u8        cnt_1ms, cnt_8ms, cnt_32ms;
bit        B_8ms, B_32ms;
bit        B_32ms_rtn;

u16         TxCnt;


/*************        本地函数声明        **************/
void        ShowOscope(void);
void        RealShowOscope(void);
void        Timer0_config(void);
void        Timer4_Config(void);
void        SetSampleTime(void);
void        ShowVoltage(void);

void        ShowTimeBase(void);        //显示时基
void        ShowPhase(void);
void        ShowRunStop(void);        //显示运行状态
void        ShowStartTime(void);

void        ADC_config(void);
void        Compare_Config(void);        //比较器初始化
void        PWMA_config(void);
void        PWMB_config(void);
void        AutoCheck(void);
void         ShowTrigMode(void);
void        ShowRunStop(void);
void        OscStop(void);

void        TxData255(u8 dat);        //转义字符处理
void        TX_write2buff(u8 dat);        //写入发送缓冲,指针+1
void        TrigTx(void);        //触发发送


/****************外部函数声明和外部变量声明 *****************/

/**************************************************************/

//采样索引 SampleIndex   0   1      2      3      4   5      6   7      8   9   10   11   12   13   14   15   16    17    18    19    20
//采样时间/DIV         10us20us   50us100us200us500us   1ms   2ms    5ms10ms   20ms   50ms100ms200ms500ms1s   2s    5s   10s   20s   50s
//第一维3, 是(SampleIndex % 3)的余数, 第二维是缩放系数, 数字为每N个点取一点, 但数字三是指2.5点取一点, 折中方案是每5点取0 2两点.
u8        const         T_TimeScale={        {10,5,2,1},
                                                                {10,5,3,1},
                                                                {10,4,2,1}};

//========================================================================
voiddelay_ms(u16 ms)
{
   u16 i;
       do
       {
               i = MAIN_Fosc / 6000;
                while(--i)        ;
   }while(--ms);
}

/****************主函数 *****************/
void        main(void)
{
        u16        j;

        WTST= 0;
        CKCON = 0;
    EAXFR = 1;        //允许访问扩展寄存器

        P0M1 = 0;        P0M0 = 0;        //设置为准双向口
        P1M1 = 0;        P1M0 = 0;        //设置为准双向口
        P2M1 = 0;        P2M0 = 0;        //设置为准双向口
        P3M1 = 0;        P3M0 = 0;        //设置为准双向口
        P4M1 = 0;        P4M0 = 0;        //设置为准双向口
        P5M1 = 0;        P5M0 = 0;        //设置为准双向口
        P6M1 = 0;        P6M0 = 0;        //设置为准双向口
        P7M1 = 0;        P7M0 = 0;        //设置为准双向口
       
        P0n_push_pull(0x80);        //P0.7 T4CLKO 1000Hz

        uart_init();
        usb_init();
        EA = 1;

        delay_ms(1500);
//        while(DeviceState != DEVSTATE_CONFIGURED)        {        NOP(3);        }
       
        ADC_config();                //ADC初始化
        Compare_Config();        //模拟比较器初始化
        Timer0_config();        //Timer0初始化, 采样
        Timer4_Config();        //Timer4初始化, 输出1000Hz方波.
        PWMA_config();                //PWM控制垂直位移
        PWMB_config();                //输出1000Hz正弦波
       
        EX1 = 1;        //允许中断
        IT1 = 1;        //下降沿中断

        WriteDelay = 0;
        EEPROM_read_n(EE_ADDR, tmp, 6);
        if(tmp == (tmp+tmp+tmp+tmp) ^ 0x55)        //校验
        {
                pwm1_voltage = tmp;
                SampleIndex = tmp;        InputIndex = tmp;        TrigMode = tmp;
                if(TrigMode & 0x80)        B_TrigPhase = 1;
                else                                B_TrigPhase = 0;
                TrigMode &= 0x03;
                if(pwm1_voltage > 250)        pwm1_voltage = 128;        //默认中点
                if(SampleIndex > 20)        SampleIndex= 6;        //默认1ms/div
                if(SampleIndex < 2)                SampleIndex= 6;        //默认1ms/div
                if(InputIndex >= 8)                InputIndex   = 3;        //默认1V/div
                if(TrigMode >= 3)                TrigMode   = 0;        //默认自动触发
                WriteDelay = 0;                //写入延时
        }
        else        //校验没通过
        {
                B_TrigPhase = 0;        //默认上升沿触发
                pwm1_voltage = 128;        //默认中点
                SampleIndex= 6;        //默认1ms/div
                InputIndex   = 3;        //默认1V/div
                TrigMode   = 0;        //默认自动触发
                WriteDelay   = 250;        //写入延时
        }
        PWMA_CCR1L = pwm1_voltage;
       

        B_Shift = 0;
        Shift= 0;
        B_ADC_Busy = 0;
        B_Run = 1;

        ShowTimeBase();                //显示水平时基
        ShowVoltage();                //显示垂直电压
        ShowRunStop();                //显示停止/运行
        ShowPhase();                //显示触发模式(触发边沿)
        ShowTrigMode();                //显示触发方式
       
        KeyCode = 0;

        while (1)
        {
                if(B_8ms)        //8ms
                {
                        B_8ms = 0;
                        AutoCheck();        // 触发超时处理
                }

                if(B_32ms)
                {
                        B_32ms = 0;
                        if(WriteDelay != 0)                //延时写入
                        {
                                if(--WriteDelay == 0)
                                {
                                        tmp = pwm1_voltage;
                                        tmp = SampleIndex;
                                        tmp = InputIndex;
                                        tmp = TrigMode;
                                        if(B_TrigPhase)        tmp |= 0x80;
                                        tmp = (tmp+tmp+tmp+tmp) ^ 0x55;        //校验
                                        EEPROM_SectorErase(EE_ADDR);
                                        EEPROM_write_n(EE_ADDR,tmp,6);
                                }
                        }
                }
                               
                if(B_Run)
                {
                        if(!B_ADC_Busy)                //启动一次采样序列
                        {
                                B_Sample_OK = 0;
                                adc_wr = 0;
                                adc_rd = 0;
                                       if(SampleIndex <= 2)        TimeScale = 1,        TimeScaleIndex = 3;        // 50us/DIV                逐点取        停止时2点间内插9点变10倍采样
                                else if(SampleIndex == 3)        TimeScale = 2,        TimeScaleIndex = 2;        // 100us/DIV        2取1        停止时2点间内插4点变5倍采样
                                else if(SampleIndex == 4)        TimeScale = 4,        TimeScaleIndex = 1;        // 200us/DIV        4取1        停止时2点间内插2.5点变2.5倍采样
                                else                                                 TimeScale = 10,        TimeScaleIndex = 0;        // >=500us/DIV        10取1
                                Current_TimeBase = SampleIndex;
                                B_ADC_Busy = 1;
                                SetSampleTime();        //设置采样时间
                                if(!B_TrigPhase)        CMPCR1 = 0x80 + 0x20;        // 比较器上升沿中断触发, 由于电路原因,与实际相位相反
                                else                                CMPCR1 = 0x80 + 0x10;        // 比较器下降沿中断触发, 由于电路原因,与实际相位相反
                                       if(SampleIndex <= 6)        CMPCR2 = 10;        // <=1ms/DIV (<=4us/sample)                        比较器没有回滞反馈时加上这3句, 兼顾噪声和速度
                                else if(SampleIndex <= 8)        CMPCR2 = 30;        // 2ms 5ms/DIV (8us 20us/sample)        比较器有回滞反馈时注释掉这3句.
                                else                                                 CMPCR2 = 63;        // 2ms 5ms/DIV (8us 20us/sample)
                        }
                        else if(SampleIndex <= 10)        // <=20ms/DIV
                        {
                                if(B_Sample_OK)                //采样完成
                                {
                                        B_Sample_OK = 0;
                                        B_ADC_Busy= 0;
                                        while(!B_32ms_rtn)        {        NOP(5);        }        //USB上传速度太快,则限制其上传速度
                                        B_32ms_rtn = 0;
                                        ShowOscope();        //显示波形
                                        if(B_RUN_REQ || (TrigMode == 2))        OscStop();        //请求停止 或 单次模式 则停止运行
                                }
                        }

                        else if(B_Sample_OK)        //50ms/DIV以上采样, 实时刷新
                        {
                                B_Sample_OK = 0;
                                RealShowOscope();        //实时显示波形
                                if(adc_rd >= 4000)        //结束
                                {
                                        B_ADC_Busy = 0;
                                        if(B_RUN_REQ || (TrigMode == 2))        OscStop();        //请求停止 或 单次模式 停止运行
                                }
                        }
                }
                else        B_ADC_Busy = 0;

                if (RxFlag)                         //当RxFlag为1时,表示已接收到CDC串口数据
                                                                                        //接收的数据大小保存在RxCount里面,每个包最多接收64字节
                                                                                        //数据保存在RxBuffer缓冲区
                {
                        if((RxCount == 4) && (RxBuffer==0xfe) &&(RxBuffer == 0x01) && (RxBuffer == 0xff))
                        KeyCode = RxBuffer;                        //PC下传键代码:FE 01 DAT0 FF
                        uart_recv_done();               //对接收的数据处理完成后,一定要调用一次这个函数,以便CDC接收下一笔串口数据
                }

                if(KeyCode)        //有键按下
                {
                        if(KeyCode == K_RUN_STOP)                //运行/停止
                        {
                                if(!B_Run)                        //已停止则启动
                                {
                                        if(InputIndex >= 8)        InputIndex = 7;
                                        ShowVoltage();
                                        B_Run = 1;                //启动运行
                                        B_RUN_REQ = 0;
                                        ShowRunStop();
                                        B_Shift = 0;
                                        Shift= 0;
                                }
                                else        //运行中
                                {
                                        if(TrigMode != 0)                        OscStop();        //标准模式 单次模式, 则直接停止
                                        else if(SampleIndex >= 11)        OscStop();        //扫描模式, 则直接停止
                                        else        B_RUN_REQ = 1;        //运行中, 无停止请求, 则请求停止
                                }
                        }

                        else if(KeyCode == K_TrigPhase)        //切换上升沿 下降沿触发
                        {
                                B_TrigPhase = ~B_TrigPhase;
                                ShowPhase();
                                B_ADC_Busy = 0;                //切换触发模式重新启动采样(如果没有停止的话)
                                WriteDelay = 250;        //写入延时8秒
                        }

                        else if(KeyCode == K_TrigMode)        //切换触发方式
                        {
                                if(++TrigMode >= 3)        TrigMode = 0;        //0: 自动, 1:普通(标准), 2:单次
                                ShowTrigMode();
                                B_ADC_Busy = 0;                //切换触发模式重新启动采样(如果没有停止的话)
                                WriteDelay = 250;        //写入延时8秒
                        }

                        else if(KeyCode == K_BaseTimeUp)        // 时基+
                        {
                                if(SampleIndex < 20)
                                {
                                        if(B_Run)        //运行中改变时基, 则仅仅改变采样率
                                        {
                                                SampleIndex++;
                                                B_ADC_Busy = 0;
                                                ShowTimeBase();        //显示时基
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                        else if(TimeScaleIndex != 0)        //停止时缩放时基并刷新波形
                                        {
                                                SampleIndex++;
                                                TimeScaleIndex--;        //停止时缩放
                                                Shift = Shift * TimeScale;
                                                TimeScale = T_TimeScale;        //时基系数索引, 0-->10, 1-->5, 2-->2, 3-->1
                                                Shift = Shift / TimeScale;
                                                if(TimeScaleIndex == 0)        Shift = 0;
                                                ShowTimeBase();        //显示时基
                                                ShowStartTime();        //显示波形起始时间
                                                ShowOscope();                //停止则刷新波形
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                }
                        }

                        else if(KeyCode == K_BaseTimeDn)                // 时基-
                        {
                                if(SampleIndex > 2)
                                {
                                        if(B_Run)        //运行中改变时基, 则仅仅改变采样率
                                        {
                                                SampleIndex--;
                                                B_ADC_Busy = 0;
                                                ShowTimeBase();        //显示时基
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                        else if(TimeScaleIndex < 3)        //停止时缩放时基并刷新波形
                                        {
                                                SampleIndex--;
                                                TimeScaleIndex++;        //停止时缩放
                                                Shift = Shift * TimeScale;
                                                TimeScale = T_TimeScale;        //时基系数索引, 0-->10, 1-->5, 2-->2, 3-->1
                                                Shift = Shift / TimeScale;
                                                ShowTimeBase();        //显示时基
                                                ShowStartTime();        //显示波形起始时间
                                                ShowOscope();                //停止则刷新波形
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                }
                        }

                        else if(KeyCode == K_VoltageUp)        //垂直幅度 +
                        {
                                if(B_Run)        //运行中
                                {
                                        if(InputIndex != 0)        //调整垂直幅度
                                        {
                                                InputIndex--;
                                                ShowVoltage();
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                }
                        }
                        else if(KeyCode == K_VoltageDn)        // 垂直幅度 -
                        {
                                if(B_Run)        //运行中
                                {
                                        if(InputIndex < 7)        //调整垂直幅度
                                        {
                                                InputIndex++;
                                                ShowVoltage();
                                                WriteDelay = 250;        //写入延时8秒
                                        }
                                }
                        }

                        else if(KeyCode == K_WaveUp)        //波形上移
                        {
                                if(B_Run)        //运行中
                                {
                                        if(pwm1_voltage != 0)        pwm1_voltage--;
                                        PWMA_CCR1L = pwm1_voltage;
                                        WriteDelay = 250;        //写入延时8秒
                                }
                        }
                        else if(KeyCode == K_WaveDown)        //波形下移
                        {
                                if(B_Run)        //运行中
                                {
                                        if(pwm1_voltage < 250)        pwm1_voltage++;
                                        PWMA_CCR1L = pwm1_voltage;
                                        WriteDelay = 250;        //写入延时8秒
                                }
                        }

                        else if(KeyCode == K_ShiftLeft)        //波形左移
                        {
                                if(!B_Run)        //停止时, 左右移动波形
                                {
                                        Shift++;
                                        TimeScale = T_TimeScale;        //时基系数索引, 0-->10, 1-->5, 2-->2, 3-->1
                                        if(TimeScale == 3)        j = 8000/5 - 400;
                                        else                                j = 4000/TimeScale - 400;
                                        if(Shift >= j)        Shift = j;
                                        ShowStartTime();        //显示波形起始时间
                                        ShowOscope();                //停止则刷新波形
                                }
                        }
                        else if(KeyCode == K_ShiftRight)        //波形右移
                        {
                                if(!B_Run)        //停止时, 左右移动波形
                                {
                                        if(Shift != 0)        Shift--;
                                        TimeScale = T_TimeScale;        //时基系数索引, 0-->10, 1-->5, 2-->2, 3-->1
                                        if(TimeScale == 3)        j = 8000/5 - 400;
                                        else                                j = 4000/TimeScale - 400;
                                        if(Shift >= j)        Shift = j;
                                        ShowStartTime();        //显示波形起始时间
                                        ShowOscope();                //停止则刷新波形
                                }
                        }
                       
                        else if(KeyCode == K_RtnMssage)        //返回参数
                        {
                                ShowTimeBase();                //显示水平时基
                                ShowVoltage();                //显示垂直电压
                                ShowRunStop();                //显示停止/运行
                                ShowPhase();                //显示触发模式(触发边沿)
                                ShowTrigMode();                //显示触发方式
                        }       

                        KeyCode = 0;
                }
        }
}
/**********************************************/



/*************** 转义字符处理 *******************************/
void        TxData255(u8 dat)
{
        if(dat >= 0xfb)
        {
                TX_write2buff(0xfd);        //转义字符
                TX_write2buff(dat & 0x7f);
        }
        else        TX_write2buff(dat);
}


/*************** 装载串口发送缓冲 *******************************/
void TX_write2buff(u8 dat)        //写入发送缓冲,指针+1
{
        TxBuffer = dat;
}

/*************** 触发发送 *******************************/
void        TrigTx(void)        //触发发送
{
        uart_send(TxCnt);        //将要发送的数据保存在TxBuffer缓冲区中, 然后调用uart_send(n)函数触发数据发送,参数为发送的字节数. 一次最多可发送64K,函数内部会自动进行USB分包.
}

/***************** 显示触发方式函数 *****************************/
void ShowTrigMode(void)
{
        TxCnt = 0;
        TX_write2buff(0xfe);                //命令开始
        TX_write2buff(0x06);                //上传触发方式:FE 06 DATA0 FF
        TX_write2buff(TrigMode);        //触发方式。0--自动,1--普通(标准),2--单次。
        TX_write2buff(0xff);                //命令结束
        TrigTx();        //触发发送
}

/***************** 显示运行状态函数 *****************************/
void        ShowRunStop(void)
{
        TxCnt = 0;
        TX_write2buff(0xfe);                //命令开始
        TX_write2buff(0x04);                //上传运行模式:FE 04 DATA0 FF
        TX_write2buff((u8)B_Run);        //运行模式。0--停止,1--运行。
        TX_write2buff(0xff);                //命令结束
        TrigTx();        //触发发送
}


/***************** 停止运行函数 *****************************/
void        OscStop(void)
{
        CMPCR1 = 0x80;                // 关比较器中断
        TR0    = 0;                        //关闭采样定时器1
        B_ADC_Busy = 0;
        B_Run = 0;
        B_RUN_REQ = 0;
        AutoTimeCnt = 0;
        ShowRunStop();
        Shift = 0;                        //停止后可以移位波形
        ShowStartTime();        //显示波形起始时间

        if(Current_TimeBase == 4)        //200us/DIV
        {
                Current_TimeBase = 5;
                TimeScaleIndex   = 1;
        }
        else if(Current_TimeBase == 3)        //100us/DIV
        {
                Current_TimeBase = 5;
                TimeScaleIndex   = 2;
        }
        else if(Current_TimeBase == 2)        //50us/DIV
        {
                Current_TimeBase = 5;
                TimeScaleIndex   = 3;
        }
}


          //采样索引 SampleIndex   0   1      2      3      4   5   6   7      8   9   10   11   12   13   14    15    16    17    18    19    20
          //采样时间单位       0.1us 0.1us   us   us   us   10us10us10us   0.1ms 0.1ms0.1ms   1ms   1ms    1ms10ms10ms10ms0.1s0.1s0.1s   1s
u16 const   StartTimeTable[]= {   4,    8,   2,   4,   8,    2,   4,    8,    2,    4,   8,   2,   4,   8,    2,    4,    8,    2,    4,    8,   2};
          //采样时间/DIV      10us20us   50us100us200us500us   1ms   2ms    5ms10ms   20ms   50ms100ms200ms500ms   1s   2s    5s   10s   20s   50s
u8        const        StartTimeDanWei[]={   2,    2,   3,   3,   3,    4,   4,    4,    5,    5,   5,   6,   6,   6,    7,    7,    7,    8,    8,    8,   9};
//    DAT2:时间单位。0--1ns,1--10ns, 2--100ns, 3--1us,4--10us, 5--100us, 6--1ms,7--10ms, 8--100ms, 9--1s。

/***************** 显示起始时间函数 *****************************/
void ShowStartTime(void)
{
        u16        j;

        TxCnt = 0;
        j = StartTimeTable * Shift;
        TX_write2buff(0xfe);        //命令开始
        TX_write2buff(0x08);        //上传波形左移时间:FE 08 DATA0 DATA1 DATA2 FF
        TxData255((u8)(j >> 8));
        TxData255((u8)j);
        TX_write2buff(StartTimeDanWei);        //时间单位: 时间单位。0--1ns,1--10ns, 2--100ns, 3--1us,4--10us, 5--100us, 6--1ms,7--10ms, 8--100ms, 9--1s。
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送
}



        #define        X_START                40
        #define        Y_START                25
        #define        GridColor        GREEN        //格子颜色
        #define        WaveColor        YELLOW        //波形颜色


//        P_V_C = 0;        P_V_B = 1;        P_V_A = 1;        //输入增益选择, CBA   000 001 010 011 100 101 110 111
                                                                                //                                倍数   2   4   101   20 20040 100
//索引InputIndex      0   1    2    3   4    5    6    7    8   9   10
                        //倍数      1   2    4   1020   40   100200200 200 200
u8        const T_V_GAIN={ 3,0,   1,   2,4,   6,   7,   5,   5,5,5};        //电压幅度
                        //幅度   1V 500m 250m 100m 50m25m10m5m2.5m1m 0.5m
                        //幅度    10V5V2.5V1V500m 250m 100m 50m25m 10m5m

/************** 显示波形函数 ( 50us< 采样 <=20ms/DIV 或停止后缩放时基) ********************/
void        ShowOscope(void)
{
        u16        x,j;
        u8        i;

        if(TimeScale == 3)
        {
                j = 8000/5 - 400;        //波形移位处理
                if(Shift >= j)        Shift = j;
                for(j=(Shift*5)/2,x=0; x<400; x++)
                {
                        i = adc_sample;        //读一个采样
                        if(i > 250)        i = 250;
                        adc_tmp = i;
                        j = j + 2;
                        x++;
                        i = adc_sample;        //读一个采样
                        if(i > 250)        i = 250;
                        adc_tmp = i;
                        j = j + 3;
                }
        }
        else
        {
                j = 4000/TimeScale - 400;        //波形移位处理
                if(Shift >= j)        Shift = j;
                for(j=Shift*TimeScale,x=0; x<400; x++)
                {
                        i = adc_sample;        //读一个采样
                        if(i > 250)        i = 250;
                        adc_tmp = i;
                        j = j + TimeScale;
                }
        }
       
        TxCnt = 0;
        TX_write2buff(0xfb);        //上传一帧数据:FB DAT0 DAT1 ..... DAT399 FF
        for(x=0; x<400; x++)        TX_write2buff(adc_tmp);
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送
}


/************** 实时显示波形函数(>=50ms/DIV) ********************/
void        RealShowOscope(void)
{
        u16        x;
        u8        i;

        x = adc_rd/10;
        if(x >= 400)        return;       

        i = adc_sample;
        if(i > 250)        i = 250;        //增加判断, 中断不判断
        TxCnt = 0;
        TX_write2buff(0xfc);        //上传一个点数据:FC DAT0 DAT1 DAT2 FF
        TxData255((u8)(x>>8));        //X轴位置高字节
        TxData255((u8)x);                //X轴位置低字节
        TX_write2buff(i);                        //Y轴数值(0~250)
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送
        adc_rd += 10;
}


/***************** ADC配置函数 *****************************/
#define ADC_START        (1<<6)        /* 自动清0 */
#define ADC_FLAG        (1<<5)        /* 软件清0 */

#define        ADC_SPEED        0                /* 0~15, ADC时钟 = SYSclk/2/(n+1) */
#define        RES_FMT                (0<<5)        /* ADC结果格式 0: 左对齐, ADC_RES: D9 D8 D7 D6 D5 D4 D3 D2, ADC_RESL: D1 D0 000000 */
                                                        /*             1: 右对齐, ADC_RES: 000000D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */

#define CSSETUP                (0<<7)        /* 0~1,ADC通道选择时间      0: 1个ADC时钟, 1: 2个ADC时钟,默认0(默认1个ADC时钟)        */
#define CSHOLD                (0<<5)        /* 0~3,ADC通道选择保持时间(n+1)个ADC时钟, 默认1(默认2个ADC时钟)                                        */
#define SMPDUTY                10                /* 10~31, ADC模拟信号采样时间(n+1)个ADC时钟, 默认10(默认11个ADC时钟)                                */
                                                        /* ADC转换时间: 10位ADC固定为10个ADC时钟, 12位ADC固定为12个ADC时钟.                                 */

void        ADC_config(void)
{
        P1n_pure_input(0x08);        //设置要做ADC的IO做高阻输入
        ADC_CONTR = 0x80 + 3;        //ADC on + channel
        ADCCFG = RES_FMT + ADC_SPEED;
        P_SW2 |=0x80;        //访问XSFR
        ADCTIM = CSSETUP + CSHOLD + SMPDUTY;        //28 ADC CLOCK
}
//***********************************************************************************************

//========================================================================
// 函数: void Timer4_Config(void)
// 描述: timer3初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void Timer4_Config(void)
{
        P_SW2 |= 0x80;                //SFR enable   
        T4T3M &= 0x0f;                //停止计数, 定时模式, 12T模式, 不输出时钟

        T4T3M |=(1<<5);        //1T mode
        T4H = (u8)((65536UL - MAIN_Fosc/2000) /256);
        T4L = (u8)((65536UL - MAIN_Fosc/2000) %256);

        T3T4PIN = 0x00;                //选择IO, 0x00: T3--P0.4, T3CLKO--P0.5, T4--P0.6, T4CLKO--P0.7;    0x01: T3--P0.0, T3CLKO--P0.1, T4--P0.2, T4CLKO--P0.3;
        T4T3M |=(1<<4);        //允许输出时钟
        T4T3M |=(1<<7);        //开始运行
}

/************************ 比较器配置函数 ****************************/
void        Compare_Config(void)        //比较器初始化
{
        CMPCR1 = 0;
        CMPCR2 = 63;                //比较结果变化延时周期数, 0~63
        CMPCR1 |= (1<<7);        //1: 允许比较器,   0:关闭比较器
        CMPCR1 |= (0<<5);        //1: 允许上升沿中断, 0: 禁止
        CMPCR1 |= (0<<4);        //1: 允许下降沿中断, 0: 禁止
        CMPCR1 |= (0<<1);        //1: 允许比较结果输出到IO(P3.4或P4.1),0: 比较结果禁止输出到IO
        CMPCR2 |= (0<<7);        //1: 比较器结果输出IO取反, 0: 不取反
        CMPCR2 |= (0<<6);        //0: 允许内部0.1uF滤波,    1: 关闭

        P_SW2 |=0x80;        //访问XSFR
        CMPEXCFG = (3<<6) | (1<<2) | 3;        // bit7 bi6(比较器DC迟滞输入选择): 0--0mV, 1--10mV, 2--20mV, 3--30mV,
                                                                        // bit2(负输入端选择): 1: 选择内部BandGap电压BGv做负输入, 0: 选择外部P3.6做输入
                                                                        // bit1 bit0(正输入端选择): 0--P3.7, 1--P5.0, 2--P5.1, 3--ADCIN(ADC_CONTR的bit3:0选择, ADC_CONTR的最高位置1)

        IP2|= (1<<5);        //比较器中断优先级最高
        IP2H |= (1<<5);

        CMPCR1 = 0x80;                        // 关比较器中断
//        CMPCR1 = 0x80 + 0x20;        // 比较器上升沿中断
//        CMPCR1 = 0x80 + 0x10;        // 比较器下降沿中断
}

/***************** 比较器中断函数 *****************************/
void CMP_ISR(void) interrupt CMP_VECTOR                //比较器中断函数, 检测到反电动势过0事件
{
        ADC_RES = 0;
//        ADC_RESL = 0;
        ADC_CONTR = 0x80 + ADC_START + 3;        //ADC on + channel
        TR0 = 1;                //开始运行Timer1.

        AutoTimeCnt = 0;        //有同步信号, 则取消超时触发
        adc_wr= 0;
        adc_rd= 0;

        CMPCR1 = 0x80;                // 关比较器中断 并且清除中断标志位
}

//================= 触发超时处理 ========================
void        AutoCheck(void)
{
        if(AutoTimeCnt != 0)                //8ms call
        {
                if(--AutoTimeCnt == 0)        //同步触发超时, 则强制启动
                {
                        ADC_RES = 0;
                        ADC_RESL = 0;
                        ADC_CONTR = 0x80 + ADC_START + 3;        //ADC on + channel
                        TR0 = 1;                //开始运行Timer1.

                        CMPCR1 = 0x80;                // 关比较器中断
                        adc_wr= 0;
                        adc_rd= 0;
                }
        }
}


//========================================================================
// 函数: void PWMA_config(void)
// 描述: PWMA初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2022-6-25
//========================================================================
void PWMA_config(void)
{
        u8        ccer1;
        u8        ccer2;
        u8        ps;
        u8        eno;
        u8        PWMA_ISR_En;

        P_SW2 |= 0x80;                //SFR enable   
        PWMA_ENO    = 0;        // IO输出禁止
        PWMA_IER    = 0;        // 禁止中断
        PWMA_SR1    = 0;        // 清除状态
        PWMA_SR2    = 0;        // 清除状态
        ccer1 = 0;
        ccer2 = 0;
        ps    = 0;
        eno   = 0;
        PWMA_ISR_En = 0;

        PWMA_PSCRH = 0x00;                // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
        PWMA_PSCRL = 0x00;
        PWMA_DTR   = 0;                        // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
                                                        //                                0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
        PWMA_ARRH   = 256/256;        // 自动重装载寄存器,控制PWM周期
        PWMA_ARRL   = 256%256;

        PWMA_CCMR1= 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR1H= 128/256;        // 比较值, 控制占空比(高电平时钟数)
        PWMA_CCR1L= 128%256;
        ccer1 |= 0x07;                        // 开启比较输出, 低电平有效
        ps    |= 0;                                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
        eno   |= 0x02;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
//        PWMA_ISR_En|= 0x02;                // 使能中断

        PWMA_CCER1= ccer1;        // 捕获/比较使能寄存器1
        PWMA_CCER2= ccer2;        // 捕获/比较使能寄存器2
        PWMA_PS   = ps;                // 选择IO
        PWMA_IER    = PWMA_ISR_En;        //设置允许通道1~4中断处理

        PWMA_BKR    = 0x80;                // 主输出使能 相当于总开关
        PWMA_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMA_ENO    = eno;                // 允许IO输出

        P1n_push_pull(1<<1);        //P1.1 设置为推挽输出
}
//        PWMA_PS   = (0<<6)+(0<<4)+(0<<2)+0;        //选择IO, 4项从高到低(从左到右)对应PWM1 PWM2 PWM3 PWM4, 0:选择P1.x, 1:选择P2.x, 2:选择P6.x,
//PWMA_PS    PWM4N PWM4P    PWM3N PWM3P    PWM2N PWM2P    PWM1N PWM1P
//    00       P1.7P1.6   P1.5P1.4   P1.3P5.4   P1.1P1.0
//    01       P2.7P2.6   P2.5P2.4   P2.3P2.2   P2.1P2.0
//    02       P6.7P6.6   P6.5P6.4   P6.3P6.2   P6.1P6.0
//    03       P3.3P3.4      --    --       --    --       --    --

//========================================================================
// 函数: void PWMB_config(void)
// 描述: PWMA初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2022-6-25
//========================================================================
void PWMB_config(void)
{
        u8        ccer1;
        u8        ccer2;
        u8        ps;
        u8        eno;
        u8        PWMB_ISR_En;

        P_SW2 |= 0x80;                //SFR enable   
        PWMB_ENO    = 0;        // IO输出禁止
        PWMB_IER    = 0;        // 禁止中断
        PWMB_SR1    = 0;        // 清除状态
        PWMB_SR2    = 0;        // 清除状态
        ccer1 = 0;
        ccer2 = 0;
        ps    = 0;
        eno   = 0;
        PWMB_ISR_En = 0;

        PWMB_PSCRH = 0x00;                // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
        PWMB_PSCRL = 6;
        PWMB_ARRH= 0;                        // 自动重装载寄存器,控制PWM周期, PWM频率 = 35000000/(6+1)/250=20000
        PWMB_ARRL= 250-1;

        PWMB_CCMR4= 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMB_CCR4H= 0;                // 比较值, 控制占空比(高电平时钟数)
        PWMB_CCR4L= 87;
        ccer2 |= 0x50;                        // 开启比较输出, 高电平有效
        ps    |= (0<<6);                // 选择IO, 0:选择P2.3, 1:选择P3.4, 2:选择P0.3, 3:选择P7.7,
        eno   |= 0x40;                        // IO输出允许,bit6: ENO8P, bit4: ENO7P,bit2: ENO6P,bit0: ENO5P
//        PWMB_ISR_En|= 0x10;                // 使能中断

        PWMB_ISR_En = 0x01;                // 使能更新中断

        PWMB_CCER1= ccer1;        // 捕获/比较使能寄存器1
        PWMB_CCER2= ccer2;        // 捕获/比较使能寄存器2
        PWMB_PS   = ps;                // 选择IO
        PWMB_IER    = PWMB_ISR_En;        //设置允许通道1~4中断处理

        PWMB_BKR    = 0x80;                // 主输出使能 相当于总开关
        PWMB_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        PWMB_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMB_ENO    = eno;                // 允许IO输出

        P2n_push_pull(1<<3);        //P2.3设置为推挽输出
}
//        PWMB_PS   = (0<<6)+(0<<4)+(0<<2)+0;        //选择IO, 4项从高到低(从左到右)对应PWM8 PWM7 PWM6 PWM5
//PWMB_PS    PWM8    PWM7    PWM6    PWM5
//    00       P2.3    P2.2    P2.1    P2.0
//    01       P3.4    P3.3    P5.4    P1.7
//    02       P0.3    P0.2    P0.1    P0.0
//    03       P7.7    P7.6    P7.5    P7.4

//========================================================================
// 函数: void PWMA_ISR(void) interrupt PWMA_VECTOR
// 描述: PWMA中断处理程序. 捕获数据通过 TIM1-> CCRnH / TIM1-> CCRnL 读取
// 参数: None
// 返回: none.
// 版本: V1.0, 2021-6-1
//========================================================================
#include        "SineTable.h"
u8        SineIndex;
void PWMB_ISR(void) interrupt PWMB_VECTOR
{
        u8        sr1;

        sr1 = PWMB_SR1;        //为了快速, 中断标志用一个局部变量处理
        PWMB_SR1 = 0;        //清除中断标志
        PWMB_SR2 = 0;        //清除中断标志
//        sr1 &= PWMB_ISR_En;        //每个通道可以单独允许中断处理
        if(sr1 & 0x01)        //更新中断标志
        {
                PWMB_CCR4L = T_SIN;                //P1.1输出1000Hz正弦波
                if(++SineIndex == 20)        SineIndex = 0;

                if(++cnt_1ms == 20)
                {
                        cnt_1ms = 0;
                        if(++cnt_8ms == 8)
                        {
                                cnt_8ms = 0;
                                B_8ms = 1;
                        }
                        if(++cnt_32ms == 32)
                        {
                                cnt_32ms = 0;
                                B_32ms = 1;
                                B_32ms_rtn = 1;
                        }
                }
        }

}

//========================================================================
// 函数:void        Timer0_config(void)
// 描述: timer0初始化函数.
// 参数: noe.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void        Timer0_config(void)
{
        TR0 = 0;        //停止计数
        ET0 = 1;        //允许中断
        PT0 = 1;        //高优先级中断
        TMOD &= ~0x03;
//        TMOD |= 0;        //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
        Timer0_1T();        //1T mode
//        TR0 = 1;        //开始运行
}

//========================================================================
void timer0_ISR (void) interrupt TMR0_VECTOR
{
        adc = ~ADC_RES;
        ADC_RES = 0;
//        ADC_RESL = 0;
        ADC_CONTR = 0x80 + ADC_START + 3;        //ADC on + channel

        if(!B_sample_ms)        //<=20ms/DIV, 采样完一块再显示
        {
                adc_sample = adc;
                if(++adc_wr >= 4000)        B_Sample_OK = 1, TR0 = 0;
        }

        else if(--sample_cnt == 0)        // >=50ms/DIV 实时扫描显示波形
        {
                sample_cnt = SampleTime;
                adc_sample = adc;
                if((adc_wr%10) == 0)        B_Sample_OK = 1;
                if(++adc_wr >= 4000)        B_Sample_OK = 1, TR0 = 0;
        }
}




#define        D_MAIN_CLOCK        (MAIN_Fosc/1000000UL)

          //采样索引 SampleIndex   0   1      2      3      4   5      6   7      8   9   10   11   12   13   14   15   16    17    18    19    20
          //采样时间单位          us    us   us   us   us    us   us    us   us    us   us   ms   ms   ms   ms   ms   ms    ms    ms    ms    ms
u16        const   SampleTimeTable[]={   2,    2,   2,   2,   2,   2,    4,    8,    20,   40,    80,   200,   400,   800,   2,   4,    8,   20,   40,   80,200};
          //采样时间/DIV      10us20us   50us100us200us500us   1ms   2ms    5ms10ms   20ms   50ms100ms200ms500ms   1s   2s    5s   10s   20s   50s
u16        const   T_Time_div[]=   {10,   20,    50,   100,   200,   500,    1,    2,   5,   10,    20,    50,   100,   200,   500,   1,    2,    5,   10,   20,   50};
u8        const   T_Time_DanWei[]={   1,    1,   1,   1,   1,   1,    2,    2,   2,    2,   2,   2,   2,   2,   2,   3,    3,    3,    3,    3,    3};

/***************** 设置采样时间函数 *****************************/
void        SetSampleTime(void)
{
        u16        j;

               if(SampleIndex <= 5)        ADCCFG = RES_FMT + 0;        // ADC CLOCK = 20MHz @2us/sample,ADC CLOCK = SYSclk/2/(n+1), 转换需要 28 ADC CLOCK
        else if(SampleIndex == 6)        ADCCFG = RES_FMT + 1;        // ADC CLOCK = 10MHz @4us/sample,ADC CLOCK = SYSclk/2/(n+1)
        else if(SampleIndex == 7)        ADCCFG = RES_FMT + 3;        // ADC CLOCK =5MHz @8us/sample,ADC CLOCK = SYSclk/2/(n+1)
        else                                                 ADCCFG = RES_FMT + 9;        // ADC CLOCK =2MHz >=20us/sample, ADC CLOCK = SYSclk/2/(n+1)

               if(SampleIndex <= 8)        AutoTime = 100/8;        //同步超时100ms           <=5ms/div                <=60ms/frme
        else if(SampleIndex == 9)        AutoTime = 200/8;        //同步超时200ms           10ms/div                        ==120ms/frme
        else if(SampleIndex == 10)        AutoTime = 400/8;        //同步超时500ms           20ms/div                        ==240ms/frme
        else if(SampleIndex == 11)        AutoTime = 800/8;        //同步超时800ms           50ms/div                        ==600ms/frme
        else if(SampleIndex == 12)        AutoTime = 1600/8;        //同步超时800ms           100ms/div                ==600ms/frme
        else                                                 AutoTime = 2000/8;        //同步超时1200ms   >=200ms/div                >=1200ms/frme

        if(TrigMode == 0)        AutoTimeCnt = AutoTime;        //自动模式

        if(SampleIndex <= 10)        //50us 100us 200us/DIV均用2us采样, 500us~20ms/DIV使用10倍采样
        {
                j = SampleTimeTable;
                TR0 = 0;        //停止计数
                B_sample_ms = 0;
                TH0 = (u8)((65536UL - j*D_MAIN_CLOCK) / 256);
                TL0 = (u8)((65536UL - j*D_MAIN_CLOCK) % 256);
        }
       
        else if(SampleIndex <= 13)        // 50ms 100ms 200ms/DIV使用10倍采样
        {
                j = SampleTimeTable;
                TR0 = 0;        //停止计数
                SampleTime= 1;        //依旧是一次中断采样一次
                sample_cnt= 1;
                B_sample_ms = 1;        //实时扫描显示
                TH0 = (u8)((65536UL - j*D_MAIN_CLOCK) / 256);
                TL0 = (u8)((65536UL - j*D_MAIN_CLOCK) % 256);
        }

        else                 // >=500ms/DIV, 实时扫描, 定时器中断固定为1ms
        {
                j = SampleTimeTable;
                TR0 = 0;        //停止计数
                SampleTime= j;        //一个采样点对应的中断次数
                sample_cnt= j;
                B_sample_ms = 1;        //实时扫描显示
                TH0 = (u8)((65536UL - 1000*D_MAIN_CLOCK) / 256);        //1ms中断
                TL0 = (u8)((65536UL - 1000*D_MAIN_CLOCK) % 256);
        }
}

/***************** 显示时基函数 *****************************/
void        ShowTimeBase(void)
{
        TxCnt = 0;
        TX_write2buff(0xfe);        //命令开始
        TX_write2buff(0x02);        //上传时基参数: FE 02 DATA0 DATA1 DATA2 FF
        TX_write2buff((u8)(T_Time_div >> 8));
        TxData255((u8)T_Time_div);
        TX_write2buff(T_Time_DanWei);        //时间单位: 0--ns, 1--us, 2--ms, 3--s
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送
}


        //InputIndex   0   1    2    3   4    5      6    7
        //InputIndex+3               3   4    5      6    7      8    910   11   12   13
        // V/DIV      10V5V2.5V1V500mV 250mV 100mV 50mV
u16 const T_VOLTAGE[]={ 10000, 5000, 2500, 1000, 500, 250, 100, 50};

/***************** 显示垂直电压档位 V/DIV 函数 *****************************/
void        ShowVoltage(void)
{
        u8        i;
        TxCnt = 0;
        TX_write2buff(0xfe);        //命令开始
        TX_write2buff(0x03);        //上传垂直幅度参数: FE 03 DATA0 DATA1 DATA2 FF
        TX_write2buff((u8)(T_VOLTAGE >> 8));
        TxData255((u8)T_VOLTAGE);
        TX_write2buff(0x01);        //电压单位: mV
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送

        i = T_V_GAIN;
        if(i & 0x04)        P_V_C = 1;        else P_V_C = 0;
        if(i & 0x02)        P_V_B = 1;        else P_V_B = 0;
        if(i & 0x01)        P_V_A = 1;        else P_V_A = 0;
}

/***************** 显示触发模式函数 *****************************/
void        ShowPhase(void)
{
        TxCnt = 0;
        TX_write2buff(0xfe);        //命令开始
        TX_write2buff(0x05);        //上传触发方式: FE 05 DATA0 FF
        if(B_TrigPhase)        TX_write2buff(0x00);        //B_TrigPhase=1:上升沿, 0:下降沿.
        else                        TX_write2buff(0x01);        //DAT0:触发模式。0--上升沿,1--下降沿。
        TX_write2buff(0xff);        //命令结束
        TrigTx();        //触发发送
}


页: [1]
查看完整版本: 83-老梁示波器-CDC虚拟显示,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64