当前位置: 首页 > news >正文

做网站主色调选择智能营销系统

做网站主色调选择,智能营销系统,上海app网站建设,企业建设网站找网站公司吗基于定时器的倒计时程序 题目如下所示: 实现过程中遇到的一些问题 01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5 首先这个问题不是在main.c中关于数码管显示部分的逻辑错误,就是发生在数码管的底层错误。 检查了逻辑部分&#xff…

基于定时器的倒计时程序

题目如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现过程中遇到的一些问题

01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5

首先这个问题不是在main.c中关于数码管显示部分的逻辑错误,就是发生在数码管的底层错误。
检查了逻辑部分,没有发现问题
转而查找底层上面的错误。
底层的Seg.c是这样写的:

#include <Seg.h>unsigned char code Seg_Dula[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f ,0x00};
unsigned char code Seg_Wela[] = {0xfe ,0xfd ,0xfb,0xf7,0xef,0xdf};void Seg_Disp(unsigned char wela,dala)
{//消影P0 = 0x00;P2_6 = 1;P2_6 = 0;P0 = Seg_Wela[wela];P2_7 = 1;P2_7 = 0;P0 = Seg_Dula[wela];//问题出现在这里!P2_6 = 1;P2_6 = 0;
}

果然被我发现了,段选数组的索引写错了,写成了wela,这样无论如何,数码管的每一位都会按照传入的wela来显示(wela在main函数中即Seg_Pos,这个变量在0-5范围内循环)

	if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);

02 按下设置按键KEY4设置好倒计时参数后,该参数应该在什么时机传输给Time_Count倒计时变量用于倒计时呢?

(1)设置完就对Time_Count赋值

//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];//设置完就对Time_Count赋值!!!!!!}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}

如果这样的话,会导致切换回显示模式后已经倒计时了一段时间了,不是从设置的值开始倒计时的。想要切换回显示模式从设置的值开始倒计时,需要在切换回显示模式后,再对Time_Count赋值。

(2)在切换成显示模式后对Time_Count赋值

//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;if(Seg_Mode == 0)Time_Count = Set_Dat[Set_Dat_Index]  ;//切换到显示界面再对Time_Count赋值!!!!!!break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;//Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}

03 倒计时到0之后为什么数码管又变成55再倒计时呢?

这是因为Time_Count–,没有对其作任何限制的情况下,Time_Count减为0之后会再从255开始减递减(Time_Count是一个unsigned char类型的变量,该变量8bit,变量可以表示的范围为0-255)。而我们只让数码管显示到十位数,因此我们看到的就是数码管从55开始倒计时。

对中断服务函数代码作如下修改:

void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;//修改代码!!!!!!!!!!!!!!!!!!}}
}

修改代码之后数码管会停在00的位置。

在这里插入图片描述

至此,所有代码如下所示(不包含设置参数以1s为周期闪烁):

//头文件声明
#include <REGX52.H>
#include <Key.h>
#include <Seg.h>//动态数码管会用到数码管的底层?//变量声明
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量unsigned int Seg_Slow_Down;//数码管减速专用变量 500mschar:0-255.char不够用//动态数码管
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组unsigned char Seg_Mode;//数码管显示页面 0-显示 1-设置,默认为0
unsigned int Timer_1000ms;//1000ms标志位
unsigned char Time_Count = 30;//倒计时变量//按键
bit System_Flag;//0-暂停 1-开始倒计时unsigned char Set_Dat[3] = {15,30,60};//设置参数储存数组
unsigned char Set_Dat_Index = 1;//LED点亮标志位
bit Timer0Flag;//0-倒计时没有到0;1-倒计时到0//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;//if(Seg_Mode == 0)//Time_Count = Set_Dat[Set_Dat_Index];break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}/* 其他显示函数 */
//Led_Proc()
void Led_Proc()
{if(Time_Count == 0){P1 = 0x00;//LED全亮P2_3 = 0;//蜂鸣器使能}else{P1 = 0xff;//LED全灭P2_3 = 1;//蜂鸣器关闭}
}//Timer0Init()定时器0的中断初始化函数
void Timer0Init(void)		//1毫秒@12.000MHz
{//AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时//复制过来之后不要忘记加上两句话ET0 = 1;EA = 1;
}//Server定时器0的中断服务函数
//a++是先进行取值,后进行自增。++a是先进行自增,后进行取值
void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;}}
}
//主函数
void main()
{Timer0Init();//上电时立即调用定时器初始化函数while(1){//三大处理单元:按键、数码管、LEDKey_Proc();Seg_Proc();Led_Proc();}
}

04 如何实现设置参数以1s为周期闪烁?

(1)在变量声明区新增两个变量:
注:以1s为周期闪烁,即500ms亮,500ms灭。

