导航:首页 > 操作系统 > 51单片机总结

51单片机总结

发布时间:2022-10-16 11:59:53

1. 学习MCS-51(具体以89C51为例)系列单片机的体会

http://www.38xian.com/index.aspx?menuid=4&type=articleinfo&lanmuid=19&infoid=685&language=cn

http://www.38xian.com/index.aspx?menuid=4&type=articleinfo&lanmuid=19&infoid=686&language=cn

又来看了一下,修改一下吧,加点文字

C语言学习总结
搞嵌入式的,大都用C语言写代码,本人从事单片机开发,也写了不少的代码,一直习惯用 if 、switch打天下,在定义数据结构的时候也只用到 字符型、整型、数组,位;很少用结构体,共用体,枚举,因为咱C语言学得不好,和它们不熟,总感觉它们不那么好招呼,重要的是自已觉得没必要用上它们。随着越来越多的积累,咱写代码的风格也在不断的发生变化,从以前的喜欢将所有的函数及数据的定义写在一个文件里到逐渐的将函数按功能模块化、从以前的习惯直接在程序里写常数到慢慢的开始用上宏来代替,咱编程的风格也逐渐开始正规化,编程水平也逐步提升,当然这些成绩都源于咱不断的学习,学习匠人的编程规范、学习herald的感悟设计、还有网上写得非常出色的代码以及STM32的固件函数库,在咱的不断领悟和思考下,总结了几点关于C语言的用法,与大家共同分享。

一、 学习匠人的头文件包含巧妙用法
当一个头文件被多个C文件包含,且该头文件中定义了这些C文件的公共变量,则在编译的时候会出现重复定义,导致编译通不过,通常我们会采用如下两种做法来解决上述问题。
(为了让问题表述得更清楚,我们假设两个C文件C1,C2,C3,一个头文件H1,C1,C2,C3有两个公共变量V1和V2)
1、 在C1文件中定义变量V1和V2,在C2和C3文件中对V1,V2用extern声明;
2、 在C1文件中定义变量V1和V2,在H1中对V1,V2用extern声明,然后在C2和C3文件中包含H1;
很显然,以上两种方法都要对V1和V2书写至少两次,一次定义,一次外部声明,且不是在同一文件下,这样不利于管理和修改,有没有一种方法可以让这些公用的变量放在一个文件里,且只要书写一次呢?
偶在二姨那里无意中看到匠人的发帖,就是关于该问题的讨论,现在我转发一下,与大家同共分享。首先我们将要用到的公共变量全部书写到com.h文件中,每一个变量在定义前加一个符号EXT_,当该头文件被main.c函数包含时,定义EXT_为空,表示com.h中的变量在main.c中被定义,当被其它文件包含时,定义EXT_为extern,表示外部声明,如:
Com.h文件:
//避免重复定义
#ifdef root
#define EXT_
#else
#define EXT_ extern
#endif

//全局变量
EXT_ u8 variable1; //该变量在三个C文件中都要用到

Main.c
#define root //在包含com.h前定义root
#include "com.h"

二、 用结构体的方式来定义总线或外设地址
当一个整体包含不同类型的多个成员时,通常用结构体来定义结构体变量,这样内存会将这些变量按照递增的方式分配到相邻的地址(不对齐的地方会有填充),按“结构体名.成员名”的方式访问结构体内的成员,这是访问结构体变量的方式;但是还有一种指向结构体变量的指针,它可以将某个地址转换成该结构体类型的指针,比如寄存器的定义:
(以下是摘自STM32固件函数库,关于GPIO的定义)
typedef struct
{
vu32 CRL; //0
vu32 CRH; //偏移量4
vu32 IDR; //偏移量8
vu32 ODR;
vu32 BSRR;
vu32 BRR;
vu32 LCKR;
} GPIO_TypeDef;

#define GPIOA_BASE ((u32)0x40010800) //GPIOA的基地址为0x40010800
#define GPIOA (GPIO_TypeDef *) GPIOA_BASE; //强制类型转换为GPIO_TypeDef类型的指针

这样在操作GPIOA的寄存器时只要这样写就可以了
读: X="GPIOA-">CRL; 写:GPIOA->CRL=X;
或 读: X=(*GPIOA).CRL; 写:(*GPIOA).CRL =X;

当然,要达到上述目的也可以采用如下方式
#define GPIOA_ CRL 0x40010800
#define GPIOA_ CRH 0x40010804
#define GPIOA_ IDR 0x40010808
#define GPIOA_ ODR 0x4001080C
#define GPIOA_ BSSR 0x40010810
#define GPIOA_ LCKR 0x40010814

很明显,第一种书写方式更加正规化,且当定义多个GPIO时,只要将其它GPIO的基地址强制转换为该结构类型的指针即可。

