seg cs是什么意思,看看这里就知道了!

本文详细介绍了寄存器的默认组合问题,包括si和di寄存器默认的段地址寄存器以及如何通过“段超越”改变默认设置。同时,通过具体的汇编指令示例,展示了如何在实际编程中应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【转帖】

先讲一下寄存器的默认组合问题,比如指令mov   [si],   ax表示将ax中的内容存入ds:si指向的内存单元,也就是说在寄存器间接寻址的情况下,以si间接寻址时总是默认以ds为相应的段地址寄存器。同样di是以es为默认的段地址寄存器。
第二个要了解的是“段超越”的问题,就是在某些时候你不想使用默认的段地址寄存器,那
么你可以强制指定一个段地址寄存器(当然这种强制是在允许的情况下,建议看一下汇编
教材上的说明),同上例mov   [si],ax表示存入ds:si中,但如果你想存入cs指向的段中可
以这样mov   cs:[si],ax,   这样就强制指定将ax中的内容存入cs:si的内存单元。
第三个要明白的是seg   cs这样的语句只影响到它下一条指令,比如在linux启动代码中的一段:
      seg   cs
      mov   sectors,ax
      mov   ax,#INITSEG
要说明两点:
    第一,seg   cs   只影响到mov   sectors,ax而不影响mov   ax,#INITSEG
    第二,如果以Masm语法写,seg   cs和mov   sectors,ax两句合起来等
                价于mov   cs:[sectors],ax,这里使用了间接寻址方式。
                重复一下前面的解释,mov   [sectors],ax表示将ax中的内容
                存入ds:sectors内存单元,而mov   cs:[sectors],ax强制以
                cs作为段地址寄存器,因此是将ax的内容存入cs:sectors内存
                单元,一般来说cs与ds的值是不同的,如果cs和ds的值一样,
                那两条指令的运行结果会是一样的。(编译后的指令后者比前
                者一般长一个字节,多了一个前缀。)
    结论,seg   cs只是表明紧跟它的下一条语句将使用段超越,因为在编
                译后的代码中可以清楚的看出段超越本质上就是加了一个字节
                的指令前缀,因此as86把它单独作为一条指令来写也是合理的。
基本情况就是这样,因为Linux使用了as86的汇编语言,与国内教科书上教的存在一些差
异。

