谁能帮我解释一下这段程序?最好是逐条的。

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-31
谁能帮我解释一下这段程序的意思?最好每一句特别是开头那几句有什么作用?万分感谢

小弟只有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;
  };

1. plot(x(1:N/4))是作图向量x的第一到第N/4个值
2. f=-0.5:1/N:0.5-1/N; 中-0.5的意思是f的初值,0.5-1/N是f的最后值,1/N则是f没变化一次的增量。例如若N=10,那么f=-0.5:0.1:0.4,其实f就分别取-0.5 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4
你用f=-0.5:0.5 则系统会默认增量是1 所以系统不可能运行出来

3. f即是plot作图的横坐标 ,至于fftshift 你在matlab 里运行help fftshift
fftshift函数就是一个交换函数:
交换规则如下:
如:x=[1 2 3 4 5 6 7 8];
y=fftshift(x);
then y=[5 6 7 8 1 2 3 4];

其在fft运算里的物理意义:
把0频(低频)周围的频谱搬移到中频范围(采样频率的一半),只是形象化的展示FT变换后的低频成分(正负频率)。
其实质是把Fs/2的右边频谱平移到Fs/2的左边,把低频平移到Fs/2的右边,各图象间距不变。不知道怎么贴图,放附件了。

P2.0~P2.2为通道选择线,P2.6为IC选择线;P1.0为转换结束信号线;P0.0~P0.8为数据线;P2口被配置为第二功能,即地址线的高8位(低8位忽略),所以通道选择线的地址范围为C0FFH~C7FFH,采集的数据存放在30H开始的外部ram中。
详细解释:
ORG 0030H; 定位程序在ROM中的开始存储地址为30H
MOV R1, #30H; R1=30H
MOV R2, #8H; R2=8

MOV TL0, #0H; 定时器0的低8位为0
MOV TH0, #0B8H; 定时器0的高8位为B8H
MOV TMOD, #1H; 定时器0的工作方式为1,功能为定时器方式, 软件控制
CLR ET0; 禁止定时器0的中断
SETB TR0; 启动定时器0

MOV SCON, #40H; 设定串口为工作方式1,不允许接受
MOV DPTR, #0C0FF; 设置DPTR为C0FFH——ADC0809的通道选择地址
LOOP:
MOV A, R2; A=R2=8H
SUBB A, R1; A=A-R1
JNZ LOOP2; A!=0,则跳转到LOOP2处执行
MOV R1,#0H; R1=0;
MOV DPTR, #0COFF; DPTR=C0FF;
MOV R1, #OH;
MOV DPTR, #0C0FF;
LOOP1:
JNB TFO, LOOP1; 如果TF0!=1,则等待(循环执行本指令)
CLR TF0; TF0=0
MOV TL0, #0H; 定时器0的低8位为0
MOV TH0, #0B8H; 定时器0的高8位为B8H

LOOP2:
MOVX @DPTR, A; (DPTR)=A;实际是一条空操作,目的只是为了选择转 换器AD0809的通道0并开始经行AD转换

LOOP3:
JB P1.0,LOOP3; 判断P1.0是否为高;实际是判断AD转换是否开始(开始转换则EOC输出高电平)
LOOP4:
JNB P1.0,LOOP4; 判断P1.0是否为低;实际是判断AD转化是否结束(转换结束,则EOC输出为低电平)

MOVX A, @DOTR; A=(DPTR);读取转换后的数据
MOV @R1,A; (R1)=A;将转换后的数据存入到R1指示的地址中
INC DPH; DPH++;即选择下一个转换通道
INC R1; R1++;
LJMP LOOP; 调到LOOP开始执行程序
END

30H-8H=28H=40;所以一共转换40次,每个ADC0809有8个通道,所以我估计在每个通道前还有5个选择开关——DPH最后要加40,也就是P2.3~P2.5应该是5选1的地址线。

