解释一下这段程序

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-11
帮忙解释一下这段matlab程序

load wbarb;%装载数据wbarb,其中有X,map等变量
subplot(1,2,1);
image(X);colormap(map);%按map颜色显示X为图片
[c,l]=wavedec2(X,2,'db3');%2水平2D小波分解
[thr,sorh,keepapp]=ddencmp('cmp','wv',X);%求小波压缩默认值
[Xcmp,cxc,lxc,perf0,perf12]=wdencmp('gbl',c,l,'db3',2,thr,sorh,keepapp);%小波压缩
subplot(1,2,2);
image(Xcmp);colormap(map);%按map颜色显示Xcmp为图片
disp('小波分解系数中为0的系数个数百分比:');
perf0
disp('压缩后保留能量百分比:');
perf12

小弟只有10年VC++经验,帮你解读一下哦: 满意的话麻烦给我分.

如下代码是为了实现: 接收串口过来的数据! 首先初始化一个泛型类型接受容器, 接收串口接口发来的数据,然后显示在界面上的edit控件上!

VARIANT variant_inp; 用VARIANT 泛型变量类型 定义一个数组变量variant_inp; 泛型就是任何类型都可以放进去的意思. 作为缓冲池使用很适合.

COleSafeArray safearray_inp; 用COleSafeArray用OLE安全数据容器类 定义一个对象名字是 safearray inp 因为VARIANT虽然可以放任何类型数据到这个数组中,但该类型没有丰富的处理成员函数,说白了他是结构体不是类, 所以 需要做个转换, 转为COleSafeArray类型的数组类即可. 他具有非常丰富的成员函数.

那么, 你会问为什么不直接让safearray_inp=m_ctrlComm.GetInput(); 读缓冲区,而要经过一个中间变量呢?
variant_inp=m_ctrlComm.GetInput(); 读缓冲区
safearray_inp=variant_inp; VARIANT转换成COleSafeArray型变量

VARIANT和COleSafeArray 是什么关系呢?

原因是:

这中间有调用不同的重载=运算符,m_ctrlComm.GetInput(); 的数据可以转化为variant_inp,有默认的转化方式,而safearray_inp=variant_inp则是另一个转化方式,如果直接转,可能数据不对。
VARIANT和COleSafeArray 一个是结构体,一个是类,各自的数据构造不一样。



long k=0; 初始化一个长整型变量 k=0;
int len; 定义长度len,整数型.

BYTE rxdata[2048]; 定义接受数据的数组,2k大小,2048字节. 为BYTE类型,也即unsigned char类型.
CString strtemp; 定义一个CString类型的字符串strtemp;
if(m_ctrlComm.GetCommEvent()) 如果控制通信对象m_ctlComm有get的事件发生,
{

------------------------
这里应该加switch(ret) , 将上面getcommevent赋值给ret.

case 2: 事件值为2表示接收缓冲区内有字符
{
variant_inp=m_ctrlComm.GetInput(); 控制通信器对象得到输入数据流. 如果GetCommEvent返回2,说明有字符到达了, 接收缓冲区内有字符
safearray_inp=variant_inp; 将variant inp转换为COleSafeArray 类型,付给safearry inp. 因为COleSafeArray提供了丰富的函数处理.符合我们的需要.

len=safearray_inp.GetOneDimSize(); 获取输入安全数组的长度len
for(k=0;k<len;k++) 做个循环,
{
safearray_inp.GetElement(&k,rxdata+k); 从输入的安全数组到rxdata进行数据拷贝. 一次一个字节拷贝.
}
for(k=0;k<len;k++) 做个循环. 读取len长度的所有字节.
{
BYTE bt=*(char*)(rxdata+k); 内存 rxdata 起始地址+k字节偏移的指针 取值,得到 一个字节.
strtemp.Format("%c",bt); strtemp赋值为bt,也就是一个字符.
m_strEditRXData+=strtemp; m_strEdit这个CEdit控件显示一直加长.
}
}
UpdateData(FALSE); 将内存变量数据更新到界面.


====================
参考:



VARIANT




  

C++、BASIC、Java、Pascal、Script......计算机语言多种多样,而它们各自又都有自己的数据类型,COM
产生目的,其中之一就是要跨语言(注3)。而 VARIANT
数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。从C语言的角度来讲,VARIANT
其实是一个结构,结构中用一个域(vt)表示------该变量到底表示的是什么类型数据,同时真正的数据则存贮在 union
空间中。结构的定义太长了(虽然长,但其实很简单)大家去看 MSDN 的描述吧,这里给出如何使用的简单示例:

学生:我想用 VARIANT 表示一个4字节长的整数,如何做?
老师:VARIANT v; v.vt=VT_I4; v.lVal=100;

学生:我想用 VARIANT 表示布尔值“真”,如何做?
老师:VARIANT v; v.vt=VT_BOOL; v.boolVal=VARIANT_TRUE;
学生:这么麻烦?我能不能 v.boolVal=true; 这样写?
老师:不可以!因为
 

类型
字节长度
假值
真值

bool
1(char)
0(false)
1(true)

BOOL
4(int)
0(FALSE)
1(TRUE)

VT_BOOL
2(short int)
0(VARIANT_FALSE)
-1(VARIANT_TRUE)

  所以如果你 v.boolVal=true 这样赋值,那么将来 if(VARIANT_TRUE==v.boolVal)
的时候会出问题(-1 !=
1)。但是你注意观察,任何布尔类型的“假”都是0,因此作为一个好习惯,在做布尔判断的时候,不要和“真值”相比较,而要与“假值”做比较。
学生:谢谢老师,你太牛了。我对老师的敬仰如滔滔江水,连绵不绝......

学生:我想用 VARIANT 保存字符串,如何做?
老师:VARIANT v; v.vt=VT_BSTR; v.bstrVal=SysAllocString(L"Hello,你好");

学生:哦......我明白了。可是这么操作真够麻烦的,有没有简单一些的方法?
老师:有呀,你可以使用现成的包装类 CComVariant、COleVariant、_variant_t。比如上面三个问题就可以这样书写:CComVariant v1(100),v2(true),v3("Hello,你好"); 简单了吧?!(注4)

学生:老师,我再问最后一个问题,我如何用 VARIANT 保存一个数组?
老师:这个问题很复杂,我现在不能告诉你,我现在告诉你怕你印象不深......(注5)
学生:~!@#$%^&*()......晕!




VARIANT 数据类型在文件OAIDL.IDL中定义如下:

struct tagVARIANT {
  union {

  struct __tagVARIANT {

  VARTYPE vt;

  WORD wReserved1;

  WORD wReserved2;

  WORD wReserved3;

  union {

  ULONGLONG ullVal;

  LONGLONG llVal;

  LONG lVal;

  BYTE bVal;

  SHORT iVal;

  FLOAT fltVal;

  DOUBLE dblVal;

  VARIANT_BOOL boolVal;

  _VARIANT_BOOL bool;

  SCODE scode;

  CY cyVal;

  DATE date;

  BSTR bstrVal;

  IUnknown * punkVal;

  IDispatch * pdispVal;

  SAFEARRAY * parray;

  BYTE * pbVal;

  SHORT * piVal;

  LONG * plVal;

  LONGLONG * pllVal;

  FLOAT * pfltVal;

  DOUBLE * pdblVal;

  VARIANT_BOOL *pboolVal;

  _VARIANT_BOOL *pbool;

  SCODE * pscode;

  CY * pcyVal;

  DATE * pdate;

  BSTR * pbstrVal;

  IUnknown ** ppunkVal;

  IDispatch ** ppdispVal;

  SAFEARRAY ** pparray;

  VARIANT * pvarVal;

  PVOID byref;

  CHAR cVal;

  USHORT uiVal;

  ULONG ulVal;

  INT intVal;

  UINT uintVal;

  DECIMAL * pdecVal;

  CHAR * pcVal;

  USHORT * puiVal;

  ULONG * pulVal;

  ULONGLONG * pullVal;

  INT * pintVal;

  UINT * puintVal;

  struct __tagBRECORD {

  PVOID pvRecord;

  IRecordInfo * pRecInfo;

  } __VARIANT_NAME_4;

  } __VARIANT_NAME_3;

  } __VARIANT_NAME_2;

  DECIMAL decVal;

  } __VARIANT_NAME_1;
  };

DELAY5MS PROC ;延时子程序开始
MOV DX,0B000H ;所选计数器对应的端口地址送DX
MOV AX,5000 ;8253计数初值送AX
OUT DX,AL ;低8位送入计数器端口
MOV AL,AH ;把高八位先给AL,输入输出指令的必须格式
OUT DX,AL ;高8位计数器送入端口
HH:MOV DX,0F002H ;标号,把端口号给DX
IN AL,DX ;读地址端口值
AND AL,01H ;屏蔽端口值的D7~D1位,目的是保持AL中D0位不变,检测其值是否为0
JNZ HH ;若不为0,跳转到HH,否则顺序执行
LL:IN AL,DX ;读地址端口值
AND AL,01H ;功能与之前的相同
JZ LL ;检测是否低位为0 ,为0则跳转到LL,否则顺序执行
RET ;返回值
DELAY5MS ENDP ;子程序结束命令

这段8253的程序少了一段控制字送控制端口的命令,没有控制字送控制端口是不行的。
5000并不是5000ms 按你题目所给,应当是5ms 至于5000要根据CLK是多少MHZ来计算。
你想知道是如何实现5ms延时的,这个我懂得不多,没有控制字,我的知道范围内说不出来它的工作方式,8253一共6种工作方式,很复杂,我建议你不要那么深究,除非你将来确定要搞这方面的,否则只会8253的初始化编程就够了,我也是学生,对于我们用的教材和一些资料来说,都没有哪个书会去很深刻的剖析它,我觉得微型计算机原理这门课,你要选择性的学习一些东西。

先汗一个!
你要知道无论是8253,8255A,还是8259A,想对它们初始化编程都需要控制字,我想你如果学了8253就应该能知道什么是控制字。控制字的格式如下:
SC1, SC0———通道选择位.为00, 01, 10分别表示选择0, 1, 2通道.RL1, RL0———读/写操作位.00 表示锁存数据,可随时读取计数器中的计数值; 01 表示只读/写低8位,高8位自动置为0; 10表示只读/写高8位,低8位自动置为0; 11表示读/写16位数据,先低8位,后高8位.M2,M1,M0———工作方式选择位。
根据控制字可以具体判断是选择哪一种工作方式,现在没有我就大体上说一说。
首先,计数初值=定时时间÷CLK周期 你算一算呵呵 对吧。
再说一下大体原理:
8253内部包括3个功能完全相同和操作完全独立的计数通道,每个计数通道由16位减法计数器、16位计数初值寄存器和16位计数值锁存器组成。初始化时,向计数通道装入的计数初值,先送到计数初值寄存器中保存,然后送到减法计数器。计数器启动后,减法计数器对CLK的下降沿进行减1计数,在未锁定时把结果送入16位计数值锁存器中。当计数值减到0时,输出OUT信号,一次计数结束。计数初值寄存器的内容,在计数过程中保持不变。计数初值寄存器和计数值锁存器占用一个端口地址(即该计数通道口地址),CPU读取计数通道的当前计数值来自计数值锁存器。

不知道你懂不懂锁存,所存命令是在读取计数值时先用所存命令将其锁定,防止它改变,否则如果计数值有可能正处于变化中,这样得到的就是不确定的结果了。当cpu用读取所存命令后,锁存器就失效了,计数器将恢复工作。

没有控制字 但是你这个是一个延时程序那么就应该是将通道工作在定时器方式,此时确定频率的时钟脉冲从CLK输入,这正好与上面我说的频率,以及初值的计算吻合吧。

然后各通道的启动、禁止、允许计数与门控信号GATE有关,GATE的作用OUT的输出波形随各通道工作方式不同而不同。
没有控制字没法确定工作方式,也许有办法,但是我的知识有限,能知道的就这么多了,希望对你有所帮助。
PS:你算是把我榨干了!

DELAY5MS PROC
MOV DX,0B000H ;端口号
MOV AX,5000 ;5000毫秒
OUT DX,AL ;先把5000毫秒的低字节送入端口
MOV AL,AH
OUT DX,AL ;再把高字节送入端口
HH:MOV DX,0F002H ;检测端口号
IN AL,DX ;获取值
AND AL,01H
JNZ HH ;低位未置0,说明没循环完
LL:IN AL,DX ;继续检测端口,因为上次是分2次把计时器送入的
AND AL,01H
JZ LL ;检测是否低位为0
RET
DELAY5MS ENDP

DELAY5MS PROC
MOV DX,0B000H ;端口号
MOV AX,5000 ;8253计数初值
OUT DX,AL ;先把低字节送入端口
MOV AL,AH
OUT DX,AL ;再把高字节送入端口
HH:MOV DX,0F002H ;端口号
IN AL,DX ;读高地址端口值(因为分2次赋值,2个口(高低端口)都有数据)
AND AL,01H ;测试高地址端口值的最低位是否为0
JNZ HH ;不为0,说明延时还没完
LL:IN AL,DX ;读低地址端口值
AND AL,01H ;继续检测端口
JZ LL ;检测是否低位为0 ,为0不循环,程序结束
RET
DELAY5MS ENDP

三楼太nB 了 俺才开始学习 公司给安排的 干了

  • 解释一下这个单片机程序。 ORG 0000H LJMP AAO ORG 0030H AAO: MOV...
    答:LJMP AAO ;跳转至 AAO执行程序 ORG 0030H ;程序数据开始地址(一般为30H,30H前的作为51的5个中断地址)AAO: MOV P0,#0FFH ;将P0口置全1 AA4: MOV A,#0FEH ;将立即数0FE送至累加器A(然后再送给P0口)AA5:MOV 30H,#7 ;循环次数1 AA1: MOV P0,A ;将0FE送给P0 LCALL BB0 ;调...
  • 帮我解释下这段c++的程序。最好详细点,尤其是typedef int int_array[4...
    答:一、先解释typedef int int_array[4];关键字typedef用来自定义数据类型,这是所有教材都这样讲的,但不要理解为新创建了一个数据类型,而是将已有的一个类型赋予个新名称而已,即起一个别名。具体对这个语句来说,别名就是:int_array。而[4]不属于名字,而表示一种已有的数据类型,即:给一个大小...
  • 求大神帮忙解释一下下面这段C程序,求详细!
    答:这句语句是定义一个5行2列的2维数组a,这里你可以理解为5个拥有"2个元素的数组"的集合 int* p = a[0];整型指针指向2维数组的首元素的地址 int (*p2)[2] = &a[1];定义p2是一个指向数组的指针,现在p2指向a[1],即指向5行2列数组的第二行的首元素的地址 对一个指针(也即地址)加1,...
  • 有人解释下这段程序是啥意思吗
    答:这是一段用汇编指今编写的代码。DB被称为伪指令,用于告诉编译软件定义字节数据。X DB 18H 表示在地址X位置有一个字节数据,值为16进制18H;Y DB ?表示在地址Y位置保留一个字节单元;…mov al,X ; 表示x单元中内容送入aI;cmp aI,0 ; 表示aI中内容与0比较;jl L1 ...
  • 谁能帮我解释一下这段程序?最好是逐条的。
    答:详细解释:ORG 0030H; 定位程序在ROM中的开始存储地址为30H MOV R1, #30H; R1=30H MOV R2, #8H; R2=8 MOV TL0, #0H; 定时器0的低8位为0 MOV TH0, #0B8H;
  • 解释一下,下面一段程序,每句代码的含义,以及输出结果。
    答:int main( ){ int p1; //定义变量 p1 while((p1=fork())==-1); // 执行p1 = fork(), 并判断 p1 是否等于-1:如果不等于-1,继续执行 p1 = fork();// fork 是LINUX 下的函数,作用是将当前进程的变量,数据复制一份到另一个进程执行。如果fork成功,返回进程的id,否则返...
  • 谁能解释一下这段程序是什么意思,结果是什么?
    答:17,18},i=0,j=0;//循环,i=0 到6 共循环7次 while(i++<7)//如果p[i] 也就是数组p的第i个数能被2整除,j=j+p[i];if(p[i]%2) j+=p[i];//循环结束,打印j printf("%d\n",j);这段程序用来选择此长度为8的数组的前七个元素中的偶数,并把这些偶数相加的和打印出来。
  • 麻烦大家帮我解释一下这个三菱plc程序的意思?谢谢
    答:这段的意思是,X001导通时,D10递增1,同时在X001导通时将D10的内容传到Y007-Y000,同时D11递增1,并将D11的内容传到Y027~Y020,。这里需要注意的是,INC和INCP的区别,INC是连续执行型,也就是说,如果X001在持续导通中,那么,D10在每个运算周期都会执行加一运算。而INCP是脉冲执行型,意思就是...
  • 请给我详细解释一下这段程序 谢谢了!!!C语言的!
    答:程序开始的时候首先让数组的第一个数和第二个数比较,如果第一个数较大,则交换它们,以此类推,把最大的一个数交换到最后,然后再找前面剩下的最大数放到倒数第二个位置,如此循环下去,直到循环完成,数组也就排序完成了。对问题补充的回答:楼主的这个算法还可以再优化一下,比如该数组一开始是:...
  • 谁能给我解释一下这段程序
    答:意思就是在字符串的后面加上一个'\0'啊,表示这个字符串结束了,因为strlen,strcpy等函数是以'\0'来判断字符串的结束的,如果不加,调用这些函数的时候就可能会出错。请你仔细看看,当strchr找到第一个'.'号的时候,我们写了一句*p=0,就是把那个'.'号变成了'\0',然后我们用了strcpy(tp[i],...