c语言单片机实例

更新时间:2023-11-06 07:41:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第三章 单片机C语言编程基础

本章主要学习51单片机的外部引脚和内部结构等,叙述一下。本书任务驱动教学,引入案例有浅变深,循序渐进,给读者留下思考和发挥空间。

3.1 利用单片机的I/O口驱动LED

3.1.1利用单片机的P0.0 端口驱动1只LED闪烁

编程的目的是利用C语言控制单片机I/O端口按要求输出矩形波脉冲信号,信号的周期由延时函数决定。

一、电路原理

STC-89C51单片机的P0口采用为OD门输出,不存在拉出电流,因此利用P0驱动负载时有两种接法:一种是加上拉电阻R2,见图3-1-1,既用1K?电阻接电源正极,此时P0口输出高电平时LED亮;另一种电路为P0.7低电平驱动有效,在P0.7输出低电平时,STC-89C51端口灌入电流达20mA,可直接驱动小负载。图3-3-1中的R3为限流电阻,限制LED2的工作电流。

VCC(+5V)R3 1KIC STC89C51CY 12MHz1918XTAL1XTAL2P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD393837363534333221222324252627281011121314151617R2 1KLED1LED2C1 30PC2 30PR1 1K9RESETC3 10μ293031PSENALEEAP1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7VCC12345678

图3-1-1 驱动LED电路原理

单片机的最小系统包括晶体振荡电路,加电复位电路,同时要求单片机的31引脚EA接高电平。时钟频率主要由晶体CY决定,C1、C2为独石电容,用于微小调整单片机时钟的振荡频率;R1和C3组成加电复位电路,C3为电解电容器;整个电路由+5V电压供电。电路使用的元件参数见表3.1.1。

表3.1.1 3-1-1电路元件表

元件名称 单片机 电容器

序号 IC C1

标称 STC89C51 30PF

规格(封装,功率电压等参数)

DIP40 独石

作用 核心芯片 振荡

电容器 电容器 晶振 电阻 电阻 电阻 发光二极管 发光二极管

C2 C3 CY R1 R2 R3 LED1 LED2

30PF 10μF 12MHz 1K? 1K? 1K?

??独石 点解电容器

S型 1/4W,金属膜 1/4W,金属膜 1/4W,金属膜 红色高亮 红色高亮

振荡 复位 振荡

电容器C3放电电阻 端口电位上拉电阻

限流电阻 显示 显示

5 5

二、程序设计

1.程序设计平台

程序设计采用keil C 软件,为了养成一个良好的文件管理习惯,建议:编程前,在计算机的某个硬盘分区下建立一个目录,目录的名字为你编写程序的主题,然后把keil C产生的所有文件都放在该目录下。程序设计步骤如下:

(1)运行keil C,创建一个项目。利用keil C菜单栏中project-new project创建,项目的名字为你编程的主题,如本案例可以用“LED_1.uv2”或“一个LED闪烁实验.uv2”,存放目录为你的主题目录下;

(2)创建建一个文件,然后以“.c”后缀名,文件存放在你的主题目录下; (3) 把c文件添加在你的项目中,在project workspace窗口利用add file to group?实现。如果软件界面不显示这个窗口,运行keil C菜单栏中的view-project window。

(4)设置编译器,是编译过程中能生成“.hex”文件。默认文件名与主题名字相同。运行project-option for‘target 1’-output窗口下点击create HEX file。

(5)在编程区域写你的程序,结束后存储文件并编译,要做检查,尽量避免警告出现,直到程序编译无误为止。

(6)程序烧写并试运行。这个过程称为软件和硬件联合调试,如果实验板无误,程序编译通过,但在硬件上运行不成功是常用的事情,需要对程序进行多次调试。在没有实验板的情况下,可以利用proteus软件仿真调试,也可以检验你的程序设计结果。

2.程序设计

(1)利用P0.0口驱动LED闪烁,高电平有效

/*****************************************************************************/

#include //包含头文件

sbit LED = P0^0; // LED接P0.0。在kell C51软件中,定义P0.0为P0^0, void delay(unsigned char x) //延时函数 { unsigned char i,j; for(i = 0;i < x;i++) for(j = 0;j < 200;j++); }

void main(void) //主函数 { While(1) //程序死循环 {

LED = 0; //P0.0输出低电平,LED灭

void delay(100); //调用延时函数,延时一段时间,约0.3秒,不精确 LED = 1; //P0.0输出高电平,LED亮

void delay(100); } }

/*****************************************************************************/

(2)利用P0.7端口驱动LED闪烁,低电平有效

/*****************************************************************************/ #include //包含头文件,程序为小5号字 sbit LED = P0^7;

void delay(unsigned char x) //延时函数

{ unsigned char i,j; for(i = 0;i

void main(void) //主函数 { while(1) {

LED = ~LED; //LED初始状态为灭,执行一次,LED改变一次状态

void delay(100); //延时一段时间

} }

/*****************************************************************************/

三、程序说明

1.应为使用的单片机芯片为STC89C51,因此程序开始处加入#include,文件reg51.h中包含了51芯片所有特殊功能寄存器的名称定义和相对应的地址值;

2. 单片机程序单步顺序执行,先执行主函数,在主函数可以调用分函数,分函数可以调用分函数,但分函数不能调用主函数,程序执行一条命令再执行下一条,单片机等待的过程是执行了一个循环命令或一个浪费时间的程序,实际执行过程永远不会结束。delay()为函数延,单片机在执行此函数相关指令时占用的时间过长,在执行过程中,如果没有中断,单片机只能忙这一件事情。利用delay()不能得到精确的延时。延时函数还可以利用下面的函数实现。

