上班族

 找回密码
 立即注册
查看: 665|回复: 0

SDCC编译51单片机笔记

[复制链接]

568

主题

726

帖子

2412

积分

金牌会员

Rank: 6Rank: 6

积分
2412
发表于 2021-7-14 10:41:48 | 显示全部楼层 |阅读模式
本帖最后由 云谷鹤峰 于 2021-7-14 10:42 编辑

一、main没有循环语句但还会执行循环:
举例:
#include <8051.h>
__sbit __at 0x80 relay;
void delay(long int i)
{
    while(i--);
}
int main()
{
    delay(100000);
    relay=0;
    delay(50000);
    relay=1;
    return 0;
}
目的上电后让继电器延时吸合再延时断开,实际执行情况是继电器循环执行吸合及断开
原因及解决方法:
有的单片机程序内如果没有循环程序,会从头执行到最后然后返回最开始继续执行。在写单片机程序的时候,最好是加上while循环,即便你的程序只运行一次,也要在最后加上while(1);使其一直指向这个语句而不会出现误操作。实测keil5及sdcc编译51、stm32、f103zet6 不加while(1)main都会循环执行。

二、数据类型扩充:
1、sfc:特殊功能寄存器声明
举例:
__sfc __at 0x80 led;
将P0口声明为led

#define led P0;
将P0口宏声明为led

2、sbit:特殊功能位声明
举例:
__sbit __at 0x80 led;
将P0_0口声明为led

三、将数组用code写入到rom中:
举例:
u8 __code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
与keil5编写方法不同,需要在code前加__

四、变量取反:
取反有两种“!”“~”
!符号是位取反(是“位”),只针对位变量。
~符号是按位取反(是“按位”),针对字节变量

五、精确延时:
实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。 今天主要介绍软件延时,关于硬件延时,之后定时器部分再做详细说明。
首先介绍单片机的几个周期
在电子技术中,脉冲信号是一个按一定电压幅度,一定时间间隔连续发出的脉冲信号。脉冲信号之间的时间间隔称为周期;而将在单位时间(如1秒)内所产生的脉冲个数称为频率。频率是描述周期性循环信号(包括脉冲信号)在单位时间内所出现的脉冲数量多少的计量名称;频率的标准计量单位是Hz(赫)。电脑中的系统时钟就是一个典型的频率相当精确和稳定的脉冲信号发生器。
指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。
时钟周期:也称为振荡周期,一个时钟周期 = 晶振的倒数。对于单片机时钟周期,时钟周期是单片机的基本时间单位,两个振荡周期(时钟周期)组成一个状态周期。
机器周期:单片机的基本操作周期,在一个操作周期内,单片机完成一项基本操作,如取指令、存储器读/写等。
机器周期=6个状态周期=12个时钟周期。
51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/ 晶振频率)= x μs。常用单片机的晶振为11.0592MHz,12MHz,24MHz。其中11.0592MHz的晶振更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。
接下来列出这三种不同的晶振的延时函数
1、 11.0592MHz
//N ms延时
void delay_ms(uint n)
{
uint i,j;
for(i=n;i>0;i–)
for(y=114;y>0;y–);
}
2、12MHz晶振
//延时n毫秒void delay_ms(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i )
        for(j=0;j<123;j );
}
//延时n秒void delay_m(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i )
        for(j=0;j<21738;j );
}
//延时10*n微秒void delay_10um(unsigned int n)
{
    while(n--);
}
3、24MHz晶振
//延时n毫秒
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i
//延时n秒  void delay_s(unsigned int n)  
{  
    unsigned int i=0,j=0;  
    for(i=0;i<n;i )  
        for(j=0;j<54053;j );   
}  
//延时10*n微秒  void delay_10us(unsigned int n)  
{  
    unsigned int i=0;  
    char j=0;  
    for(i=0;i<n;i )  
        for(j=0;j<2;j );  
}  
建议大家封装为头文件,可以方便的调用。
接下来介绍几个自动适应主时钟的延时函数
//参数:ms,要延时的ms数,自动适应主时钟  #define MAIN_Fosc        11059200UL    //定义主时钟HZ  typedef unsigned int INT16U;  
void delay_ms(INT16U ms)    //INT16U 等价于 unsigned int  
{  
    INT16U i;  
    do{  
        i=MAIN_Fosc/9600;  
        while(--i);     //96T per loop  
    }while(--ms);       //--ms  ms=ms-1  
}  
//5us 延时函数,自动适应主时钟  #define MAIN_Fosc        11059200UL    //定义主时钟HZ  
void delay5us()  
{  
    #if MAIN_Fosc == 11059200  
        _nop_();  
    #elif MAIN_Fosc == 12000000  
        _nop_();  
    #elif MAIN_Fosc == 22118400  
        _nop_(); _nop_(); _nop_();  
    #elif  
}  
单片机中还可自动生成
//11.0592MHZ延时100微秒
void Delay100us()       //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    i = 2;
    j = 15;
    do
    {
        while (--j);
    } while (--i);
}
//100US
void Delay100us()       //@12.000MHz
{
    unsigned char i, j;

    i = 2;
    j = 39;
    do
    {
        while (--j);
    } while (--i);
}
//100US
void Delay100us()       //@24.000MHz
{
    unsigned char i, j;

    i = 3;
    j = 82;
    do
    {
        while (--j);
    } while (--i);
}



                                                                                            

                                                                                                                                                                                                                                                                                                                                                                                                                        
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|shangbanzu.xyz

GMT+8, 2025-12-16 15:04 , Processed in 0.061919 second(s), 30 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.. 技术支持 by 巅峰设计

快速回复 返回顶部 返回列表