一天:51单片机从入门到一个动态数码管显示数字控制

最近进的公司是一个做路由器的。。很多嵌入式工程师。有个项目( 智能空调控制)是跟嵌入式工程师对接,我做APP+PHP。。他做服务器。我们用MQTT(由于emqtt是用erlang写的,所以我也学了点erlang,后期有时间分享一下,这个语言很好,很强大。特别抽象)。这个项目激发了我对嵌入式的兴趣,于是乎。开始从51单片机搞起了。。所以就有了这篇文章。。。今天搞得东西挺多。我最近都是笔记形式,不想以前写的那么详细。。。因为学的东西太多,白天在公司搞项目,没时间写太具体。。。

今天学了什么呢?

>keil安装和使用,下载程序到开发板

>点亮第一个led灯,这个很简单。给单片机的p0口 的最低位,输入一个高电平,就可以点亮一个动态数码管【当然下载程序之后,要连线】

#include <reg52.h>
sbit led1 = P0^0;
void main(){
    led1 = 1;
}

>在点亮led之后,再加点程序控制,让led闪烁。。。闪烁的思路也简单: 一下高电平。然后延时,再低电平。。再延时。。就OK了。。延时多少秒合适? 可以通过keil软件仿真算出。仿真的时候,记得把晶振调整跟开发板一样。我的开发板是12M

#include <reg52.h>

sbit led = P0^0;
typedef unsigned char u8;
typedef unsigned int u16;

void delay( u16 i ){
    while( i-- );
}

void main (){
    while( 1 ) {
        led = 1;
        //delay( 5000 ); //  通过软件仿真得出 执行5000次循环 需要45ms
        delay( 50000 );
        led = 0;
        //delay( 5000 );
        delay( 50000 );
    }
}

>点亮led之后,再来一个流水灯,思路就是循环设置一个数码管的某一段 为 高电平。其他段为低电平。。然后,延时循环。就可以达到流水灯的效果

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

void delay( u16 i ){
    while( i-- );
}

void main (){
    u8 i = 0;
    //led = 0x01; //p0的 最低位为高电平  0x01( p0端口的第8位为1 即,高电平 )

    led = 0x80;
    while( 1 ) {
        /*  方法一: 不用库函数
        for( i = 0; i < 8; i++ ){
            led = ( 0x01 << i ); //循环移位, 把p0端口从p0.0--->p0.7循环设置为高电平
            delay( 50000 );
        }
        */

        //方法二,使用库函数
        /*
        for( i = 0 ; i < 8; i++ ){
            led = _crol_( led, 1 ); //每次向左移动1位
            delay( 50000 );
        }
        */

        for( i = 0 ; i < 8; i++ ){
            led = _cror_( led, 1 ); //每次向右移动1位
            delay( 50000 );
        }

    }
}

>再然后,控制蜂鸣器。。我的开发板是无源蜂鸣器靠频率驱动。把频率换算成周期: F = 1 / T,周期通过延时函数实现。 然后改变高低电平的占空比,可以实现蜂鸣器的声音大小。频率改变的是蜂鸣器

的音色。

#include <reg52.h>

#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

sbit beep = P1^5; //用p1口的第5位

void delay( u16 i ){
    while( i-- );
}

void main (){
    //无源蜂鸣器靠频率驱动, 假设10k能驱动, 那么T = 1 / 10k,  T = 0.1 毫秒
     //之前的测试是循环50000次 = 450 ms(毫秒 ) 那0.1 ms = 12.8次

    while( 1 ) {
        beep = ~beep; //~:取反操作
        delay( 50 );

        //改变高低电平的占空比(比例) 控制蜂鸣器声音大小
        beep = 1;
        delay( 50 );
        beep = 0;
        delay( 5 );
    }
}

>在然后,控制一个继电器。这个很简单。跟点亮led灯同样的思路

#include <reg52.h>

#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

//继电器控制
sbit relay = P1^4; //用p1口的第4位

void main (){
    relay = 0; //给一个低电平 继电器开启
    while( 1 ) {

    }
}

>再然后,在静态数码管上做了个循环显示0~F的程序,思路就是 1~F 怎么在静态数码管上表示? 因为我的开发板静态数码管是共阳数码管。要用低电平才能点亮对应的段。然后把每一位数字(0~F)对应的

二进制算出对应的十六进制,就是我程序中定义的那个数组表示的就是( 0 ~ F).

#include <reg52.h>

#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

void delay( u16 i ){
    while( i-- );
}

void main (){
    u8 character [16] = { 0xC0, 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92,
                         0x82 , 0xF8 , 0x80  , 0x90 , 0x88 , 0x83,
                         0xC6 , 0xA1 , 0x86 , 0x8E};
    int i = 0;
    while( 1 ) {
        for( i = 0; i < 16; i++ ){
            led = character[i];
            delay( 50000 );
            delay( 50000 );
        }
    }
}

>在然后,在8个动态数码上显示1~8,用到38译码器模块的输入,输出,我的第一版(傻瓜版程序)

#include <reg52.h>

sbit A1 = P2^2;
sbit B1 = P2^3;
sbit C1 = P2^4;
#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

void delay( u16 i ){
    while( i-- );
}

void main (){
    while( 1 ){
        A1 = 0x0;
        B1 = 0x0;
        C1 = 0x0;
        //0x06 , 0x5b , 0x4f , 0x66 , 0x6d, 0x7d , 0x07 , 0x7f
        led = 0x06;

        delay( 100 );

        A1 = 0x1;
        B1 = 0x0;
        C1 = 0x0;
        led = 0x5b;
        delay( 100 );

        A1 = 0x0;
        B1 = 0x1;
        C1 = 0x0;
        led = 0x4f;
        delay( 100 );

        A1 = 0x1;
        B1 = 0x1;
        C1 = 0x0;
        led = 0x66;
        delay( 100 );

        A1 = 0x0;
        B1 = 0x0;
        C1 = 0x1;
        led = 0x6d;
        delay( 100 );

        A1 = 0x1;
        B1 = 0x0;
        C1 = 0x1;
        led = 0x7d;
        delay( 100 );

        A1 = 0x0;
        B1 = 0x1;
        C1 = 0x1;
        led = 0x07;
        delay( 100 );

        A1 = 0x1;
        B1 = 0x1;
        C1 = 0x1;
        led = 0x7f;
        delay( 100 );
    }
}

然后经过封装改造的程序:

#include <reg52.h>

sbit A1 = P2^2;
sbit B1 = P2^3;
sbit C1 = P2^4;
#define led P0
typedef unsigned char u8;
typedef unsigned int u16;

void delay( u16 i ){
    while( i-- );
}

u8 digital[16] = { 0x3f  , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d,
                        0x7d , 0x07 , 0x7f  , 0x6f , 0x77 , 0x7c,
                        0x39 , 0x5e , 0x79 , 0x71 };

void showDigital(){
    int i = 0;
    for ( i = 0; i < 8; i++ ) {
        switch( i ) {
            case 0:  //位选第一个数码管
                A1 = 0x0; B1 = 0x0; C1 = 0x0;
                break;
            case 1:
                A1 = 0x1; B1 = 0x0; C1 = 0x0;
                break;
            case 2:
                A1 = 0x0; B1 = 0x1; C1 = 0x0;
                break;
            case 3:
                A1 = 0x1; B1 = 0x1; C1 = 0x0;
                break;
            case 4:
                A1 = 0x0; B1 = 0x0; C1 = 0x1;
                break;
            case 5:
                A1 = 0x1; B1 = 0x0; C1 = 0x1;
                break;
            case 6:
                A1 = 0x0; B1 = 0x1; C1 = 0x1;
                break;
            case 7:
                A1 = 0x1; B1 = 0x1; C1 = 0x1;
                break;
        }
        led = digital[ i ];
        delay( 100 );
    }
}

void main (){
    while( 1 ){
        showDigital();
    }
}

原文地址:https://www.cnblogs.com/ghostwu/p/9130177.html

时间: 2024-10-24 09:04:24

一天:51单片机从入门到一个动态数码管显示数字控制的相关文章

51单片机编程:做一个简易的流水灯

#include <reg52.h> #define uchar unsigned char #define uint unsigned int uint table[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; void delay(void) { uint a = 50000; while(a--); } void main() { int i = 0; while(1) { for(i = 0; i < 8; i++)

单片机入门-矩阵键盘控制数码管显示

任务简述:通过按下4X4矩阵键盘实现数码管对应显示数字 实现方式:通过行列分接法,可以节省使用单片机的I/O口,扫描矩阵键盘是否有按下,判断P2端口得到的值. protues 硬件系统 单片机晶振复位电路: 锁存器.上拉电阻: 4x4矩阵键盘: 代码实现: void key44scan(void)//键盘扫描函数 { uint t; P2=0xfe; t=P2; t=t&0xf0; if(t!=0xf0) { delay(); t=P2; switch(t) { case 0xee:keynum

51单片机 数码管的显示与译码器

共阳极数组0~9:display[]={0xC0,0xF9,0xA4,0xB0,0x91,0xA2,0x82,0xF8,0x80,0x90} 共阳极数组A~F:display[]={0x88,0x83,0xA6,0xC1,0x86,0x8E} 共阴极数组0~9:display[]={0x3F,0x06,0x5B,0x4F,0x6E,0x6D,0x7D,0x07,0x7F,0x6F} 共阴极数组A~F:display[]={0x77,0x7C,0x59,0x3E,0x79,0x71} 共阴.两组四

[学习笔记]15个QA让你快速入门51单片机开发

一.C语言相关... 1 Q1:sbit与sfr代表是什么?有什么作用?... 1 Q2:#define OSC_FREQ  22118400L这句宏命令里的“L”是什么意思?... 1 Q3:我粘贴了别人的代码,怎么发现没有unit这个类型?... 1 Q4:为什么好多变量都是char类型?它不是字符类型吗?怎么可以用来计数?    1 Q4.1:51单片机中的char,int,long,float,double各占多少个字节,取值范围多大?    1 Q5:unsigned char dat

[51单片机] nRF24L01 无线模块 串口法命令 通过无线控制另一个的灯

>_<!概述: 这是在上一个的基础上通过按键发送4种不同命令来控制接收端的LED灯亮的改进版(上一个:http://www.cnblogs.com/zjutlitao/p/3840013.html),这里俺把按键发命令给去掉,然后加入一个串口通信的功能,PC通过串口给发送端发送命令,然后发送端通过无线将命令发给接收端来实现控制,这里接收端和上一个例程中的一样,只是在发送端的代码里去除了按键控制,变成了串口控制. >_<!发送端电路: >_<!接收电路图: >_&l

51单片机入门基础教程,视频、课件、源码免费下载

今天也是分享资料,不过是很大量的学习资料,足够您国庆七天在家闭关学习了,4G的51单机片开发学习视频和资料,包括每一节的视频.课件和源码!内容很大,想要更多的单机片学习.交流和实战的机会,可以上闯客网论坛,和同行并肩同行,一起学习 图一 下面就给大家分享单片机的基础知识PCB的种类1. 单面板(只在一个面走线)2. 双面板(在两个面都走线)3. 多层板(4.6.8.10......)(出两个面外还有内层)4. 柔性PCB(触摸屏等的连接) 图二 PCB的制作步骤(工业企业环境下的PCB制作步骤)

51单片机入门1--与C语言的交接

我们即将进入51单片机的编程学习,咱们今天就来讲解一下单片机中的C语言(你可以称作C51) 在说编程之前,要先说一些别的东西: 二进制,八进制,十六进制 二进制中只有数字0和1,在二进制中1+1为10,我们常说十进制逢十进一,那二进制就是逢二进一,那为什么我会在这里说二进制呢,因为我们的51单片机的io口是可以接受发送低电平和高电平的,意思就是输入输出的口只有0和1两个状态,所以如果我们理解了二进制,那么对于单片机的输入和输出就会十分明了了 八进制,学过C语言,咱们都知道,在C语言中其实是不能直

51单片机入门(三)

数码管显示,定时器中断:键盘检测: 1.数码管:分共阳极和共阴极数码管.我的实验板是共阴极,多位数码管的公共端叫做"位选线",连接在一起的段线叫做"段选线".位选是独立控制的,而段选是连接在一起的.段选数据由P0口发送,位选由P2口的2.3.4控制.(消影用P0=0x00) 2.中断:为使单片机具有对外部或内部随机事件发生的时间实时处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或内部时间的能力.51单片机内部共有5个中断源,外部中断0.1:定时器中断0

[51单片机] 以PWM控制直流电机为例建一个简单的51工程框架

目录 1)功能概述 2)引脚连接 3)框架介绍 4)模块说明 5)复用规则 6)工程链接 1)功能概述 名称:独立按键控制直流电机调速 内容:对应的电机接口需用杜邦线连接到uln2003电机控制端; 使用5V-12V 小功率电机皆可 2个按键分别加速和减速; 采用8个8段数码管的后两位显示0~10级速度; 2)引脚连接 P3连接按键:P0连接8x八段数码管,P22段码锁存,P23位码锁存:P1.1连接ULN2003的一个输入:直流电机端连接ULN2003对应的输出,另一端连接VCC. 3)框架介