• 基于51单片机的电流电压采集程序,有串口通信和led显示,自己编写,完全可以使用
  • 数据采集系统——ADC0808的应用,单片机编程,protues仿真,很好用,内有ADC0808/ADC0809的中文资料,很全,很详细
  • 本设计是一个主从系统,采用单片机控制,从机负责采集八路数据,采集精度可以达到0.1%以上,同时应答主机发送的命令,将采集的数据上传;主机进行数据处理,数据显示,键盘输入,系统报警。在主机与从机的通讯中,...
  • 数据采集单片机对外控制的重要应用,其中AD数据采集是难点。本实验基于STC89C52最大系统设计实验,用于对热敏电阻值的测量,并把所得的电阻值转换成数字信号显示在数码管上。
  • 使用51单片机结合ADC0808模数转换器采集多路模拟电压,并通过数码管显示,包含仿真
  • 该工程,是用KEIL开发的适合单片机采集AD值,并且通过串口传输数据,采用了协议传输,通过相应的上位机显示波形图,很有用
  • (基于51核的STC12C5A60S2,keil uvision5 mdk 5.25 编译) #include <STC12C5A60S2.h> #define ADC_POWER 0x80 //ADC power control bit #define ADC_FLAG 0x10 //ADC complete fla...

    (基于51核的STC12C5A60S2,keil uvision5 mdk 5.25 编译)

     

    #include <STC12C5A60S2.h>
    
    #define ADC_POWER   0x80            //ADC power control bit 
    #define ADC_FLAG    0x10            //ADC complete flag 
    #define ADC_START   0x08            //ADC start control bit 
    #define ADC_SPEEDLL 0x00            //420 cLOCks 
    #define ADC_SPEEDL  0x20            //280 clocks 
    #define ADC_SPEEDH  0x40            //140 clocks 
    #define ADC_SPEEDHH 0x60            //70 clocks 
    #define ADC_CH1 0x01                //选择通道1
    
    typedef unsigned char u8;
    
    sbit BEEP = P1 ^ 0;     //置1则响
    
    
    void delay_2ms(unsigned long int time) //2ms的基
    {
    	unsigned long int i;
    	for (i = 0; i < time * 100; i++);
    }
    
    void UART1_Init()
    {
    	SCON = 0x50;
    	EA = 1;
    	ES = 1;
    	TR1 = 1;
    
    	TMOD = 0x20;
    	TH1 = 0xfd;
    	TL1 = 0xfd;
    }
    
    void Uart1_ISR() interrupt 4
    {
    	ES = 0;
    	if (TI == 1)        // 如果TI=1,则说明中断是由发送完成引发的 
    	{
    		TI = 0;
    	}
    	else if (RI == 1)   // 如果RI=1,则说明中断是由发送完成引发的 
    	{
    		RI = 0;
    	}
    	ES = 1;
    }
    
    void ADC_Init()
    {
    
    	P1ASF = 0xff;                   //Open 8 channels ADC function 
    	ADC_RES = 0;                    //Clear previous result 
    	ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
      
    	delay_2ms(1);                       //ADC power-on and delay 
    }
    
    
    u8 GetADCVal(u8 ch)
    {
    	ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
      
    	while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag 
    	ADC_CONTR &= !ADC_FLAG;         //Close ADC 
    
    	return ADC_RES;                 //Return ADC result 
    }
    
    //-------------------------------------------------------------------------
    
    void main()
    {
    	BEEP = 0;
    	UART1_Init();
    	ADC_Init();
    
    	while (1)
    	{
    		SBUF = GetADCVal(1);
    		delay_2ms(100);
    	}
    }
    

     

    展开全文
  • 单片机声音定位程序

    2020-06-03 23:33:04
    本程序通过硬件电路中四个麦克风采集一个声音信号,并将其定位,题目源于电子设计竞赛。
  • 传感器将所测的温度转换为电信号,由单片机进行采集并进行ASCII编码,为液晶显示及串行口通信作准备。根据串行通信原理,采用新型电平转换芯片MAX232实现TTL电平与RS-232电平双向转换,建立了单片机与计算机之

    本系统设计利用单片机实现温度数据采集与传输;计算机实现温度数据的接收、分析及处理的一种设计方法,应用于近距离温度检测。主要涵盖了传感器、计算机串口通信、C程序及VB编程、单片机和计算机信息处理等几方面技术。

    本系统硬件电路主要采用温度传感器DS18B20、液晶显示器1602及单片机STC89C52。传感器将所测的温度转换为电信号,由单片机进行采集并进行ASCII编码,为液晶显示及串行口通信作准备。根据串行通信原理,采用新型电平转换芯片MAX232实现TTL电平与RS-232电平双向转换,建立了单片机与计算机之间通信。利用VB6.0编程实现将采集到的温度数据的接收、分析和存储,将温度数据显示在计算机窗口中并绘制温度的实时曲线,同时在必要的时候可以通过电子邮件的方式将系统状态发送给用户以便于用户进行分析和远程实时操作。     

    更多内容请联系:QQ544921189

    展开全文
  • 模拟量信号滤波算法

    2015-11-05 15:49:20
    理论上讲单片机从A/D芯片上采集信号就是需要的量化信号,但是由于存在电路的相互干扰、电源噪声干扰和电磁干扰, 在A/D芯片的模拟输入信号上会叠加周期或者非周期的干扰信号,并会被附加到量化值中,给信号带来...
    模拟量信号滤波算法  


    收集的关于基础滤波算法: 


    理论上讲单片机从A/D芯片上采集的信号就是需要的量化信号,但是由于存在电路的相互干扰、电源噪声干扰和电磁干扰,
    在A/D芯片的模拟输入信号上会叠加周期或者非周期的干扰信号,并会被附加到量化值中,给信号带来一定的恶化。
    考虑到数据采集的实时性和安全性,有时需要对采集的数据进行软处理,一尽量减小干扰信号的影响,这一过程称为数据采集滤波。


    以下介绍十种数据采集滤波的方法和编程实例。这10种方法针对不同的噪声和采样信号具有不同的性能,
    为不同场合的应用提供了较广的选择空间。选择这些方法时,必须了解电路种存在的主要噪声类型,主要包括一下方面:


    * 噪声是突发随机噪声还是周期性噪声


    * 噪声频率的高低


    * 采样信号的类型是块变信号还是慢变信号


    * 另外还要考虑系统可供使用的资源等


    通过对噪声和采样性能分析,选用最合适的方法以及确定合理的参数,才能达到良好的效果。


        目前用于数据采集滤波的主要方法有以下10种,这10种方法都是在时域上进行处理的,相对于从频域角度设计的IIR或者FIR滤波器,
    其实现简单,运算量小,而性能可以满足绝大部分的场合的应用要求




    1、限幅滤波法(又称程序判断滤波法)
        A、方法:
            根据经验判断,确定两次采样允许的最大偏差值(设为A)
            每次检测到新值时判断:
            如果本次值与上次值之差<=A,则本次值有效
            如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
        B、优点:
            能有效克服因偶然因素引起的脉冲干扰
        C、缺点
            无法抑制那种周期性的干扰
            平滑度差
        
    2、中位值滤波法
        A、方法:
            连续采样N次(N取奇数)
            把N次采样值按大小排列
            取中间值为本次有效值
        B、优点:
            能有效克服因偶然因素引起的波动干扰
            对温度、液位的变化缓慢的被测参数有良好的滤波效果
        C、缺点:
            对流量、速度等快速变化的参数不宜
    3、算术平均滤波法
        A、方法:
            连续取N个采样值进行算术平均运算
            N值较大时:信号平滑度较高,但灵敏度较低
            N值较小时:信号平滑度较低,但灵敏度较高
            N值的选取:一般流量,N=12;压力:N=4
        B、优点:
            适用于对一般具有随机干扰的信号进行滤波
            这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
        C、缺点:
            对于测量速度较慢或要求数据计算速度较快的实时控制不适用
            比较浪费RAM
            
    4、递推平均滤波法(又称滑动平均滤波法)
        A、方法:
            把连续取N个采样值看成一个队列
            队列的长度固定为N
            每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
            把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
            N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
        B、优点:
            对周期性干扰有良好的抑制作用,平滑度高
            适用于高频振荡的系统    
        C、缺点:
            灵敏度低
            对偶然出现的脉冲性干扰的抑制作用较差
            不易消除由于脉冲干扰所引起的采样值偏差
            不适用于脉冲干扰比较严重的场合
            比较浪费RAM
            
    5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
        A、方法:
            相当于“中位值滤波法”+“算术平均滤波法”
            连续采样N个数据,去掉一个最大值和一个最小值
            然后计算N-2个数据的算术平均值
            N值的选取:3~14
        B、优点:
            融合了两种滤波法的优点
            对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
        C、缺点:
            测量速度较慢,和算术平均滤波法一样
            比较浪费RAM
    6、限幅平均滤波法
        A、方法:
            相当于“限幅滤波法”+“递推平均滤波法”
            每次采样到的新数据先进行限幅处理,
            再送入队列进行递推平均滤波处理
        B、优点:
            融合了两种滤波法的优点
            对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
        C、缺点:
            比较浪费RAM
    7、一阶滞后滤波法
        A、方法:
            取a=0~1
            本次滤波结果=(1-a)*本次采样值+a*上次滤波结果
        B、优点:
            对周期性干扰具有良好的抑制作用
            适用于波动频率较高的场合
        C、缺点:
            相位滞后,灵敏度低
            滞后程度取决于a值大小
            不能消除滤波频率高于采样频率的1/2的干扰信号
            
    8、加权递推平均滤波法
        A、方法:
            是对递推平均滤波法的改进,即不同时刻的数据加以不同的权
            通常是,越接近现时刻的数据,权取得越大。
            给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低
        B、优点:
            适用于有较大纯滞后时间常数的对象
            和采样周期较短的系统
        C、缺点:
            对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号
            不能迅速反应系统当前所受干扰的严重程度,滤波效果差
    9、消抖滤波法
        A、方法:
            设置一个滤波计数器
            将每次采样值与当前有效值比较:
            如果采样值=当前有效值,则计数器清零
            如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)
                如果计数器溢出,则将本次值替换当前有效值,并清计数器
        B、优点:
            对于变化缓慢的被测参数有较好的滤波效果,
            可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动
        C、缺点:
            对于快速变化的参数不宜
            如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系

    10、限幅消抖滤波法
        A、方法:
            相当于“限幅滤波法”+“消抖滤波法”
            先限幅,后消抖
        B、优点:
            继承了“限幅”和“消抖”的优点
            改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统
        C、缺点:
            对于快速变化的参数不宜
     
    假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();
    1、限副滤波
    /*  A值可根据实际情况调整
        value为有效值,new_value为当前采样值  
        滤波程序返回有效的实际值  */
    #define A 10
    char value;
    char filter()
    {
       char  new_value;
       new_value = get_ad();
       if ( ( new_value - value > A ) || ( value - new_value > A )
          return value;
       return new_value;
             
    }
    2、中位值滤波法
    /*  N值可根据实际情况调整
        排序采用冒泡法*/
    #define N  11
    char filter()
    {
       char value_buf[N];
       char count,i,j,temp;
       for ( count=0;count<N;count++)
       {
          value_buf[count] = get_ad();
          delay();
       }
       for (j=0;j<N-1;j++)
       {
          for (i=0;i<N-j;i++)
          {
             if ( value_buf[i]>value_buf[i+1] )
             {
                temp = value_buf[i];
                value_buf[i] = value_buf[i+1]; 
                 value_buf[i+1] = temp;
             }
          }
       }
       return value_buf[(N-1)/2];
    }     
    3、算术平均滤波法
    /*
    */
    #define N 12
    char filter()
    {
       int  sum = 0;
       for ( count=0;count<N;count++)
       {
          sum + = get_ad();
          delay();
       }
       return (char)(sum/N);
    }
    4、递推平均滤波法(又称滑动平均滤波法)
    /*
    */
    #define N 12 
    char value_buf[N];
    char i=0;
    char filter()
    {
       char count;
       int  sum=0;
       value_buf[i++] = get_ad();
       if ( i == N )   i = 0;
       for ( count=0;count<N,count++)
          sum = value_buf[count];
       return (char)(sum/N);
    }
    5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
    /*
    */
    #define N 12
    char filter()
    {
       char count,i,j;
       char value_buf[N];
       int  sum=0;
       for  (count=0;count<N;count++)
       {
          value_buf[count] = get_ad();
          delay();
       }
       for (j=0;j<N-1;j++)
       {
          for (i=0;i<N-j;i++)
          {
             if ( value_buf[i]>value_buf[i+1] )
             {
                temp = value_buf[i];
                value_buf[i] = value_buf[i+1]; 
                 value_buf[i+1] = temp;
             }
          }
       }
       for(count=1;count<N-1;count++)
          sum += value[count];
       return (char)(sum/(N-2));
    }
    6、限幅平均滤波法
    /*
    */  
    略 参考子程序1、3
    7、一阶滞后滤波法
    /* 为加快程序处理速度假定基数为100,a=0~100 */
    #define a 50
    char value;
    char filter()
    {
       char  new_value;
       new_value = get_ad();
       return (100-a)*value + a*new_value; 
    }
    8、加权递推平均滤波法
    /* coe数组为加权系数表,存在程序存储区。*/
    #define N 12
    char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};
    char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;
    char filter()
    {
       char count;
       char value_buf[N];
       int  sum=0;
       for (count=0,count<N;count++)
       {
          value_buf[count] = get_ad();
          delay();
       }
       for (count=0,count<N;count++)
          sum += value_buf[count]*coe[count];
       return (char)(sum/sum_coe);
    }
    9、消抖滤波法
    #define N 12
    char filter()
    {
       char count=0;
       char new_value;
       new_value = get_ad();
       while (value !=new_value);
       {
          count++;
          if (count>=N)   return new_value;
           delay();
          new_value = get_ad();
       }
       return value;    
    }
    展开全文
  • 资源包括Android、单片机开发全套工具(eclipse+sak+adt+keil+下载工具)和app源码,51单片机源码(温湿度采集、无线信号传输、数码管显示、LED控制指令)。 此资源仅供学习交流,如有问题及时在评论区留言
  • 合泰单片机AD采集及外部中断学习,包含代码示例。

     

    一、AD采集

    include HT66F0185.inc
    
    ds	.section	'data'
    
    ;ADC采集
    SADOL_buffer db ?
    SADOH_buffer db ?
    
    
    cs	.section	at  000h	'code'
    
    ;ADC采集
    		clr ADE         ; 禁用ADC中断
    		mov a,63H
    		mov SADC1,a     ; 选择fSYS/8作为A/D时钟,关闭VBG电压及转换器电源电压VDD/4
    		set ADCEN       ;使能A/D 转换器使能控制位
    		mov a,01H       ; 配置ACEL以配置PIN AN0
    		mov ACERL,a
    		mov a,20H
    		mov SADC0,a     ;启用和连接AN0通道到A/D转换器
    		
    		start_conversion:
    		clr START       ; 启动脉冲高位脉冲启动转换
    		set START       ; 复位 A/D
    		clr START       ; 开始 A/D
    		
    		polling_EOC:
    		sz ADBZ         ; 轮询SADC0寄存器ADBZ位检测A/D结束
    		; 转换
    		jmp polling_EOC ; 继续轮询
    		
    		mov a,SADOL     ; 读取低字节转换结果值
    		mov SADOL_buffer,a ; 将结果保存到用户定义的寄存器
    		mov a,SADOH     ; 读取高位字节转换结果值
    		mov SADOH_buffer,a ;将结果保存到用户定义的寄存器
    		
    		jmp start_conversion; 开始下一个A/D转换
    		
    		JMP $

    官方资料:SADC0 寄存器中的SACS2~SACS0 位用于选择哪个外部模拟输入通道被连接到内部A/D 转换器。SADC1 寄存器中的SAINS2~SAINS0 位用于选择外部模拟输入通道或内部模拟信号被连接到内部A/D 转换器。若SAINS2~SAINS0 位为“000”或“100”,则选择转换外部模拟输入信号,具体通道编号由SACS2~SACS0 位决定。若SAINS2~SAINS0 位为“000”和“100”以外的其它值,则选择转换内部模拟信号,这些信号可以来自A/D 转换器电源VDD 或内部参考电压VR 的分压,分压比为1、1/2 或1/4。当选择内部模拟信号时,外部输入通道会自动关闭以避免信号冲突。

    程序解读:AD采集配置3个寄存器SADC0、SADC1、SADC2和1个设置AD输入引脚的ACERL 寄存器,最后从存AD采集数据的SADOL,SADOH寄存器中读取数据就好了。

    SADC1寄存器配置 A/D 输入信号选择位和A/D 时钟源选择位,即要采集的信号来自外部还是内部,时钟源是几分频。

    配置时钟源时注意:A/D 转换器的时钟源为系统时钟fSYS 或其分频,而分频系数由SADC1 寄存器中的SACKS2~SACKS0 位决定。虽然A/D 时钟源是由系统时钟fSYS 和SACKS2~SACKS0 位决定,但可选择的最大A/D 时钟源则有一些限制。由于允许的A/D 时钟周期tADCK 的范围为0.5μs~10μs,所以选择系统时钟速度时就必须小心。如果系统时钟速度为8MHz 时,SACKS2~SACKS0 位不能设为“000”、“001”或“111”。必须保证设置的A/D转换时钟周期不小于时钟周期的最小值,否则将会产生不准确的A/D 转换值。

    SADC0寄存器配置 当选择采集信号是外部的时候,配置启用(ADCEN:A/D 转换器使能控制位置1)和连接哪个通道口;外加一个ADRFS:A/D 转换数据格式选择位 是选存数据的俩种方式,没差,一样的会读就好了,都是以D0位最低位开始读,然后其他口一般给0,因为会单独拿出来配。

    SADC2寄存器配置 是为了配置参考电压的,有需要就配,无特别需要,不需要配,寄存器默认全0,即VDD就是参考电压。

    参考电压官方资料:A/D 转换器参考电压来自正电源电压引脚VDD、外部参考源引脚VREFI 或内部Bandgap 参考源,所选的参考电压源除了来自VDD 的以外,都可通过可编程增益放大器进行放大,PGA 增益可以为1、2、3 或4,可通过SADC2 寄存器中的SAVRS3~SAVRS0 位及相关引脚共用功能选择位来选择。注意,所选的参考电压将会输出到VREF 引脚。由于VREFI 和VREF 引脚都与其它功能共用,当选择VREFI 或VREF 参考电压时,需合理设置相关引脚功能选择位选择VREFI 或VREF 引脚功能且除能其它共用引脚功能。

    简单来讲就是参考电压除了VDD是不变的,配置了其他参考电压都可以进行放大改变,那参考电压有什么用呢?

    参考电压就是拿来计算AD采集的值的大小的。A/D转换器的输入是模拟量而输出是数字量,输出的数字量表示的是输入的电压信号或电流信号与基准电压或基准电流相比所占的比例。简单来讲就是采集到的信号的值与参考电压的值的比例。输出= 2^{n}xGxA{m}/V{ref}

    上诉公式中输出就是存在SADOL,SADOH寄存器中采集到的数据,公式换算一下:(Vref就是参考电压)

    该系列单片机含有一组12 位的A/D 转换器,它们转换的最大值可达FFFH。由于模拟输入最大值等于VREF 的电压值,因此每一位可表示VREF/4096 的模拟输入值。
                                                                                            1 LSB=Vref÷4096
    通过下面的等式可估算A/D 转换器输入电压值:
                                                                       A/D 输入电压=A/D 数字输出值×Vref÷4096

    程序流程步骤:

    ● 步骤1
    配置SADC1 寄存器选择所需的A/D 转换时钟和连接至内部A/D 转换器的信号。
    ● 步骤2
    将SADC0 寄存器中的ADCEN 位置高使能A/D。
    ● 步骤3
    配置SADC0 寄存器选择哪个外部通道接至A/D 转换器和ADRFS 位选择A/D 转换器输出数据格式,(若选择A/D 输入信号来自内部模拟信号,无论SACS2~SACS0 为何值,外部通道输入都会自动断开。)接着配置ACERL设置相关的引脚共用功能控制位将该引脚规划为A/D 输入引脚。注意:A/D输入引脚优先级较高,若该引脚不用作A/D输入引脚时,应置零关闭,否则可能影响正常IO口以及其他功能使用。
    ● 步骤4
    配置SADC2选择参考电压。(不配就是VDD)
    ● 步骤5
    如果要使用中断,则中断控制寄存器需要正确地设置,以确保A/D 中断功能是激活的。总中断控制位EMI 需要置位为“1”,以及A/D 转换器中断位ADE 也需要置位为“1”。
    ● 步骤6
    现在可以通过设置SADC0 寄存器中的START 位从“0”到“1”再回到“0”,开始模数转换的过程。
    ● 步骤7
    如果A/D 转换正在进行中,ADBZ 位会被置为逻辑高。A/D 转换完成后,ADBZ位会被置为逻辑低,并可从SADOH和SADOL寄存器中读取输出数据。
    注:若使用轮询SADC0 寄存器中ADBZ 位的状态的方法来检查转换过程是否结束时,则中断使能的步骤可以省略。

    include HT66F0185.inc
    
    ds	.section	'data'
    
    ;ADC采集
    SADOL_buffer db ?
    SADOH_buffer db ?
    
    acc_stack db ?
    status_stack db ?
    
    
    cs	.section	at  000h	'code'
    ;ADC采集中斷
    		org 00h
    		jmp INT
    		org 18h
    		jmp ADC_ISR
    		
    		INT:	
    		clr ADE ; disable ADC interrupt
    		mov a,63H
    		mov SADC1,a ; select fSYS/8 as A/D clock and switch off VBG voltage
    		set ADCEN
    		mov a,01H ; setup ACERL to configure pin AN0
    		mov ACERL,a
    		mov a,20H
    		mov SADC0,a ; enable and connect AN0 channel to A/D converter
    		
    		Start_conversion:
    		clr START ; high pulse on START bit to initiate conversion
    		set START ; reset A/D
    		clr START ; start A/D
    
    		clr ADF ; clear ADC interrupt request flag
    		set ADE ; enable ADC interrupt
    		set EMI ; enable global interrupt
    		
    		JMP $
    		
    
    
    		ADC_ISR: ; ADC interrupt service routine
    		mov acc_stack,a ; save ACC to user defined memory
    		mov a,STATUS
    		mov status_stack,a ; save STATUS to user defined memory
    		
    		mov a, SADOL ; read low byte conversion result value
    		mov SADOL_buffer,a ; save result to user defined register
    		mov a, SADOH ; read high byte conversion result value
    		mov SADOH_buffer,a ; save result to user defined register
    		
    		EXIT_INT_ISR:
    		mov a,status_stack
    		mov STATUS,a ; restore STATUS from user defined memory
    		mov a,acc_stack ; restore ACC from user defined memory
    		reti

    附一段使用AD采集中断的方式来检测转换结束的程序。第一种方法是通过轮询ADBZ状态检测AD采集是否完成,AD采集完成后ADBZ会置0,同样会置位中断控制寄存器内相应的A/D 中断请求标志位。

    要使用AD采集中断只需,        clr ADF ; 清除ADC中断请求标志
                                                    set ADE ; 允许ADC中断
                                                     set EMI ; 启用全局中断

    中断请求标志位ADF置1后,程序会跳到相应的中断向量地址,AD采集中断对应的是18h,中断的用法一般为置高相应中断及总中断,当中断标志位置1后跳转到相应地址(ROM程序存储器),此地址一般放跳转函数“JMP 中断名称”,程序就会跳到对应子函数执行中断,ORG 18h                                                                                                                                                                                            JMP ADC_ISR 此指令将存放在18h

                                      

                                     mov acc_stack,a ; 将ACC保存到用户定义的内存
                                     mov a,STATUS
                                     mov status_stack,a ; 将状态保存到用户定义的内存

    这三句是为了保存ACC和STACK状态寄存器的值,一般进中断保存这些值可以防止中断里的操作改变了这些值影响到主程序,中断结束时在把值存回去然后RETI就可以返回主程序了。(RET和RETI区别在于RETI返回主程序后会把EMI置1,中断下次可以继续进行,RET不会)


    二、外部中断

    include HT66F0185.inc
    
    ds	.section	'data'
    
    ;外部中断
    flag db ?
    flag1 db ?
    
    cs	.section	at  000h	'code'
    
    ;外部中断
              	ORG	00H                		
    		JMP	INIT
    		ORG	004H		        ;HT66FX0 EXT. INTERRUPT VECTOR,外部中斷口INIT0地址
    		JMP	ISR_EXTINT0
    INIT:		
    		CLR     ACERL		        ;AD採集口優先級較高,清除之後才可正常使用外部中斷口
    		MOV     A,1
    		MOV     flag,A
    		SET	PBPU.0			;使PB0上拉
    		SET	PBC.0			;配置PB0(IN0)作为输入。
    		MOV	A,00000010B		;选择It0下降沿触发器
    		MOV	INTEG,A
    		SET	INT0E		        ;启用外部中断0
    		SET	EMI			;启用全局中断
    		
    MAIN:			
    		MOV     A,5
    		MOV     flag1,A
    		JMP     MAIN
    ISR_EXTINT0:
    		INC     flag
    		CLR	INT0F		         ;CLEAR EXT. INT CAUSED BY BOUNCING 清除中断标志位
    		RETI

     

    展开全文
  • Labview编程跟以往传统的软件编程有很大的不同,最明显的差别就是它是图形化编程。用过Labview的童鞋都知道,整个编程都是拖控件的过程,而不是像传统的软件一样码代码。萝卜青菜各有所爱,Labview也有自己小众Fans...

    Labview编程跟以往传统的软件编程有很大的不同,最明显的差别就是它是图形化编程。用过Labview的童鞋都知道,整个编程都是拖控件的过程,而不是像传统的软件一样码代码。萝卜青菜各有所爱,Labview也有自己小众Fans。但是小众归小众,在一些信号处理领域,使用Labview编程会大大缩小我们开发的周期。

    今天,我就来给大家讲讲如何使用Labview的串口来与设备进行通信的。并且在通信的基础上,做了一个四通道的温度采集。按照国际惯例,先来张效果图~~
     

    1.首先我们来认识下Labview的串口控件:

    我们打开Labview的程序框图,右上角有个帮助信息,点击打开Labview帮助,也可以使用快捷键Ctrl + SHIFT + ? 打开

    依次找到串口VI和函数,本篇文章,基本上是围绕这几个控件来实现的,现在我就给大家介绍其中一些重要控件(配置-打开,读,写,关闭控件)的使用。(关于如何使用,帮助里已经说的很清楚了,我这里就不多说了)

    1.1.首先我们来认识下Labview的串口控件:

    VISA配置串口控件:

    说明如下:就是配置好串口的参数,在使用一个串口的时候,我们一般都会设置波特率,奇偶校验,和数据位等相关信息,在使用之前,我们必须要先配置好它的相关参数,这里是配置也是打开串口的控件。

     

    VISA读串口控件:

    就是将数据从串口中读取出来。(这个控件有个R噢~~即Read的意思)

    VISA写串口控件:

    就是将数据写到串口中里。(这个控件有个W噢~~即Write的意思,本文没有使用到该控件,但最基本的我还是提一下)

    VISA串口字节数控件:

    就是返回串口里输入的缓冲区字节数

    VISA关闭控件:

    当使用完毕时,需要关闭硬件资源,否则别的串口工具软件使用时,会提示串口资源被占用。

    好了,相关的控件就到此结束了。接下来给大家说说程序的设计流程图

    流程不是很复杂,我就不多解析整个流程了。

    这里需要提一下解析数据的流程,我们都知道设计出来的Labview的上位机是要跟设备打交道的,那它们是如何打交道呢?这里的话,我们使用的串口的协议,但是串口只是物理层协议,如果才能使得它们能识别彼此发送的数据呢?这就涉及到一个通信协议制定的问题。通信协议说白了就是双方的一个约定,比如两个邻居的日常交流,如果一个用方言(听不懂普通话),一个用普通话(听不懂方言),那么这个交流的过程那是非常痛苦的。所以,制定一个通信协议的作用是让双方都能明白对方的意思,能够无障碍的沟通交流。

    这里的上位机和下位机也有一个解析通信协议的过程,这里定义十六进制数0xAA为帧头,0xBB为帧尾。中间的都是数据。

    比如我要显示的温度为:

    CH1=11.1° CH2 = 22.2°  CH3=33.3° CH4=44.4°

    那么发送的数据应该为:

    0xAA,'1','1','1','2','2','2','3','3','3','4','4','4',0xBB

    原则上来说,在数据域前面应该还有一个长度和字节类型之类的,这就是通常的TLV格式的通信协议。这里的话,没有必要设计这么复杂的协议。所以,怎么简单就怎么来了

    1.2.协议设计好之后,就是开始设计程序了,步骤如下:

    1.2.1 配置串口参数----->读取串口缓存数据----->得到串口数据                              

    1.2.2.将串口数据,按照我们的通信协议进行解析,解析正确后,才显示出来。

    最后来张效果图,这是我用两个串口来模拟的数据(手头上没有这么多传感器来测试哈),如果是用在单片机上,只要编写好温度传感器的驱动,然后按照约定的格式通过串口发送给Labview上位机即可:


    ~~~~关于该项目的完整源码获取方式,可关注公众号:玩转IoT物联网 进行获取~~~~

    原创不易,转载请标明出处

    展开全文
  • 以下介绍十种数据采集滤波的方法和编程实例。这10种方法针对不同的噪声和采样信号具有不同的性能,为不同场合的应用提供了较广的选择空间。选择这些方法时,必须了解电路种存在的主要噪声类型,主要包括一下方面: ...
  • AD采集算法

    2018-12-06 19:23:54
    理论上讲单片机从A/D芯片上采集信号就是需要的量化信号,但是由于存在电路的相互干扰、电源噪声干扰和电磁干扰,在A/D芯片的模拟输入信号上会叠加周期或者非周期的干扰信号,并会被附加到量化值中,给信号带来一定...
  • 007 adc0809 电压 显示在数码管 51单片机 proteus 仿真 一、实验目的 (1)掌握 A/D 转换与单片机的接口方法 (2)了解 A/D 芯片 ADC0809 转换性能及编程方法 (3)通过实验掌握单片机如何进行数据采集。 二、实验...
  • 同理,将数字信号转换成模拟信号的电路称为数模转换器,简称D/A转换器或DAC,单片机能够存储的数据都是数字类型的。 一、逼近式ADC原理 简介:在进行转化时,一般都需要经过采样、量化和编码三个步骤。A/D转换的...
  • 单片机 数字电压表(ADC0809) 一、简述 采用模数转换的芯片ADC0809实现设计数字电压表。例子中设计的数字电压表可以测量0~5V范围内的输入电压值,并且通过4位LED数码管显示采集的电压值,例子测量三个模拟值:4....
  • 单片机应用编程技巧

    2012-06-25 23:39:49
    1. C语言和汇编语言在开发单片机时各有哪些优缺点? 答:汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言...
1 2 3 4 5 ... 20
收藏数 2,867
精华内容 1,146