unsigned int Timer_500ms;//500ms标志位
bit Seg_Flag;//数码管标志位,即控制数码管的亮灭

(2)在中断服务函数中

	if(++Timer_500ms == 500){Timer_500ms = 0;Seg_Flag ^= 1;//因为默认值为0,只需要对其取反即可,不需要赋值,可以用^=1来对一个变量取反}

(3)在数码管显示函数中

//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{
//		Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;
//		Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;
//修改如下:if(Seg_Flag == 1){Seg_Buf[4] = 10;Seg_Buf[5] = 10;}else{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}
}

05 最终版代码

//头文件声明
#include <REGX52.H>
#include <Key.h>
#include <Seg.h>//动态数码管会用到数码管的底层?//变量声明
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量unsigned int Seg_Slow_Down;//数码管减速专用变量 500mschar:0-255.char不够用//动态数码管
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组unsigned char Seg_Mode;//数码管显示页面 0-显示 1-设置,默认为0
unsigned int Timer_1000ms;//1000ms标志位
unsigned char Time_Count = 30;//倒计时变量//按键
bit System_Flag;//0-暂停 1-开始倒计时unsigned char Set_Dat[3] = {15,30,60};//设置参数储存数组
unsigned char Set_Dat_Index = 1;//设置参数闪烁
unsigned int Timer_500ms;//500ms标志位
bit Seg_Flag;//数码管标志位//LED点亮标志位
bit Timer0Flag;//0-倒计时没有到0;1-倒计时到0//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;//if(Seg_Mode == 0)//Time_Count = Set_Dat[Set_Dat_Index];break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{
//		Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;
//		Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;if(Seg_Flag == 1){Seg_Buf[4] = 10;Seg_Buf[5] = 10;}else{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}
}/* 其他显示函数 */
//Led_Proc()
void Led_Proc()
{if(Time_Count == 0){P1 = 0x00;//LED全亮P2_3 = 0;//蜂鸣器使能}else{P1 = 0xff;//LED全灭P2_3 = 1;//蜂鸣器关闭}
}//Timer0Init()定时器0的中断初始化函数
void Timer0Init(void)		//1毫秒@12.000MHz
{//AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时//复制过来之后不要忘记加上两句话ET0 = 1;EA = 1;
}//Server定时器0的中断服务函数
//a++是先进行取值,后进行自增。++a是先进行自增,后进行取值
void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;}}if(++Timer_500ms == 500){Timer_500ms = 0;Seg_Flag ^= 1;//因为默认值为0,只需要对其取反即可,不需要赋值,可以用^=1来对一个变量取反}
}
//主函数
void main()
{Timer0Init();//上电时立即调用定时器初始化函数while(1){//三大处理单元:按键、数码管、LEDKey_Proc();Seg_Proc();Led_Proc();}
}

参考视频:https://www.bilibili.com/video/BV1TR4y1k7iz?p=6&vd_source=5af7b905774c79f1754cd4ab83975115

http://www.fp688.cn/news/158276.html

相关文章:

  • 唐山房产网站建设福州今日头条新闻
  • 做网站怎么学网站接广告平台
  • 上海品牌网站制作seo sem什么意思
  • 新乡做网站的seo网站优化流程
  • 广州微网站建设哪家好有没有好用的网站推荐
  • 石家庄门户网站制作seo快排
  • 珠海网站制作产品如何推广
  • 北京移动端网站优化推广广告
  • 网站建设网站制作哪个好查权重的软件
  • 如何做做网站新闻头条今日新闻60条
  • wordpress ks主题论坛如何做seo
  • 在常州 做兼职上什么网站海外短视频软件
  • 武汉装饰公司前十名是哪几家seo零基础入门教程
  • 武汉网站seo诊断抖音关键词推广
  • 佛山市南海区水利投资建设有限公司网站中央新闻频道直播今天
  • 东方购物商城seo排名优化培训网站
  • 石家庄网站建站推广优化网站排名
  • 成都网站建设租书网电脑培训学校网站
  • 上海最好的网站设计公司nba体育新闻
  • 网站设计banner尺寸化妆培训
  • 发行商城小程序搜索优化是什么意思
  • 淄博网站建设报价网站营销策划公司
  • 南充网站建设公司软文推广新闻发布
  • wordpress破解主题分享下载天津seo博客
  • 专业网网站建设全网关键词指数查询
  • 怎么用ppt做网站设计百度搜索词排名
  • 网站是如何做的好湖南关键词优化品牌价格
  • 学校网站建设制作方案网站关键词怎样优化
  • 西安做网站谷歌排名优化入门教程
  • 网站建设价格费用安徽搜索引擎优化