/**************************/ void delay(unsigned int x) {

while(x) x--; }

/**************************/

3. 利用位定义命令让LED等价于P0.0或P0.7,等于先sbit P0_0 = P0^0,然后#defined LED P0_0,也在程序前面不做此类定义,在程序里面直接写成P0^0 = 1或P0^0 = 0,先定义是为了增加程序的可读性。程序执行P0^0 = 1后,P0.0对以的单片机内部位寄存器就设置为高电平,同时P0.0端口也输出高电平,单片机的所有I/O口都可位未定义,也可以字节定义。

4. 单片机C语言程序设计需要的C语言关键字不多,并且在keil C 中用到的关键字是独有的,因此对于没有学习过C语言的人学习单片机C语言程序设计困难并不是很大,主要掌握单片机C语言书写格式,怎样用C语言控制单片机的硬件资源,另外在编程时,还要有清晰的逻辑思维头脑和认真实践,由浅逐步深入学习,当你坚持到最后时,单片机C语言程序设计实际上很简单。

5. 每个人在编写程序时都有自己的风格。一般情况下,函数的字符左行距为0,其下每条语句前留一个“tab”键空。算数逻辑符号的左右留一个空格,关键语句要有中文或英文说明,每一个函数有时也可以用“/**.....**/”上下隔开这样有助于提高程序的层次感和可读性。

3.1.2 利用P0口驱动8个LED,产生跑马灯或流水灯效果

一、参考电路

实验电路见图3-3-2所示,在单片机的最小系统的基础上,P0口依次接入8个LED,P0口的上拉电阻可以使用8个1K?电阻。

VCC(+5V)R2~9 1KC1 30PC2 30PR1 1KIC STC89C51CY 12MHz1918XTAL1XTAL2P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD3938373635343332212223242526272810111213141516179RESET??LED1-8C3 10μ293031PSENALEEAP1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7VCC12345678

图3-1-2 流水灯电路

在利用Proteus软件仿真时,可以用电阻排代替。单片机最小系统在单片机元件放置后已经默认,

即C1、C2、C3、CY、R1可以省略。其它元件选取见表3.1.2所示。

表3.1.1 3-1-2电路Proteus软件元件表

元件名称component

单片机 电阻排 发光二极管

总类Category Micoroprocessor IC

Resistor Optoelectronics

分类Sub- Category

8051 Family Resistor Pack

LEDs

结果Results 80C51 RESPACK-8 led-red

模型Model type

ANALOG DIGITAL

二、参考程序

/*****************************************************************************/ #include void delay(void) {

unsigned char i,j; for(i = 0;i < 255;i++) for(j = 0;j < 255;j++); }

void main(void) {

unsigned char j = 0x01; while(1) {

j = j << 1;

if(j == 0x00) j = 0x01; P0 = j; delay();

} }

/*****************************************************************************/

三、程序说明

1.语句j = j << 1,执行的目的是控制P0整个字节的数据在循环时左移变化,程序循环第一次, P0 = 0x02,P0.1连接的LED亮,其它灭;循环第七次,P0.7连接的LED亮,其它灭;循环第八次,j = 0x00,if语句条件满足,j = 0x01,P0.0连接的LED亮,其它灭,然后依次变化下去。如果P0口驱动8个LED低电平有效,如下修该:

/**********************/ void main(void) {

}

unsigned char j = 0xfe; while(1) {

j =( j << 1) | 0x01 ; if(j = 0xff) j = 0xfe; P0 = j; delay(); }

2. delay()函数无形参,延时时间不能设置。

3.1.3 利用P0口驱动一个数码管,显示0 – 9,并循环

一、参考电路

实验电路在单片机的最小系统基础上,P0口接一只共阳数码管,见图3-1-3。带小数点的数码管是由8个LED组成,七个LED组成数字,另一只LED用来显示小数点。如果数码管内部的8只LED的正极接在一起,负极分别引出,引脚依次命名为a、b、c、d、e、f、g和dot,称为带小数点的7段共阳极性数码管。

VCC(+5V)aC1 30PC2 30PR1 1KIC STC89C51CY 12MHz1918XTAL1XTAL2P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD393837363534333221222324252627281011121314151617R2~9 200?ACagdbcdot9abcfdefegdotRESETSEVEN_SEGC3 10μ293031PSENALEEAP1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7VCC12345678图3-1-3 单片机驱动共阳数码管电路

单片机的P0.0-P0.7口分别接数码管的a-dot引脚,如果让数码管显示1,数码管b、c段亮,程序控制P0输出0xbe十六进制编码即可,因此共阳数码管显示0-9十进制数字,需要利用10个显示码组成的数组。对于共阴数码管,也有相应的编码要求。小数点在不用时一般不让显示,高位端口P0.7输出高电平即可。

由于P0每个端口的灌电流达20mA,数码管每段LED正常显示5mA即可,因此需要R2~9用来限制数码管每一段电流,以防止驱动电流过大而烧毁器件。利用Proteus软件仿真时,数码管采用Optoelectronics元件库中7-Segment Displays下的7-SEG-COM-ANODE。

二、参考程序

/*****************************************************************************/ #include

code unsigned char seven_seg[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void delay (void) /* 时间延迟函数 */ {

unsigned char i,j;

for (i = 0;i < 255;i++) for (j = 0;j = 255;j++); }

void main (void) {

unsigned char i; /* 变量 i 用来储存 0~9 */ /*无穷循环 */ while (1) {

for (i = 0; i<10; i++)

本文来源:https://www.bwwdw.com/article/aqp2.html

Top