• 发文章

  • 发资料

  • 发帖

  • 提问

  • 发视频

创作活动
0
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
返回

电子发烧友 电子发烧友

  • 全文搜索
    • 全文搜索
    • 标题搜索
  • 全部时间
    • 全部时间
    • 1小时内
    • 1天内
    • 1周内
    • 1个月内
  • 默认排序
    • 默认排序
    • 按时间排序
大家还在搜
  • 基于建构主义学习理论的藏文音素拼读法MCAI设计

    建构主义是符合人类认知规律的一种学习理论,而MCAI是广泛使用且行之有效的教学辅助工具。文章介绍基于建构主义学习理论的藏文

    2010-03-01 15:08

  • 决策树在机器学习理论学习与实践

    决策树在机器学习理论学习与实践

    2019-09-20 12:48

  • 深度学习入门之基于python的理论与实现

    深度学习入门-基于python的理论与实现(2)

    2020-06-19 11:22

  • 数学符号读法及常用符号英文

    数学符号读法及常用符号英文1 Α α alpha a:lf 阿尔法 角度;系数2 Β β beta bet 贝塔 磁通系数;角度;系数3 Γ γ gamma ga:m 伽马 电导系数(小写)4

    2019-05-29 08:22

  • 常用的数学古希腊字母 读法

    标志读法: Α α alpha 角度;系数 Β β beta 磁通系数;角度;系数 Γ γ gamma 电导系数(小写) Δ δ delta 变动;密度;屈光度 Ε ε,e epsilon

    2019-05-29 08:12

  • 在linux下显示隐藏文件的方法

    显示所有文件(包含隐藏文件)

    2019-07-12 06:07

  • 单片机的学习方法和步骤

    学习单片机比学习其他学科需要付出更多的努力和代价,不仅要学习理论知识还要练习实际操作,而且主要是在实际操作中才能真正学到单片机技术。因主修专业的不同以及电子基础的深浅不同,对于不同的人可能采用

    2021-11-30 06:38

  • 单片机宏定义学习笔记

    这几天在整理和生产EMC单片机程序的一些宏,发现这东西真的是好用得超乎了想象,大大的简化了写程序时的重复劳动。以下以 EM78P260为主,其实其他型号大通小异,注意修改一下寄存器就可以。(1)最常用的 PAGE 和 BANKEMC 的IC是分几个page和几个bank的,低端的EM78P156等只有一个bank和一个page,所以不用切换,新一点的IC基本都要切换的了,这个经常用的冬冬,做成宏就最合适,代码如下:/****************************************************** BANK SELECTION ******************************************************/BANK macro numif num == 0bc R4,6bc R4,7elseif num == 1bs R4,6bc R4,7elseif num == 2bc R4,6bs R4,7elseif num == 3bs R4,6bs R4,7elsemessage "warring!"endifendm/****************************************************** PAGE SELECTION ******************************************************/PAGE macro numif num == 0bc psw,5bc psw,6elseif num == 1bs psw,5bc psw,6elseif num == 2bc psw,5bs psw,6elseif num == 3bs psw,5bs psw,6elsemessage "warring!"endifendm调用格式是BANK num (num是 0~3 代表4个BANK)PAGE num (num是 0~3 代表4个PAGE)这样方便多了,而且不会出错(2)带参数的宏作为例子,我们假定定义一个宏“ FUNC” ,带两个参数,功能是单纯的将传进来的数据传到PORT5 和 PORT6 而已,演示用法。首先看定义:FUNC MACRO ARG1,@ARG2MOV A,@ARG1MOV PORT5,AMOV A,ARG2MOV PORT6,AENDM注意到,为什么 ARG1前面有个 @ 的符号的呢?这个代表的是宏接收的第一个参数是一个立即数,而ARG2没有那个符号,代表宏接收的第二个参数是一个寄存器的地址。为了程序的统一性,做宏的时候,凡是立即数的,都加上@符号,普通寄存器变量都不加,形成统一的风格。好了,看在主程序怎么用:FUNC 0X10, @0X20这样就OK了,编辑器编译的时候,会自动进行宏替换,将0X10这个立即数作为第一个参数传递进去,而将0X20寄存器的内容,作为第二个参数传递进去,进行宏替换之后的结果,等效于:MOV A,@0x10MOV PORT5,AMOV A,0x20MOV PORT6,A基本用法就是这样。不难,试一下就会用。(3)说一点C语言的一种良好风格C语言上面有一种比较好的编程风格,给个C51的例子:我们想设置TIMER0在模式1,TIMER1在模式2一般教程的思维和代码就是:翻资料看看TMOD的位的定义,然后慢慢算,模式1和模式2该给什么值,最后写指令:TMOD = 0x21; 完工…..其实我们还可以有另外一种办法,那就是这样写:TMOD = CT0_MODE1 | CT1_MODE2 ;其中里面用到一些宏,具体定义是:#define CT0_MODE0 0x00 // Timer0/Counter0 Mode#define CT0_MODE1 0x01#define CT0_MODE2 0x02#define CT0_MODE3 0x03#define CT1_MODE0 0x00 // Timer1/Counter1 Mode#define CT1_MODE1 0x10#define CT1_MODE2 0x20#define CT1_MODE3 0x30TMOD = CT0_MODE1 | CT1_MODE2 ;这个应该很容易看的懂吧?中间的 “|”是或运算,这个就是编译器在编译的时候做的运算了,具体CT0_MODE1 代表 0X01 CT1_MODE2 代表0x20,然后“或运算”之后结果就是0X21 了,跟上面一样。但是老实说,大家愿意用哪个办法去做呢?我会毫不犹豫的选择第二种,有意义的符号比没有意思的数据来的好用。(4)用我们的EMC的汇编编译器模仿这种风格我们的EMC汇编编译器同样支持这种编译时候的运算,让编译器帮我们先处理一些基本的运算,虽然面对C编译器这个小功能真是见惯不怪,但是原来汇编编译器也能,颇有点小小的有点意外。EMC的芯片的功能寄存器分配,真有点乱七八糟,唉,看着吐血,用定一种型号的IC那还好,如果用了几种IC的话,那个叫郁闷,一个例子就是EM78P447 和EM78P156,本来前者是升级版,但是为啥有些控制差别会那么大呢,每次都要疯狂的查DATASHEET,为了缓慢脑细胞的死亡速度,俺决定用宏……例如: 我们需要开启EM78P260的TCCA计数器来用,初始化时候的工作,我们用带参数的宏来实现。分几步走1 首先定义一个宏,以后可以用这个宏来初始化了TCCA_SETUP MACRO TCCACNTclr 0x04 ; 0x04 是用来做临时寄存器用的ior 0x08 ; 0x08是控制TCCA的寄存器and a,@0xf8 ; 屏蔽掉TCCA相关的mov 0x04,amov a,@TCCACNT ; 读取传递进来的参数or a,0x04iow 0x08mov a,@TCCACNT ; 如果允许TCCA的话,开TCCA的中断and a,@0x04 ; 否则直接跳出***c 0x03,2jmp $+4ior 0x0for a,@0x08iow 0x0fENDM(因为这个程序在初始化阶段,所以改变0x04寄存器没有所谓,不过在正常跑的时候千万不要乱来,那个是会切换BANK的,跑飞了可不是说着玩,当然,这里可以在RAM开辟一个寄存器来用,那就没事了。喜欢的自己改)2 第二部就是定义一些宏的具体数值了(跟C类似)TCCA_ENABLE == 0X04TCCA_DISABLE == 0X00TCCA_SRC_INT == 0X00TCCA_SRC_EXT == 0X02TCCA_EDGE_RISE == 0X00TCCA_EDGE_FALL == 0X013 第三步就是华丽的开始用了,在主程序里面,/*****************************************************************************TCCA_SETUP setup MACROargument : TCCA_ENABLE / TCCA_DISABLE 是否允许TCCA_SRC_INT / TCCA_SRC_EXT 计数源选择TCCA_EDGE_RISE / TCCA_EDGE_FALL 出发弦选择****************************************************************************/TCCA_SETUP TCCA_ENABLE|TCCA_SRC_INT|TCCA_EDGE_RISE看到了吧?(TCCA_DISABLE|TCCA_SRC_INT|TCCA_EDGE_RISE)一堆有意义的参数,或运算之后作为一个参数传递给宏 TCCA_SETUP ,修改的时候我们很简单就能搞定,甚至绝对不需要查资料,例如,我们想改成外部TCCA脉冲计数,只需要简单的修改TCCA_SETUP TCCA_ENABLE|TCCA_SRC_EXT|TCCA_EDGE_RISE完工了,想禁止TCCA的话,改成 TCCA_DISABLE 就OK了,是不是很简单?很方便? 当然,方便的代价就是增加程序代码,不过就多那么10来行,没有哈大问题的,重要是不要过多的抹煞脑细胞~~hoho~ 可持续发展啊~~~(5)寄存器自动分配终于到了尾声,到了最BT的地方了,也是最有成就感的东西,怎么让寄存器自动分配空间,汇编跟C一个很大的区别就是,C的变量是自动分配,看着都眼红,那是多少好的东西啊,被汇编虐待了好些日子,突然发现,原来咱们EMC的汇编编译器也有这个功能,大喜!可能已经有前辈懂得怎么用了,那就算在下班门弄斧好,拍拍砖~~~平时写程序的习惯就是,定义一个有意义,容易记的名字去代替抽象的寄存器名,例如定义一个临时变量用的寄存器TEMP EQU 0X10这样,我们定义了TEMP,以后都用 TEMP 来代替 0X10 寄存器,这是最最常规的办法。但是,问题是,我们必须每次写程序之前都重新定义一次TEMP EQU 0X10 ,当然,也不是说很烦,但是我们都有一些常用功能的子程序,子程序里面用到寄存器的话,也需要定义,然后做项目的时候,这里copy一个子程序,那里copy一个子程序,好了,一大堆冲突的寄存器定义,必须慢慢仔细的检查,如果不走运,有两个名字定义到同一个寄存器上面,好,惨了,很隐蔽的逻辑错误就出现了,那是恶梦。但是用宏可以做到自动分配用到的是变量宏,WICE手册里面也有说,用法是TEST VAR 1MOV A,@TESTTEST VAR TEST+1MOV A,@TEST对比两次的A值,我们发现,第一个A值为1,第二个A值为2 !!这个就是变量宏的基本原理,编译器当它是一个变量,可以改变的,不过这个改变,只发生在编译的时候,生成代码之后就没有用的了。好了,下面说说我们的核心,具体怎么分配。首先定义个分配变量的宏,代码如下ADDR_ASSIGN MACRO REGISTERREGISTER EQU ADDRESSADDRESS VAR ADDRESS+1ENDM用了一个参数,传递进来的变量的名字。例如我们在主程序里面写了ADDRESS VAR 0X10(首先定义开始分配的地址,我们是由 0X10 开始)ADDR_ASSIGN Temp0Temp0 作为参数传递进来,实际上就是执行了Temp EQU 0X10ADDRESS = ADDRESS+1 (现在的ADDRESS已经是 0X11了!因为它是一个变量宏!)下次如果我们继续定义ADDR_ASSIGN Temp1现在 Temp1 已经自动被定义为 0X11 了,然后ADDRESS滚到0X12为下个寄存器定义用。这样就方便了,例如我们定义一堆寄存器ADDR_ASSIGN Temp0ADDR_ASSIGN Temp1ADDR_ASSIGN Temp2ADDR_ASSIGN Temp3天啊,这实在是太好用了!!!我们完全不用关心具体分配到哪个寄存器上面,反正就是分配了,反正就是可以用了,哈~~TEST一下就知道。牵涉的问题1越界问题,当分配到 0X3F 的时候一个页面结束了,但是ADDRESS还是继续加上去,怕不怕?不怕,编译器已经报错了,不能编译,这样就不怕越界,可以放心的定义了牵涉的问题2多个bank的怎么分配?其实可以在定义宏的时候加多一个参数,通过条件宏来跳转定义就OK了,不过我怕麻烦,用了一下的办法:/*---------------------------BANK 0 入口地址-------------------------------------*/ADDRESS VAR 0X10 ; 可分配 0x10 ~ 0x3f/*--------------------------- BANK 0 ----------------------------------------*/这里就是我们需要定义的寄存器的/*---------------------------BANK0 调试信息输出----------------------------------*/MESSAGE "Bank0最大分配RAM:"ADDR_DISP ADDRESS-1/*-------------------------------------------------------------------------------*//*---------------------------BANK 1 入口地址-------------------------------------*/ADDRESS VAR 0X20 ; 可分配 0x20 ~ 0x3f/*--------------------------- BANK 1 ----------------------------------------*/这里我门需要定义的bank 1 的寄存器/*---------------------------BANK1 调试信息输出----------------------------------*/MESSAGE "Bank 1 最大分配RAM:"ADDR_DISP ADDRESS-1/*-------------------------------------------------------------------------------*/怎么样?和谐了吧? 将变量严格分开,你需要放在 bank0 的就填到 bank0 的区域,需要分到bank1 的就填到bank1那里,因为在bank1开头,重新定义了 ADDRESS 为 0X20 ,那样就可以继续从 0X20开始分配,如果有多个page的,按照同样的办法。在每个bank结束的时候,我还放了两个宏,他们是MESSAGE "Bank0最大分配RAM:"ADDR_DISP ADDRESS-1第一个,简单的显示文字而已,第二个 ADDR_DISP 是用来显示一共最大分配到哪个寄存器,这个宏的原型是:ADDR_DISP macro regIF reg==0x10MESSAGE "0x10"ELSEIF reg==0x11MESSAGE "0x11"ELSEIF reg==0x12MESSAGE "0x12"ELSEIF reg==0x13…………(下面的自己写了….)ENDM很简单,将ADDRESS最后的地址传进去,现实一下而已,因为ADDRESS执行多了一条自加指令的,所以我们减回,那就OK了。需要注意的地方,这个方法分配的全部都是全局变量,当做小项目寄存器极其紧缺,需要将某个寄存器复用的时候,这办法就见鬼了。注意一下就是了。

    2016-10-10 19:27

  • 基于流形学习的毫米波探测器目标识别方法研究【个人收藏】

    流形学习是一种机器学习理论,旨在发现高维数据分布的内在规 律,并 从中恢复低维流形结构 ,实现维数约简 。本文将流形学习方法应用于毫米波探测器目标识 别 ,并 对现有流形学习

    2021-12-20 15:43

  • 分享自己的学习资料 ! 汽车入门 汽车理论

    `自己的汽车学习资料,给大家分享,欢迎大家交流啊!`

    2012-12-26 15:07