硬件的管脚约束文件如下: /////////////////////////////系统时钟和复位//////////////////////////////////// set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports sys_clk_in] set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports sys_rst_n] ///////////////////////////////////////PS2///////////////////////////////////// set_property -dict {PACKAGE_PIN K5 IOSTANDARD LVCMOS33} [get_ports ps2_clk ] set_property -dict {PACKAGE_PIN L4 IOSTANDARD LVCMOS33} [get_ports ps2_data ] ////////////////////////////8个数码管位选信号///////////////////////////////// set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[0]}] set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[1]}] set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[2]}] set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[3]}] set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[4]}] set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[5]}] set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[6]}] set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports {seg_cs_pin[7]}] /////////////////////////////////数码管段选信号//////////////////////////////// set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[0]}] set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[1]}] set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[2]}] set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[3]}] set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[4]}] set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[5]}] set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[6]}] set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {seg_data_0_pin[7]}] set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[0]}] set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[1]}] set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[2]}] set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[3]}] set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[4]}] set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[5]}] set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[6]}] set_property -dict {PACKAGE_PIN H2 IOSTANDARD LVCMOS33} [get_ports {seg_data_1_pin[7]}] 根据上述内容,写一个正确的约束代码
04-02
最近用到了HT1621来驱动一个断码屏,写在这里记录自己的成长历程,也分享出去供大家参考!/*首先声明在本程序中和移植相关的针对不同MCU所需要的做出的修改如下:1.IO口 输入 输出 拉高 拉低等等 如:以CS引脚为例 这里用宏定义的方式提高代码可读性 PinOutput_CS; //将CS引脚设置为输出 PinHigh_CS; //将CS引脚电平拉高 PinLow_CS; //将CS引脚电平拉低2.变量宏定义 如: 初始化配置相关的宏定义(详见DataSheet) #define SYSEN 0x01 #define RC256K 0x18 #define BIAS 0x28|0x01//选中COM为4个公共口 0x01 选择了1/3偏压 #define LCDON 0x03 #define SYSDIS 0x00 #define WDTDIS 0x05 自定义封的宏 #define WrCmd 0x80//控制发送命令标识的宏 #define WrData 0xA0//控制发送写数据的宏 #define BackLightInit {PinOutput_BK; PinHigh_BK;} #define BackLightON {PinHigh_BK;} #define BackLightOFF {PinLow_BK;}3.变量类型定义 typedef unsigned char u8;//标记为u8 降低撸代码手酸的风险*/12345678910111213141516171819202122232425驱动方面只写4个简单的函数一、第一个函数先看时序图由时序图可以知道两个简单的关系,(看图标记N1,N2)1.当CS脚处于低电平状态时,WR脚才有效。2.当CS脚处于低电平状态 且 当WR脚处于上升沿的时候,DATA脚才有效。由图N3标记可知,当写数据的时候命令标识为101,传输数据格式为:101 + 6bits的Addr + 4bits的Data。我们会发现无论是传输①命令标识(100 101 110三种,详见DataSheet) 或者 ②6bits的Addr数据 又或者是 ③4bits的Data 都需要依靠DATA脚的拉高拉低作为载体来传输数据。于是理解到这里,我们就能写出第一个函数(写这个函数有很多种写法,这里只给出最方便理解的写法)如下:/******************************************************************************* * fuction WriteDatatoHT1621 * brief 写数据到HT1621 * param Data:要写入的数据bits num:传送数据位数 * return 无 *******************************************************************************/ void WriteDatatoHT1621(u8 Data,u8 num) { u8 i; for (i=0;i<num;i++) { PinLow_WR; //拉低WR脚 Data线上的数据在WR脚位上升沿写入 if(((Data & 0x80)>>7)==1)//如果当前bit为1,就拉高DATA引脚 PinHigh_Data; if(((Data & 0x80)>>7)==0)//如果当前bit为0,就拉低DATA引脚 PinLow_Data; PinHigh_WR; //当前这一bit写完,拉高WR脚,为下次WR为上升沿做准备 Data<<=1; //当前位用完了,移到下一位继续上述动作 } }1234567891011121314151617181920212223第一个函数中的参数说明:data: 要传输的数据 可以是命令标识 或者 Addr 又或者是 Data。num: 为了方便使用在不同的地方 比如当传输命令标识(如:101时)只有3bits,传输Addr时有6bits,传输Data数据时有4bits。二、第二个函数那么6bits的Addr 和 4bits的Data 分别是什么呢?先看RAM映像示意图:显示内存 RAM:静态显示内存 RAM 以 32 x 4 位(即最多可以驱动128个点,可以理解为128个LED灯)的格式储存所显示的数据 RAM 的数据直接映象到 LCD 驱动器 可以用 READ ,WRITE 和 READ-MODIFY-WRITE 命令访问,我们前一张时序图就是截取的WRITE模式。1.Addr:用6Bits的二进制数表示十进制的0~31,可以看出SEG0对应0 … SEG31对应31。2.Data:用4Bits的二进制数表示要传输的数据,可以看出COM3对应bit3 … COM0对应bit0(有的屏幕厂给出的图是从COM4 - COM1的,那么它对应的依然是bit3 - bit0)。接下来再看一张屏幕图纸就会明白。重点去看一个数码管,了解原理就可以显示所有段。第2个液晶数码管,有7段,分别为A,B,C,D,E,F,G。也就分别为下面COM\SEG地址对应关系图中的5A,5B,5C,5D,5E,5F,5G。如:要想让表示为5的数码管显示出来数字4,如图:就要点亮图中的5B,5C,5F,5G段,于是就要向pin10写入1100即0x0C,向pin11写入0110即0x06(bit3-bit0对应COM4-COM1)这里的pin就是SEG也就是地址,但是具体是如何对应的需要硬件原理图,我这里P上接线图由接线图可以知道屏幕上的SEG0和HT1621上的SEG0对应,依次至SEGn那么书回刚才的问题,点亮图中的5B,5C,5F,5G段,于是就要向SEG10写入1100即0x0C,向SEG11写入0110即0x06。理解到这里我们就可以写出第二个函数,如下:/******************************************************************************* * fuction WritetoHT1621 * brief 将要显示的数据写到HT1621 * param Addr:写入初始地址,Data:写入数据,Mode:0x80 /0xa0 * return 无 *******************************************************************************/ void WritetoHT1621(u8 Addr,u8 Data,u8 Mode) { PinLow_CS; WriteDatatoHT1621(Mode,3); //写入0x80 /0xa0 WriteDatatoHT1621(Addr<<2,6);//写入地址 WriteDatatoHT1621(Data<<4,4);//写入数据 这里是对应单个SEG写的 故而为4 PinHigh_CS;}1234567891011121314第二个函数的参数:Mode:0x80即表示命令标识100,0xa0即表示命令标识101。解析:0x80:1000 0000 只去高三位就是100,0xa0:1010 0000 只去高三位就是101 。三、第三个函数由于HT1621在正常工作开始之前需要进行一些初始化的步骤,那么转换到代码层理解就是需要发一些命令帮助HT1621完成初始化,于是如果封一个专门来发送命令的函数岂不美哉!/******************************************************************************* * fuction WriteCmdtoHT1621 * brief 写命令到HT1621 * param Cmd:命令 * return 无 *******************************************************************************/ void WriteCmdtoHT1621(u8 Cmd) { PinLow_CS; //拉低CSCS拉低时WR有效 WriteDatatoHT1621(WrCmd,3);//写入命令标志100 0x80 3 WriteDatatoHT1621(Cmd,8); //写入命令数据 WriteDatatoHT1621(0,1); PinHigh_CS; //拉高CS脚}1234567891011121314该函数中用到了一个宏:WrCmd 即0x80写入命令标志100 在文章开始之前已经声明。四、第四个函数终于到了初始化HT1621函数的部分了,针对不同的MCU大同小异,根据不同的需求配置HT1621,详见DataSheet。/******************************************************************************* * fuction HT1621Init * brief HT1621初始化 * param 无 * return 无 *******************************************************************************/ void HT1621Init(void) { /* 引脚配置相关 */ PinOutput_CS; PinOutput_WR; PinOutput_Data; PinHigh_CS; PinHigh_WR; PinHigh_Data; /* 配置HT1621 */ WriteCmdtoHT1621(SYSEN); WriteCmdtoHT1621(RC256K); WriteCmdtoHT1621(BIAS); WriteCmdtoHT1621(LCDON);// WriteCmdtoHT1621(SYSDIS);//根据需求添加// WriteCmdtoHT1621(WDTDIS);//根据需求添加 BackLightInit;//背光灯 WriteCmdtoHT1621(LCDON);}123456789101112131415161718192021222324252627至此,HT1621的驱动就已经写完了,如何让自己的断码屏达到自己想要的效果,还需要封几个与屏幕硬件连接相关的函数(只要懂得点亮一个完整的数码管的原理,点亮相关屏幕不是问题),具体要看屏幕图纸和硬件连接。
03-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值