再来看看一个定义外部总线的例子
typedef struct
{
vu8 CH375_DATA;
vu8 CH375_CMD; //偏移量1
} CH375_TypeDef;
#define CH375 ((CH375_TypeDef *) 0x6c000000)
CH375-> CH375_DATA=data; //往0x6c000000地址处写数据
CH375-> CH375_CMD=cmd; //往0x6c000001地址处写命令
怎么样,是不是方便多了。重要的是代码的观赏和可读性提高了。

三、 用枚举数据类型来定义特定的状态
在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个函数在操作过程中会返回几个特定的状态:操作成功,操作失败,忙,等等。如果我们直接在函数里用0,1和2来表示这三种状态,有时偶尔会出现数值与实际状态对不上号的情况,造成置状态和判断状态错误,那么我们可以在程序里用宏或者枚举来事先定义好这些状态。
如:用宏定义:
#define Sucess 0
#define Failure 1
#define Busy 2

用枚举
typedef enum { Sucess = 0, Failure , Busy } FlagStatus;

四、 用共用体类型定义共享内存空间
共用体类型定义的数据是将多个成员共享同一内存空间,该空间的大小为最大成员的大小,其用法与结构体完全相同,但值得注意的是不能同时引用多个成员,在某一时刻只能使用其中之一成员。
在程序中如果全局变量比较多,包含几个结构和数组,如果这些全部定义的话势必会占大量的内存,有可能还会导致单片机内存不够,如果能让几个不同时用到的数组和结构变量共享一段内存,则能省出很多的内存空间。
比如以下输入输出若不同时进行,则可以共享同一段内存空间
union {
struct {
unsigned char Flag;
unsigned char Type;
unsigned char State;
unsigned long DataLen;
unsigned char Buffer[64];
}DataOut;
struct {
unsigned char Flag;
unsigned char Type;
unsigned char State;
unsigned long DataLen;
unsigned char Buffer[64];
} DataIn;
} BOC;

C语言博大精深,丰富多彩,用得好能很好的发挥它的作用,同时学习好的编程方法养成良好的编程习惯对于一名设计人员来说也是极其的重要,以上四点都是本人自身积累和学习的一些总结,希望能够与大家一起共同交流,共同学习和提高。

个人珍藏的好文章,贴出来分享

2. 总结出51单片机工程的创建步骤

可能有些刚接触51单片机开发的新手们,对于如何用keil创建一个项目感到无从下手,那么现在就示范一下如何用keil得51单片机项目

3. 51,PIC,AVR单片机它们的优点缺点都有哪些

51单片机,是嵌入式系统的起源。历史悠远,种类繁多。
优点:
①上手易(各种51教程、例程一捞一大把);
②价格低(10块钱以内各种选择);
缺点:
①标准51内置功能少,很多功能需外部支持,所以有很多外围芯片存在(现在国产STC已经弥补了内置功能少的问题,不过工业稳定性不好);
②工业性能不高,应用场景范围窄(主要应用在教育、消费类产品)
③兼容性低(厂家N多,各行其道,无法统一。除了STC号称有AT的所有型号兼容品,但同一品牌自身的产品兼容替换就不好)

PIC单片机,不知道怎么点评。
优点:
①工业稳定性非常好;
②内置功能强大;
③兼容性高(所有一样封装的IC都是Pin对Pin);
④应用场景宽(汽车、工业、医疗、安防……而且microchip一直在推陈出新)。
缺点:
①操作繁琐(即便是老手,也没法完全摸透PIC的使用套路,新手更难,写个流水灯都够你琢磨一段时间了);
②端口特性很讲究(同意的程序,这口能实现的,那口不一定能实现);
③硬件堆栈也讲究(低级单片机(便宜货)堆栈只有2~3级,就是主函数调一个子函数,子函数再调一个子函数就到头了;不过目前常用的都已经是8级、16级堆栈了,够用了);
④价格贵(动不动就是10块20块的)。
⑤对除法的运算能力低下(一条除法要上千个周期);
⑥无越级移位能力(个人总结,所谓越级,是8位单片机竟然不能操作1<<16操作(结果为long型))。

AVR单片机,没使用过!!

4. c51单片机复位电路的工作原理

如S22复位键按下时:RST经1k电阻接VCC,获得10k电阻上所分得电压,形成高电平,进入“复位状态”

当S22复位键断开时:RST经10k电阻接地,电流降为0,电阻上的电压也将为0,RST降为低电平,开始正常工作

(4)51单片机总结扩展阅读:

复位电路是一种用来使电路恢复到起始状态的电路设备,它的操作原理与计算器有着异曲同工之妙,只是启动原理和手段有所不同。复位电路,就是利用它把电路恢复到起始状态。就像计算器的清零按钮的作用一样,以便回到原始状态,重新进行计算。

和计算器清零按钮有所不同的是,复位电路启动的手段有所不同。一是在给电路通电时马上进行复位操作;二是在必要时可以由手动操作;三是根据程序或者电路运行的需要自动地进行。复位电路都是比较简单的大都是只有电阻和电容组合就可以办到了,再复杂点就有三极管等配合程序来进行了。

