登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] 单片机程序流水灯到按键()

[复制链接]
发表于 2018-2-20 13:41:40 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机
学习安排: 结合社团的一些资源,重新写一边单片机程序
开始时间: 2018-02-20
结束时间:
电器开发部是真的赞,可以用delay函数精确延时到微妙级别
本来以为,学了结构,应该都可以看懂社团的程序了,
结果第一个流水灯的程序就遇到两个没见过的

第一个,# pragma optimize
这个也是编译预处理指令,不过我没见过,先放着,以后学
第二个,register 关键字
register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。
早期的C编译程序不会把变量保存在寄存器中,除非你命令它这样做,这时register修饰符是C语言的一种很有价值的补充。
然而,随着编译程序设计技术的进步,在决定哪些变量应该被存到寄存器中时,
现在的C编译环境能比程序员做出更好的决定。
实际上,许多编译程序都会忽略register修饰符,因为尽管它完全合法,但它仅仅是暗示而不是命令。
#include<stc12c5a60s2.h>
#include"delay.h"
#include"CTypes.h"

void main()
{
        uint8 cnt;

        P11 = 0;
        P20 = 0;
        P21 = 1;
        P22 = 1;
        while(1){
                for(cnt=0;cnt<8;cnt++){
                        P0 = ~(0x01<<cnt);
                        delay_ms(500);
                }
        }
}

有了上面多了的两个头文件和一个delay.c文件,主程序写的如此简洁

下面是高位不显示的数码管动态显示程序//秒表
由主程序,timer程序,以及timer.h头文件构成
主程序
#include<stc12c5a60s2.h>
#include"timer.h"

char ledchar[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,};
char ledn[6]={0xff,0xff,0xff,0xff,0xff,0xff};
int cnt=0;
long sec=0;
char num=0;
char i;

void main(){
        long n;
        P11 = 0;
        Timer0Init();//定时器与中断调用

        while(1){
                if(cnt>1000){
                        cnt=0;
                        sec++;
                        n = sec;

                        for(i=0;i<6;i++){
                                ledn = ledchar[n%10];
                                n/=10;
                        }
                }
        }
}

timer程序
#include"timer.h"

extern char ledn[6];
extern int cnt;
extern long sec;
extern char num;
void ledSwitch(void);

void Timer0Init(void)
{
        AUXR |= 0x80;
        TMOD &= 0xF0;
        TMOD |= 0x01;
        TH0=0x83;
        TL0=0x00;
        TR0=1;
        EA=1;
        ET0=1;
}
void interruptT0() interrupt 1
{
        TH0=0x83;
        TL0=0x00;
        cnt++;
        P0=0xff;
        ledSwitch();
}
void ledSwitch(void)
{
                switch(num){
case 0: P20 = 1; P21 = 0; P22 = 1; P0 = ledn[0]; num++;break;
case 1: num++; if(sec<10)break;
                P20 = 0; P21 = 0; P22 = 1; P0 = ledn[1]; break;
case 2: num++; if(sec<100)break;
                P20 = 1; P21 = 1; P22 = 0; P0 = ledn[2]; break;
case 3: num++; if(sec<1000)break;
                P20 = 0; P21 = 1; P22 = 0; P0 = ledn[3]; break;
case 4: num++; if(sec<10000)break;
                P20 = 1; P21 = 0; P22 = 0; P0 = ledn[4];break;
case 5: num=0; if(sec<100000)break;
                P20 = 0; P21 = 0; P22 = 0; P0 = ledn[5];break;
default :break;
        }
}

头文件
#ifndef __TIMER_H_
#define __TIMER_H_

#include <STC12C5A60S2.H>
//#include "CTypes.h"


void Timer0Init(void);

#endif

中断里面的程序尽量写成函数
首先可读性强了,其次就是我原本是把switch直接写在中断里面的,
结果编译器给了警告说我的函数没有调用,虽然不知道为什么,不过尽量的写成函数吧

还有一点需要注意,
为了避免每个程序的头文件正确,一个子程序就对应一个头文件

先发这么多,按键的还没写好
好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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