找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1667|回复: 9
打印 上一主题 下一主题
收起左侧

帮忙看看单片机程序按键k3该怎么配置?

[复制链接]
跳转到指定楼层
楼主
ID:1045601 发表于 2023-8-7 21:52 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1..怎么用按键k3关开数码管。我思路是关定时器中断。可效果不理想,必须加p3= 0x00,数码管才没有残影,应该是刷新太块,按键关不断。有没有好办法关开数码管。
2..k3关闭数码管显示时程序所有停止,开数码管显示时程序从头开始运行,程序该怎么写?
3.程序有些乱,我新手写程序不久,能看懂的老师帮忙看看应该怎么解决,谢谢

单片机源程序如下:
#include <STC15F2K60S2.H>
#define uint unsigned int
sbit ADDR0 = P1^0; //位码
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit k1 = P5^4; //时间切换键
sbit k2 = P1^6; //启动按键
sbit k3 = P5^5;    //开关
sbit fm = P1^7;    //蜂鸣器
sbit mos= P1^4;    //mos管
unsigned char knum,kn;   
bit k1f=0;
bit k2f=0;
unsigned char code LedChar[] = {0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa};
unsigned char LedBuff[4] = {0,0,0,0};
unsigned char i = 0;  // 动态扫描的索引
unsigned char sec = 10,ms=0;
unsigned char sec1 = 30,ms1=0;
unsigned char sec2 = 0,ms2=03;
unsigned char sec3 = 0,ms3=05;
unsigned char sec4 = 0,ms4=10;
unsigned int cnt=0;
void Timer2_Init();
void Delay1ms(unsigned char c)   //误差 0us
{
    unsigned char a,b;
    for(;c>0;c--)
       { for(b=199;b>0;b--)
            for(a=1;a>0;a--);
     }
}
void keyscan()
{     
if(k1==0) {Delay1ms(10);if(k1f==0)
{     k1f=1;  knum++;
if(knum==4)  knum=0; } }
      else k1f=0;   
if(k2==0) {Delay1ms(10);if(k2==0)
{ TR0=!TR0;mos=!mos;  while(k2==0);} }
if(k3==0) {Delay1ms(10);if(k2f==0)
{     k2f=1; kn++;
if(kn==2)  kn=0; } }
      else k2f=0;}      
void main()
{
P3M0 = 0xff;
P3M1 = 0x00;
Timer2_Init();   
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x67;
ET0 = 1;
while(1)
{
if(kn==0){IE2&=~0x04;EA=0;P3=0x00;}
if(kn==1){IE2|=0x04;EA=1;}
  keyscan();
if(knum==0)
  { LedBuff[0] = LedChar[ms/10];
   LedBuff[1] = LedChar[ms  % 10];
   LedBuff[2] = LedChar[sec % 10];
   LedBuff[3] = LedChar[sec /10]; }   
if(knum==1)
  { LedBuff[0] = LedChar[ms1/10];
   LedBuff[1] = LedChar[ms1  % 10];
   LedBuff[2] = LedChar[sec1 % 10];
   LedBuff[3] = LedChar[sec1 /10];     }  
if(knum==2)
  { LedBuff[0] = LedChar[ms2/10];
   LedBuff[1] = LedChar[ms2  % 10];
   LedBuff[2] = LedChar[sec2 % 10];
   LedBuff[3] = LedChar[sec2 /10];      }
if(knum==3)
  { LedBuff[0] = LedChar[ms3/10];
   LedBuff[1] = LedChar[ms3  % 10];
   LedBuff[2] = LedChar[sec3 % 10];
   LedBuff[3] = LedChar[sec3 /10];}
}
void InterruptTimer0() interrupt 1
{
TH0 = 0xFC;
TL0 = 0x67;
cnt++;
    if(cnt>=1000)
{ cnt=0;
switch(knum)
{case 0: sec--; if(sec==0) {sec = 10, ms=0; TR0=0;mos=1;fm=0;} break;
  case 1: sec1--;if(sec1==0){sec1 = 30,ms1=0;TR0=0;mos=1;fm=0;} break;
  case 2: if(ms2>0||sec2>0)   {if(ms2 > 0) {sec2--;if(sec2 >59){sec2 = 59;ms2--; }}else if(sec2 > 0)  { sec2--; }}
          if(sec2==0&&ms2==0){sec2=0;ms2=03;TR0=0;mos=1;fm=0;}break;
  case 3: if(ms3>0||sec3>0)   {if(ms3 > 0) {sec3--;if(sec3 >59){sec3 = 59;ms3--; }}else if(sec3 > 0)  { sec3--; }}
          if(sec3==0&&ms3==0){sec3=0;ms3=05;TR0=0;mos=1;fm=0;}break;
  default: break;
}
} }
void Timer2_Isr(void) interrupt 12
{
    T2L = 0xFB;                //设置定时初始值
    T2H = 0xFF;   
     P3 = 0x00;
switch (i)
{
  case 0:ADDR3=1; ADDR2 = 1; ADDR1 = 1; ADDR0 = 0; P3= LedBuff[0];      i++; break;
  case 1:ADDR3=1; ADDR2 = 1; ADDR1 = 0; ADDR0 = 1; P3= LedBuff[1]+0x04; i++; break;
  case 2:ADDR3=1; ADDR2 = 0; ADDR1 = 1; ADDR0 = 1; P3= LedBuff[2];      i++; break;
  case 3:ADDR3=0; ADDR2 = 1; ADDR1 = 1; ADDR0 = 1; P3= LedBuff[3];      i=0; break;
}
}
void Timer2_Init(void)        //5微秒@12.000MHz
{
    AUXR &= 0xFB;            //定时器时钟12T模式
    T2L = 0xFB;                //设置定时初始值
    T2H = 0xFF;                //设置定时初始值
    AUXR|=0x10;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:277550 发表于 2023-8-8 10:12 | 只看该作者
不想显示,关停定时器2、且设置P3  = 0x00;
回复

使用道具 举报

板凳
ID:712097 发表于 2023-8-8 10:12 | 只看该作者
1. 只关定时器中断不行,要不关段码(P3=0x00应该就是关段码),要不关位码。
2. k3关闭数码管显示时程序所有停止,- 关显示后,做一个死循环while(1),只保留外部中断,开数码管显示时,外部中断唤醒,中断函数中做一个软件复位,这样程序就从头开始运行了。
回复

使用道具 举报

地板
ID:213173 发表于 2023-8-8 19:18 | 只看该作者
楼主首先要说清楚程序要实现什么功能,再谈遇到什么具体问题。用5us中断扫描数码管肯定是错误的,你这个段码写的怪怪的,不清楚你的数码管硬件连接关系。STC15系列的定时器2是自动重装,无需在中断中对T2L、T2H赋值。
回复

使用道具 举报

5#
ID:1045601 发表于 2023-8-10 12:51 来自手机 | 只看该作者
devcang 发表于 2023-8-8 10:12
不想显示,关停定时器2、且设置P3  = 0x00;

谢谢建议
回复

使用道具 举报

6#
ID:1045601 发表于 2023-8-10 12:53 来自手机 | 只看该作者
chxelc 发表于 2023-8-8 10:12
1. 只关定时器中断不行,要不关段码(P3=0x00应该就是关段码),要不关位码。
2. k3关闭数码管显示时程序 ...

谢谢建议
回复

使用道具 举报

7#
ID:1045601 发表于 2023-8-10 13:08 来自手机 | 只看该作者
wulin 发表于 2023-8-8 19:18
楼主首先要说清楚程序要实现什么功能,再谈遇到什么具体问题。用5us中断扫描数码管肯定是错误的,你这个段 ...

代码也不是很乱就是不够简洁,数码管与硬件关系看段码位码就明白了啊。
谢谢你的建议
回复

使用道具 举报

8#
ID:1064915 发表于 2023-8-10 14:21 | 只看该作者
硬件原理图,一块贴出来
回复

使用道具 举报

9#
ID:213173 发表于 2023-8-10 19:55 | 只看该作者
702724152 发表于 2023-8-10 13:08
代码也不是很乱就是不够简洁,数码管与硬件关系看段码位码就明白了啊。
谢谢你的建议

用一个定时器就可以搞定
  1. #include <STC15F2K60S2.H>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit ADDR0 = P1^0; //位码
  5. sbit ADDR1 = P1^1;
  6. sbit ADDR2 = P1^2;
  7. sbit ADDR3 = P1^3;
  8. sbit k1 = P5^4; //时间切换键
  9. sbit k2 = P1^6; //启动按键
  10. sbit k3 = P5^5;    //开关
  11. sbit fm = P1^7;    //蜂鸣器
  12. sbit mos= P1^4;    //mos管
  13. //共阴数码管段码P3---5-7-3-1-0-6-4-2
  14. uchar code LedChar[] = {0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa};
  15. uchar LedBuff[4] = {0,0,0,0};
  16. char sec=10,ms=0;
  17. uchar cnt=0;//中断计数
  18. uchar knum=0;//切换键值
  19. bit flag_ms=0;//1ms中断标志
  20. bit start=0;//开始标志
  21. bit kn=0;//开关标志
  22. //初始化定时器T0
  23. void Timer0_Init(void)                //1毫秒@11.0592MHz
  24. {
  25.         TMOD |= 0x01;                        //设置定时器模式
  26.         TL0 = 0x66;                                //设置定时初始值
  27.         TH0 = 0xFC;                                //设置定时初始值
  28.         TR0 = 1;                                //定时器0开始计时
  29.         ET0 = 1;
  30.         EA  = 1;
  31. }
  32. //显示函数
  33. void display()
  34. {
  35.         static uchar i;
  36.         P3=0x00;
  37.         switch(i)
  38.         {
  39.                 case 0: ADDR0 = 0; ADDR1 = 1;ADDR2 = 1;ADDR3 = 1;break;
  40.                 case 1: ADDR0 = 1; ADDR1 = 0;ADDR2 = 1;ADDR3 = 1;break;
  41.                 case 2: ADDR0 = 1; ADDR1 = 1;ADDR2 = 0;ADDR3 = 1;break;
  42.                 case 3: ADDR0 = 1; ADDR1 = 1;ADDR2 = 1;ADDR3 = 0;break;
  43.         }
  44.         P3=LedBuff[i];
  45.         i=++i%4;
  46. }
  47. //按键扫描
  48. void keys_can()
  49. {     
  50.         static uchar count=0;
  51.         static bit sign_key=0;

  52.         if(!k1||!k2||!k3)
  53.         {
  54.                 if(++count>=20 && sign_key==0)
  55.                 {
  56.                         sign_key=1;
  57.                         fm = 1;
  58.                         if(!k1 && !start && kn)
  59.                         {
  60.                                 knum++;
  61.                                 if(knum>=4)knum=0;
  62.                                 switch(knum)
  63.                                 {
  64.                                         case 0: sec=10;ms =0; break;
  65.                                         case 1: sec=30;ms= 0; break;
  66.                                         case 2: sec= 0;ms=30; break;
  67.                                         case 3: sec= 0;ms=50; break;
  68.                                 }
  69.                         }
  70.                         if(!k2 && !start && kn)
  71.                         {
  72.                                 switch(knum)
  73.                                 {
  74.                                         case 0: sec=10;ms =0; break;
  75.                                         case 1: sec=30;ms= 0; break;
  76.                                         case 2: sec= 0;ms=30; break;
  77.                                         case 3: sec= 0;ms=50; break;
  78.                                 }
  79.                                 cnt=0;
  80.                                 mos=0;
  81.                                 start=1;
  82.                         }
  83.                         if(!k3)
  84.                         {
  85.                                 kn=~kn;
  86.                                 if(!kn)
  87.                                 {
  88.                                         knum=0;
  89.                                         cnt=0;
  90.                                         mos=1;
  91.                                         start=0;
  92.                                         sec=10;
  93.                                         ms = 0;
  94.                                 }
  95.                         }
  96.                 }
  97.         }
  98.         else
  99.         {
  100.                 count=0;
  101.                 sign_key=0;
  102.         }
  103. }
  104. //主函数
  105. void main()
  106. {
  107.         P3M0 = 0xff;  
  108.         P3M1 = 0x00;
  109.         Timer0_Init();
  110.         while(1)
  111.         {
  112.                 if(flag_ms)
  113.                 {
  114.                         flag_ms=0;
  115.                         display();
  116.                         keys_can();
  117.                         if(kn)       
  118.                         {
  119.                                 LedBuff[0] = LedChar[ms%10];
  120.                                 LedBuff[1] = LedChar[ms/10];
  121.                                 LedBuff[2] = LedChar[sec%10]|0x04;
  122.                                 LedBuff[3] = LedChar[sec/10];  
  123.                         }
  124.                         else
  125.                         {
  126.                                 LedBuff[0] = 0x00;
  127.                                 LedBuff[1] = 0x00;
  128.                                 LedBuff[2] = 0x00;
  129.                                 LedBuff[3] = 0x00;
  130.                         }
  131.                 }
  132.         }
  133. }
  134. //T0中断服务函数
  135. void InterruptTimer0() interrupt 1
  136. {
  137.         TL0 = 0x66;                                //设置定时初始值
  138.         TH0 = 0xFC;                                //设置定时初始值
  139.         if(start)
  140.         {
  141.                 if(++cnt>=10)//10ms
  142.                 {
  143.                         cnt=0;
  144.                         ms--;
  145.                         if(sec==0 && ms==0)
  146.                         {
  147.                                 start=0;
  148.                                 mos=1;
  149.                                 fm=0;
  150.                         }
  151.                         else if(ms<0)
  152.                         {
  153.                                 ms=99;
  154.                                 sec--;
  155.                         }
  156.                 }
  157.         }
  158.         flag_ms=1;
  159. }
复制代码



回复

使用道具 举报

10#
ID:1045601 发表于 2023-8-11 14:31 来自手机 | 只看该作者
wulin 发表于 2023-8-10 19:55
用一个定时器就可以搞定

老师,学生这厢有礼了。膜拜大神,代码已解决我想要的功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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