📄 z.txt
字号:
单片机C语言网站&C51BBS论坛 → C51常见问答
C51怎样将子程序段定位在1个固定的地址位置?
作者:Youth
问:C51 怎样将1个子程序段定位在1个固定的地址位置?
以下2问题均要用C51解决
1。 怎样将1个子程序段定位在1个固定的地址位置?
例如将 INT BCD2HEX(INT XX)定位在1000H
2。 HOW在EEPROM 中固定的位置存放1字符串?
如在200H处放“COPYRIGHT 2001-11”
答: 函数定位与变量定位...
1、函数定位:
假如要把C源文件 tools.c 中的函数
int BIN2HEX(int xx)
{
...
}
放在CODE MEMORY的0x1000处,先编译该工程,然后打开该工程的M51文件,在
* * * C O D E M E M O R Y * * *
行下找出要定位的函数的名称,应该形如:
CODE xxxxH xxxxH UNIT ?PR?_BCD2HEX?TOOLS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填写如下内容:
?PR?_BCD2HEX?TOOLS(0x1000)
再次Build,在M51中会发现该函数已放在CODE MEMORY的0x1000处了
2、赋初值的变量定位:
要将某变量定位在一绝对位置且要赋初值,此时用 _at_ 不能完成,则如下操作:
在工程中建立一个新的文件,如InitVars.c,在其中对要处理的变量赋初值(假设是code变
量):
char code myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,若定义的是code型,则在
* * * C O D E M E M O R Y * * *
下可找到:
CODE xxxxH xxxxH UNIT ?CO?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填入:
?CO?INITVARS(0x200)
再次编译即可。
相应地,如为xdata变量,则InitVars.c中写:
char xdata myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,在
* * * X D A T A M E M O R Y * * *
下可找到:
XDATA xxxxH xxxxH UNIT ?XD?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Xdata
中填入:
?XD?INITVARS(0x200)
再次编译即可。相应地,若定义的是data/idata等变量,则相应处理即可。
3、若有多个变量或函数要进行绝对地址定位,则应按地址从低到高的顺序排列。
DvNews
来源:
阅读:899 次
日期:2003-11-4
【 评论 】 【 推荐 】 【 打印 】 【 字体:大 中 小 】
上一篇:怎样将编译日期和时间加入C51程序中?
下一篇:
>> 相关新闻
>> 点击查看全部留言...
发表意见和建议
点评: 字数0
姓名:
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
关于C51BBS | 在C51BBS刊登广告 | 联系方式 | 网友投稿 版面设计:DJ
版权所有 ?1999-2003 单片机C语言网站 版主:龙啸九天 E-mail: c51bbs@vip.163.com
Powerby DvNews 2.6
首页 单片机C语言论坛 产品信息 ARM7编程入门 C51常见问答 C51源程序 论坛精华 精品共享 网友投稿
单片机C语言网站&C51BBS论坛 → C51常见问答
怎样在我的源程序中实现软件复位?
作者:
C51: 用C51实现软件复位
问:
怎样在我的源程序中实现软件复位?
答:
您可以使用下面的程序跳到0000H实现软复位,下面的程序实际上是一个函数指针,指针指向了0000H地址。
((void (code *) (void)) 0x0000) ();
下面的例子将实现软件自复位void reset (void)
{
((void (code *) (void)) 0x0000) ();
}
void main (void)
{
reset ();
}
你可能注意到以上的软复位程序并不能清除8051的中断系统和某些8051的外围设备,当您在中断程序中调用上面的软件复位程序后,中断将再不能触发。因此,以上的软复位程序不能在中断子程序中调用。
下面的小段汇编函数可以在中断程序或主程序中调用,该函数将0x0000压栈,然后通过“RETI”出栈,这将清除中断环境并让程序从0000H重新开始运行。
?PR?RESET SEGMENT CODE
RSEG ?PR?RESET
; C prototype: void reset (void);
PUBLIC reset
reset: POP ACC ; pop return address
POP ACC
CLR A ; push 0 as new
PUSH ACC ; return address to stack
PUSH ACC
RETI ; execute return of interrupt
END
以上程序在选择bank 0寄存器组时工作良好,假如选择的不是bank0寄存器组,那么可能无法获得预料的结果。你应该在以上的程序或启动代码中加上“MOV PSW, #0”来选择bank 0寄存器组。
以上文章由龙啸九天翻译自KEIL FAQ,可能有疏漏,欢迎提出。
DvNews
来源:
阅读:1306 次
日期:2003-10-22
【 评论 】 【 推荐 】 【 打印 】 【 字体:大 中 小 】
上一篇:一篇详细的KEIL C51 UV2使用教程
下一篇:怎样将编译日期和时间加入C51程序中?
>> 相关新闻
>> 点击查看全部留言...
这种办法不是太可靠!有时会出现某些变量不能清零的现象,最可靠的办法还是用硬复位。
推荐一本书,由周航慈老师著的(不是编)的《单片机设计技术基础》的抗干扰技术一章,对热启动的描述,这本书以及重印了多次,并再版,北航出版
你可以选则适当的看门狗电路加以软件的控制 或者你可以选用winbond 单片机组内有自带的看门狗控制字适当设计软件可使程序自重起
发表意见和建议
点评: 字数0
姓名:
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
关于C51BBS | 在C51BBS刊登广告 | 联系方式 | 网友投稿 版面设计:DJ
版权所有 ?1999-2003 单片机C语言网站 版主:龙啸九天 E-mail: c51bbs@vip.163.com
Powerby DvNews 2.6
首页 单片机C语言论坛 产品信息 ARM7编程入门 C51常见问答 C51源程序 论坛精华 精品共享 网友投稿
单片机C语言网站&C51BBS论坛 → C51常见问答
一篇详细的KEIL C51 UV2使用教程
作者:
《一篇详细的KEIL C51 UV2使用教程》
(这篇文章在2001年由w78713发表在C51新闻组,很古老但也很实用!)
这里我大致说说怎么开始keil vision2,因为我刚开始用它,不当之处请莫见笑!希望可以互相交流,共同促进。
1、首先是新建一个*.c文件(file|new),写入你的程序,保存;
2、由(project|new project)建立新工程,按程序要求输入工程名(默认后缀是.uv2),确定后弹出对话框提示你选单片机,比如我是选atmel的89c52,然后确定;
3、由(view|project window)打开project window,在工程管理区显示有一个target1的文件夹,单击其前面的+号打开该文夹,可看到有一个名为source group1的子文件夹,右击它,在弹除菜单里选择add file to group 'source group1', 在弹出‘打开’对话框里选中刚才建立的*.c文件,确定后,再用close关闭对话框,你可以看到source group1的子文件夹里有文件了(就是刚才那个加进去的*.c文件)。双击将它打开,这时如果程序的保留字没有加亮,可以用(view|option)打开对话框,选defalt,在确定就行了,当然你可以按你的习惯选其他的;
4、至此你可以看到(project|build)菜单或按钮栏可用了。选择它(或按F7)编译你的程序,在改正程序中的所有错误后,debug|start/stop debug session菜单和相应的按钮就可用了,选择它就可以开始调试了。在view|memory打开内存观查器,在address栏里输入d:0x**可以看到内部ram的直接寻址的变量,输入x:0x****,可以看到指定的外部ram地址,c:0x****对应代码区,而i:0x** 可以观察内部ram的间接寻址的变量(89c52的129~256地址,与特殊寄存器的直接寻址区分)。我还不知道如果观察ram中直接位列表,不知道是不是vision2没有提供这个功能,如果你知道麻烦告诉我一声,不过可以用watch,观察个别的位变量。
实际上你如果用过tc,bc或vc的调试器,你很快就会用vision2了。好,祝你好运!
DvNews
来源:
阅读:3663 次
日期:2003-10-21
【 评论 】 【 推荐 】 【 打印 】 【 字体:大 中 小 】
上一篇:KEIL C51支持的完整芯片列表
下一篇:怎样在我的源程序中实现软件复位?
>> 相关新闻
>> 点击查看全部留言...
大家有什么好的建议,告诉我啊,我想学习c51和arm,现在还找不着门路,郁闷中啊。 develop_2000@163.com
看看这个,不错http://www.cdle.net/alldata/C51/index.htm
我重装2000系统之后,keil就死活装不上去,出现一个不支持此接口的对话框,不知道是什么原因,怎么解决,请帮忙!
不错,我也是菜鸟,请多多指点
还好
发表意见和建议
点评: 字数0
姓名:
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
关于C51BBS | 在C51BBS刊登广告 | 联系方式 | 网友投稿 版面设计:DJ
版权所有 ?1999-2003 单片机C语言网站 版主:龙啸九天 E-mail: c51bbs@vip.163.com
Powerby DvNews 2.6
首页 单片机C语言论坛 产品信息 ARM7编程入门 C51常见问答 C51源程序 论坛精华 精品共享 网友投稿
单片机C语言网站&C51BBS论坛 → 论坛精华
实时时钟芯片DS1302 C51源程序,作者:广州老赵
作者:
/*********************************************************************
公司名称:
模块名称:DS1302.c
功 能:实时时钟模块 时钟芯片型号:DS1302
说 明:
程序设计:zhaojunjie
设计时间:2002.03.02
版 本 号: 20020302
*********************************************************************/
#include <jyh.h>
sbit T_CLK = P2^7; /*实时时钟时钟线引脚 */
sbit T_IO = P1^4; /*实时时钟数据线引脚 */
sbit T_RST = P1^5; /*实时时钟复位线引脚 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
void RTInputByte(uchar); /* 输入 1Byte */
uchar RTOutputByte(void); /* 输出?1Byte */
void W1302(uchar, uchar);
uchar R1302(uchar);
void Set1302(uchar *); /* 设置时间 */
void Bcd2asc(uchar,uchar *);
void Get1302(uchar curtime[]); /* 读取1302当前时间 */
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:BurstW1302T()
功 能:往DS1302写入时钟数据(多字节方式)
说 明:先写地址,后写命令/数据
调 用:RTInputByte()
入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void BurstW1302T(uchar *pWClock)
{
uchar i;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -