c51时钟数码管显示流程图_C51学习记录

本文记录了C51学习过程中的数码管显示和延时函数的使用。通过示例代码展示了如何使用C51进行数码管静态和动态显示,包括位操作和流水灯效果,并探讨了共阳极和共阴极数码管的工作原理。此外,还介绍了74HC573和74LS138芯片在数码管驱动中的作用,以及如何使用74HC595移位寄存器进行点阵屏显示。最后,讨论了独立按键的查询和中断方式,以及如何实现按键输入对应数码管数值显示的功能。
摘要由CSDN通过智能技术生成

26b61658-8f22-eb11-8da9-e4434bdf6706.png

C51学习记录

C51板机,安装CH340驱动,使用stc-isp下载工具将调试软件下载到板机中,正常显示。

图一

//sbit是80c51的关键字,定义位变量P2的引脚。本地全局变量gLed1

sbit gLed1 = P2^0;

示例:#include<reg51.h>

sbit gLed1 = P2^0;

sbit gLed2 = P2^1;

sbit gLed3 = P2^2;

sbit gLed4 = P2^3;

sbit gLed5 = P2^4;

sbit gLed6 = P2^5;

sbit gLed7 = P2^6;

sbit gLed8 = P2^7;

void main(void)

{

gLed1 = 0;

gLed2 = 0;

gLed3 = 0;

gLed4 = 0;

gLed5 = 0;

gLed6 = 0;

gLed7 = 0;

gLed8 = 0;

while(1);}

循环点灯

#include<reg52.h>

#define LED_PORT P2

static void Delay(void);

void main(void)

{

LED_PORT = 0xf0;

Delay();

LED_PORT = 0x0f;

Delay();

}

void Delay(void)

{

unsigned char i=0, j=0, k=0;

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

for(j=0; j<60; j++)

for(k=0; k<60; k++);

}

C语言C51位操作,流水灯

#include<reg52.h>

#define LED_PORT P2

static void Delay(void);

void main(void)

{

while(1)

{

unsigned char i;

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

{ LED_PORT = (0xff & ~(1<<i));

Delay();

}} }

void delay(void)

{

unsigned char i, j, k;

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

for(j=0; j<60; j++)

for(k=0; k<60; k++);}

数码管:

共阳极---正极接VCC(相当于接高电平1) ,负极接单片机引脚,低电平发光。

共阴极---负极接GND(相当于接低电平0),正极接单片机引脚,高电平发光。

数码管的断码:一个数码管能显示:0123456789AbCdEF(0-F)---八位二进制就是断码

74HC573芯片提升阳极的驱动能力,增大电流,是的数码管点亮。

74LS138是一个38译码器(数字电路)三个输入,确定八个输出。

#include<reg51.h>

#include<intrins.h>

#define DIG_PORT P0

void delay800ms(void);

sbit gA = P2^2;

sbit gB = P2^3;

sbit gC = P2^4;

unsigned char Seg_code[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void main(void)

{

while(1){

unsigned char i;

gA = 1;

gB = 0;

gC = 0;

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

{

DIG_PORT = Seg_code[i];

delay800ms();}}}

void delay800ms(void)

{

unsigned char a,b,c;

for(c=95;c>0;c--)

for(b=138;b>0;b--)

for(a=29;a>0;a--);

_nop_(); //if Keil,require use intrins.h

_nop_(); //if Keil,require use intrins.h

}

动态显示数码管

#include<reg51.h>

#include<intrins.h>

#define DIG_PORT P0

void Delay1ms(void);

void Delay800ms(void);

sbit gA = P2^2;

sbit gB = P2^3;

sbit gC = P2^4;

unsigned char Seg_code[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void main(void)

{

while(1)

{

unsigned char i;

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

{

switch (i)

{

case 0:

gA = 1; gB = 1; gC = 1;

break;

case 1:

gA = 0; gB = 1; gC = 1;

break;

case 2:

gA = 1; gB = 0; gC = 1;

break;

case 3:

gA = 0; gB = 0; gC = 1;

break;

case 4:

gA = 1; gB = 1; gC = 0;

break;

case 5:

gA = 0; gB = 1; gC = 0;

break;

case 6:

gA = 1; gB = 0; gC = 0;

break;

case 7:

gA = 0; gB = 0; gC = 0;

break;

default:

break;

}

DIG_PORT = Seg_code[i+1];

Delay800ms();

DIG_PORT = 0x00;} }}

void Delay800ms(void)

{

unsigned char a,b,c;

for(c=95;c>0;c--)

for(b=138;b>0;b--)

for(a=29;a>0;a--);

_nop_(); //if Keil,require use intrins.h

_nop_(); //if Keil,require use intrins.h

}

void Delay1ms(void)

{

unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=142;b>0;b--)

for(a=2;a>0;a--);}

蜂鸣器,一端接VCC,一端接ULN2003D驱动IC引脚P15,高电平时,VCC也是高电平,蜂鸣器不会响。当P15为低电平时,蜂鸣器发出声音。通过控制P15的高低变化频率,来实现蜂鸣器的工作频率。频率越高,声音越刺耳。

51的12T模式是12分频,时钟频率=12mHZ/12=1MHZ,所以cup执行一条指令的时间为1/12M=1us。

有源蜂鸣器(有电源),内部有一个可以震动的电源。外部直接给一个电压就可以。

gB = 1;delay1ms();

gB = 0;delay1ms();

点阵屏,pitch相邻的两个圆心的间距。单色点阵屏,显示广告和图形。显示器的像素就是屏幕上的最小元素,叫像素点。分辨率就是行向乘于纵向上的像素点。清晰度,人眼看屏幕的感觉,分辨率高,pitch小,那么清晰度会高。

点阵屏上面要显示图面,就会有些亮有些不亮,用的是字模。用8个字节来,显示一个页面(一帧图像)

74HC595移位器:给一个串行输入,等到并行输出。

对移位器进行操作点亮ILED灯

typedef unsigned char u8;

sbit Ai = P3^6;

sbit Bi = P3^5;

sbit Ci = P3^4;

void main(void)

{

HC595(0x7f);

while (1);

}

void HC595(u8 date)

{

u8 i=0, j=0;

Ai = 0; Bi = 0;

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

{

Ci = date>>7;

date <<= 1;

Ai = 1;

j++; j++;

Ai = 0;

}

Bi = 1;

j++; j++;

Bi = 0;

使用点阵显示字模:

#include<reg52.h>

#include<intrins.h>

typedef unsigned char u8;

typedef unsigned char u16;

#define MATRIX_PORT P0

sbit SCK = P3^6;

sbit RCK = P3^5;

sbit SER = P3^4;

u8 gLineCode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

u8 gK[] = {0x0,0x0,0x7E,0x38,0x66,0x0,0x0,0x0};

void Hc595SendByte(u8 dat);

void MatrixDisplay(u8 *zimo);

void main(void)

{

MatrixDisplay(gK); }

void MatrixDisplay(u8 *zimo)

{

u8 i = 0;

while (1)

{

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

{

MATRIX_PORT = gLineCode[i];

Hc595SendByte(zimo[i]);

Hc595SendByte(0x00); } }}

void Hc595SendByte(u8 dat)

{

u8 i = 0, j = 0;

SCK = 0;

RCK = 0;

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

{

SER = dat & (0x01);

dat >>= 1;

SCK = 1;

j++;

j++;

SCK = 0;

}

RCK = 1;

j++;

j++; }

独立按键,小键盘,抬起时单片机引脚是高电平状态,按下时按键接通GND引脚变成低电平。

查询方式:通过CPU读取按键引脚电平,来执行返回的值,然后控制对于的LED点亮。达到按下一个按键,点亮一个LED的效果。

就是等待一个异步事件,不知道什么时候发生。1,没隔一分钟查询一下,会很累。2,异步通知,等他通知我。就是中断方式,他有办法通知到我。中断和CPU也可以实现。有中断机制,让按键主动通知CPU有人按了按键。外部中断(按键),内部中断(串口和时钟)。分为主任务(一般时间的任务)和中断任务(打断后的任务)。

#include<reg51.h>

#include<intrins.h>

typedef unsigned char u8;

typedef unsigned int u16;

#define LED_PORT P2

sbit S15 = P3^2;

sbit S16 = P3^3;

void delay10ms(void);

void Int0(void);

void Int1(void);

void main(void)

{

Int0();

Int1();

while(1);}

void Int0(void)

{

IT0 = 1; // 设置为边沿触发模式(下降沿)

EX0 = 1; // 打开INT0的中断允许。

EA = 1;}

void Int1(void)

{

IT1 = 1; // 设置为边沿触发模式(下降沿)

EX1 = 1; // 打开INT1的中断允许。

EA = 1; // 打开总中断 }

void Int0s(void) interrupt 0

{ delay10ms();

if(S15 == 0)

{LED_PORT ^=(1<<0);}}

void Int1s(void) interrupt 2

{ delay10ms();

if(S16 == 0)

{LED_PORT ^=(1<<1);}}

void delay10ms(void) //误差 0us

{

unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=38;b>0;b--)

for(a=130;a>0;a--)}

使用独立矩阵按键1-16,按下按键时,数码管能显示对于的1-16.

#include<reg51.h>

#include<intrins.h>

typedef unsigned char u8;

typedef unsigned int u16;

#define KEY_PORT P1

#define DIG_PORT P0

sbit gA = P2^2;

sbit gB = P2^3;

sbit gC = P2^4;

unsigned char gDuanMa[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay10ms(void);

u8 KeyScan(void);

void KeyValueDisplay(u8 val);

void main(void)

{

u8 Key = 0;

u8 Key1 = 0;

while(1)

{

Key = KeyScan() ;

if(Key != 0)

{

Key1 = Key;

}

KeyValueDisplay(Key1);

}}

u8 KeyScan(void)

{u8 val = 0;

KEY_PORT = 0x0f;

if(KEY_PORT != 0x0f)

{delay10ms();

if(KEY_PORT != 0x0f)

{

switch(KEY_PORT)

{

case 0x07: val = 1; break;

case 0x0b: val = 2; break;

case 0x0d: val = 3; break;

case 0x0e: val = 4; break;

default: break;} }

KEY_PORT = 0xf0;

switch(KEY_PORT)

{

case 0x70: val += 0; break;

case 0xb0: val += 4; break;

case 0xd0: val += 8; break;

case 0xe0: val += 12; break;

default: break;} }

return val;}

void KeyValueDisplay(u8 val)

{gA=1; gB=1; gC=1;

DIG_PORT = gDuanMa[val/10] ;

delay10ms();

DIG_PORT = 0x00;

gA=0; gB=1; gC=1;

DIG_PORT = gDuanMa[val%10] ;

delay10ms();

DIG_PORT = 0x00;}

void delay10ms(void) //误差 0us

{unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=38;b>0;b--)

for(a=130;a>0;a--);}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值