单片机复位电路主要有四种类型:

(1)微分型复位电路:

(2)积分型复位电路:

(3)比较器型复位电路:

比较器型复位电路的基本原理。上电复位时,由于组成了一个RC低通网络,所以比较器的正相输入端的电压比负相端输入电压延迟一定时间.而比较器的负相端网络的时间常数远远小于正相端RC网络的时间常数。

因此在正端电压还没有超过负端电压时,比较器输出低电平,经反相器后产生高电平.复位脉冲的宽度主要取决于正常电压上升的速度.由于负端电压放电回路时间常数较大,因此对电源电压的波动不敏感.但是容易产生以下二种不利现象:

(1)电源二次开关间隔太短时,复位不可靠:

(2)当电源电压中有浪涌现象时,可能在浪涌消失后不能产生复位脉冲。

为此,将改进比较器重定电路,如图9所示.这个改进电路可以消除第一种现象,并减少第二种现象的产生.为了彻底消除这二种现象,可以利用数字逻辑的方法和比较器配合,设计的比较器重定电路。此电路稍加改进即可作为上电复位和看门狗复位电路共同复位的电路,大大提高了复位的可靠性。

5. 总结mcs51单片机p0 p1 p2 p3的功能和特性

mcs51单片机的特性:

P0.0~P0.7 P0口8位双向口线(在引脚的39~32号端子)。

P1.0~P1.7 P1口8位双向口线(在引脚的1~8号端子)。

P2.0~P2.7 P2口8位双向口线(在引脚的21~28号端子)。

P3.0~P3.7 P3口8位双向口线(在引脚的10~17号端子)。

P0口有三个功能:

1、外部扩展存储器时,当做数据总线(如图1中的D0~D7为数据总线接口)。

2、外部扩展存储器时,当作地址总线(如图1中的A0~A7为地址总线接口)。

3、不扩展时,可做一般的I/O使用,但内部无上拉电阻,作为输入或输出时应在外部接上拉电阻。

总结如下:

单片机(Single-Chip Microcomputer)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统。

定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统。

在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,发展到现在的300M的高速单片机。

6. 如何学习c51单片机

1,楼主,你首先要学习C语言基础,就相当于80%会单片机了,因为现在所有8/16/32位(51系列,MSP430系列,ARM系列)都是使用C语言。
2,先看内核8051的单片机:台湾宏晶的STC89C51-DIP40/或其它如新茂,到网上买一个开发板,价格不会超过200元。
3,看一下单片机功能:包换内部FLASH、RAM、TIMER、INT、ADC、USB、ISP/IAR等。
4,编译环境、编程软件KEIL。
5,打开开发板的例子程序,在KEIL编译,下载到板,看结果和说明是不是相符,达到这样效果时,你心里肯定很激动,这时你真正学会了单片机,你成功了!!!!!。
6,单片机C语言举例:
sbitSPEAK=P1^5; //IO口定义为蜂鸣器控制
如果蜂鸣器正极接电源,SPEAK=0;蜂鸣器就会响,你看就是这么简单。
unsiggnechartemp;//定义TEMP为单字节变量。
sfrPORTAP1;//将P1口定义为PORTA
总结:多做开发板上的实验,你要多参与这样的项目开发,慢慢就会了。

7. 51单片机指令长度,有两字节三字节,指令寄存器长度是一个字节,指令长度等于指令寄存器长度不矛盾吗

指令长度等于指令寄存器长度,这并不矛盾。对于51单片机,执行指令时,是先取第一个字节的指令码,也叫操作码,进行译码,然后执行。如果是单字节指令就执行操作了。如果是两个字节,或三个字节的指令,就会再取出第二字节,第三个字节,第二,第三字节通常是立即数,地址,偏移量等操作数,取出这些操作数后,就会进行计算,或按立即数,地址传送数据了,是偏移量就计算目标地址然后跳转了。
总结,51单片机是逐一字节取出指令码的,并不是一下子全部取出二个,三个字节的指令。而只有第一个字节才是操作码,其余是操作数。

阅读全文

与51单片机总结相关的资料

热点内容
打开加密软件的方法 浏览:154
云存储服务器可靠吗 浏览:967
2核1g的云服务器能带动游戏嘛 浏览:898
逆命20解压码 浏览:144
徐州办犬证需要下载什么app 浏览:1002
百保盾是什么样的app 浏览:699
文件和文件夹的命名规格 浏览:796
java命令行运行java 浏览:664
搜索pdf内容 浏览:497
程序员装机必备的软件 浏览:12
php微信第三方登录demo 浏览:538
上海php工具开发源码交付 浏览:793
哪里有求购黄页的源码 浏览:194
商城矿机源码矿场系统 浏览:198
单片机的led灯熄灭程序 浏览:224
洛阳python培训 浏览:704
小键盘命令 浏览:194
单片机c语言返回主程序 浏览:816
dockerpythonweb 浏览:972
程序员算法有多强 浏览:717