600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > STC学习:扫描频率可变的电子钟

STC学习:扫描频率可变的电子钟

时间:2022-10-09 12:38:07

相关推荐

STC学习:扫描频率可变的电子钟

程序设计目标及程序运行效果说明

(1)用STC ISP默认设置,打开工程中的HEX并下载

(2)下载后观察现象为:8个数码管从00-00-00开始计数,最右边二极管被点亮(默认为最高扫描频率所以秒部分变化很快)

(3)辅助操作:长按下key1数码管扫描频率减半,从右起第二个二极管点亮、第一个灭,上方数码管显示的内容有轻微的闪动;再长按下key1,扫描频率继续减半,从右起第三个二极管点亮、第二个灭,数码管闪动明显;继续按下key1键,跳动现象更加明显…接下来观察单个LED数码管2次被点亮的时间间隔:当key1控制到左起第三个二极管点亮时,左起第5个LED数码管两次点亮的时间间隔为1;当key1控制到左起第二个二极管点亮时,点亮左起第5个LED数码管的间隔为2,从此以后可以看到一次只有一个LED数码管点亮;当key1控制到最左边二极管点亮时,点亮左起第5个LED数码管的间隔为4,此时扫描频率最低;再按key1,最右边二极管点亮,重新以最快速度扫描,如此重复操作。

程序相关电路及工作原理说明

1.LED数码管电路

2.按键电路

3.工作原理

本实验中同时用发光二极管和LED数码管,由于其功用P0口,所以采用分时复用的形式。

代码如下:

#include "STC15F2K60S2.h"#include "intrins.h"#define uint unsigned int#define uchar unsigned char#define i1 interrupt 1sbit ledSel=P2^3; // led or digital tubesbit key1=P3^2; //控制数码管扫描频率uchar baseSevenSegment[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段选unsigned char const line=0x40;//横杠的七段码char timeAddOneFlag=0; //标记为1,此时需要秒+1char key1ActionFlag=0; //值为1时表示按键操作需要执行unsigned int ledOnFlag=0; //led亮char tubeOnFlag=0; //数码管亮int ledValue=1; //led显示数值int myDisplay[8]={0};//数码管显示内容unsigned int timeCount=1; //时间计时器unsigned int currHour=0;unsigned int currMinute=0;unsigned int currSecond=0;unsigned int interruptCount=0;unsigned int keyDownTime=0;unsigned int scanTime=1; //扫描时间unsigned int currBit=0; //当前显示的位void Delay5us() //@11.0592MHz{unsigned char i;_nop_();i = 11;while(--i);}//设置ledSel,转为数码管显示void switchToTube(){ledSel=0;}//设置ledSel,转为led设置void switchToLed(){P0=0;ledSel=1;}/*** 改变其中一位的内容** @param bitNum 位数(第几位)(例如最左那位,则调用1)* @param value 改变后的数字,确保大于0小于10*/void change1Bit(int bitNum,int value){myDisplay[bitNum-1]=baseSevenSegment[value];}/*** 改变其中一位的内容(设置七段码)** @param bitNum 位数(第几位)(例如最左那位,则调用1)* @param sevenSegCode 目标七段码*/void change1Bit_seven(int bitNum,int sevenSegCode){myDisplay[bitNum-1]=sevenSegCode;}/*** 数码管设置为显示指定的长度** @param num 数字*/void changeAll(long num){int i;for(i=7;i>=0;--i){int foo=num%10;myDisplay[i]=baseSevenSegment[foo];num/=10;}}//led亮void displayLed(){if(ledOnFlag){switchToLed();P0=ledValue;}}//显示数码管void showTube(){if(tubeOnFlag){switchToTube();P0=0;P2=currBit;P0=myDisplay[currBit];Delay5us();}}//初始化定时器void timer0Initialize() //0.1毫秒@12MHz{AUXR|=0x80; //定时器时钟1T模式TMOD&=0xF0; //设置定时器模式TL0=0xAE; //设置定时器初值TH0=0xFB; //设置定时器初值TF0=0; //清除TF0标志TR0=1; //定时器0开始计时EA=1; //打开总中断ET0=1; //打开定时器0中断}//初始化void initialize(){P0M0=0xFF;P0M1=0x00;P2M0=0x0f; //设置P2.0-3为推挽模式P2M1=0x00;ledSel=0;timer0Initialize();changeAll(0);//第三位和第六位设置为'-'change1Bit_seven(3,line);change1Bit_seven(6,line);}//时间自增1svoid addTime(){++currSecond;if(currSecond==60){++currMinute;currSecond=0;if(currMinute==60){++currHour;currMinute=0;if(currHour==24)currHour=0;change1Bit(2,currHour%10);change1Bit(1,currHour/10);}change1Bit(5,currMinute%10);change1Bit(4,currMinute/10);}change1Bit(8,currSecond%10);change1Bit(7,currSecond/10);}//按下key1要做的事void key1Action(){if(key1ActionFlag){if(ledValue==0x80)ledValue=0x01;elseledValue<<=1;if(ledValue==1)scanTime=1;else if(ledValue==2)scanTime=50;else if(ledValue==4)scanTime=100;else if(ledValue==8)scanTime=200;else if(ledValue==16)scanTime=500;else if(ledValue==32)scanTime=1000;else if(ledValue==64)scanTime=2000;else if(ledValue==128)scanTime=5000;key1ActionFlag=0;}}//收到中断的信号(是时候自增时间了)void timeSignalHandler(){if(timeAddOneFlag){addTime();timeAddOneFlag=0;}}//每0.1ms进入一次定时器中断void interruptFunction()i1{static const int KEY_TIME_THRESHOLD=500;interruptCount=(interruptCount+1)%20000;//led显示的频率应该低些才有好的显示效果if(interruptCount%12>10){ledOnFlag=1;tubeOnFlag=0;}else{tubeOnFlag=1;ledOnFlag=0;}//数码管的扫描if(interruptCount%scanTime==0)currBit=(currBit+1)%8;//读秒if(interruptCount%10000==0)timeAddOneFlag=1;//按键功能设置if(key1==0){if(keyDownTime<KEY_TIME_THRESHOLD)++keyDownTime;}else{if(keyDownTime>=KEY_TIME_THRESHOLD)key1ActionFlag=1;keyDownTime=0;}}int main(){initialize();while(1){timeSignalHandler();displayLed();showTube();key1Action();}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。