楼上解释很详细

  • 谁能帮我解释一下这段程序?最好是逐条的。
    答:P2.0~P2.2为通道选择线,P2.6为IC选择线;P1.0为转换结束信号线;P0.0~P0.8为数据线;P2口被配置为第二功能,即地址线的高8位(低8位忽略),所以通道选择线的地址范围为C0FFH~C7FFH,采集的数据存放在30H开始的外部ram中。详细解释:ORG 0030H; 定位程序在ROM中的开始存储地址为...
  • 谁能帮我解释一下这段程序的意思?最好每一句特别是开头那几句有什么...
    答:小弟只有10年VC++经验,帮你解读一下哦: 满意的话麻烦给我分.如下代码是为了实现: 接收串口过来的数据! 首先初始化一个泛型类型接受容器, 接收串口接口发来的数据,然后显示在界面上的edit控件上!VARIANT variant_inp; 用VARIANT 泛型变量类型 定义一个数组变量variant_inp; 泛型就是任何类型都可...
  • 哪位大侠帮我解释一下这段宏程序?(FANUC立式加工中心)
    答:103=#5021; 第1轴 当前坐标位置 104=#5022; 第2轴 当前坐标位置 105=#104-#101; 计算第2轴长度 106=#103-#100; 计算第1轴长度 105=ABS[#105]; 第2轴取绝对值 106=ABS[#106}; 第1轴取绝对值 107=ATAN[#105]/[#106]; 反正切 计算角度 500=#107; ...
  • 有谁可以帮我解释这段程序,是Java拼图程序里的,最好逐字逐句,谢谢。
    答:buttons[0][0].setVisible(false);//将第一排第一个按钮设为可见 count++;//操作步骤加一 //这个if块操作是将第一排第一个和第二个交换位置 //下边程序是将第一排第一个和第二排第一个交换位置 } else if (buttons[1][0].getText().equals("6")) { buttons[1][0].setText("" + ...
  • 哪位兄弟能解释一下这段程序,最好逐行解释!谢谢!
    答:public void OutputPersonInfo(System.Data.DataTable dt, string fileName){ System.Diagnostics.Process[] arrProcesses;arrProcesses = System.Diagnostics.Process.GetProcessesByName("Excel");//得到与"Excel'关联的所有进程的一个数组 foreach (System.Diagnostics.Process myProcess in arrProcesses){ ...
  • 请谁能帮我解释一下这段程序的意思,特别是最后几行和开头几行,谢谢了...
    答:public static void main(String args[]){ int i=1,n=10,s=0; //int代表整型,这里是定义三个整型变量 i,n,s并初始化,分别等1,10,0 for(i=1;i<=n;i++) //for循环开始,每循环一次i就加1,等到i大于n时结束 s+=i; //意思是s=s+i,相当于累加,如果循环10次,相当于1+2+...
  • 谁能帮我解释一下这段程序啊:
    答:可以不打, %g是代替后面出现的sum,\n是换行 return 0; //代表程序已正常执行 这样实际求得的和是:sum=1.0*1+(1.0*1)*2+…+(1.0*1*2*…*48)*49+(1.0*1*2*…*49)*50,也就是sum=1!+2!+…+49!+50!(就这么多了,再详细我也无能无力了,加油,好好学C)...
  • 谁能帮我解释一下这个matlab程序,逐条解释更好,万分感谢啊
    答:粒子群优化算法的程序
  • 谁能帮我具体解释一下这段程序。这段程序是为了实现将二进制数转换成...
    答:拿 十进制数 除以十六就可以了 10转16:100以内一点的10转16心算比较快。10转16用传统的计算方式可以了,就是大于15小于256的10进制数除以16为的值为十位的16进制数,其余数为个位的16进制数,没余数则个位为0。如61的16进制是3D,61除以16得3余13,3作十位数,13转成D为各位数。十进制转换...
  • 请逐句解释此程序
    答:main() // main没有类型,有问题要写为int main()或void main(){ char c1='A',c2='\144',c3='\x44',c=0xf5,x=13,a;int i=0122,j=0xa4;/ c1 = 'A'c2 = '\144' = 'd' \000 000是八进制数, 查ASCII码表,d -> 144 c3 = '\x44' = 'D' \x00 x00是十六进制,D ...