|
小弟初学单片机,正在写一个EC11数码管菜单的程序,遇到问题搞不定,特来发帖请教。
实现功能:EC11数码管菜单的子功能,上电后左右旋转增减数值。按钮长按三秒后,个位闪动,进入调整状态。旋转按钮,数值加减1,可自动进位;短按一次,十位闪动,数值加减10,逢100自动进位;再短按一次,百位闪动,数值加减100。
加值时候正常,问题出在对百位减值的时候。假如现在值是134,百位闪动。这时旋钮左转一格,百位应该变成0,同时改成十位闪动;若旋钮再左旋3格,十位变成0,同时改成个位闪动。在十位或个位闪动的时候,短按按钮,闪动的位数应该自由升位,但是现在不行。
(就是说在百位变成0时,闪动标记n应该由1变成2,但是只变一次就行了,不要再被while循环扫描。现在是一直被while扫描,导致短按按钮时数值2降不下来)我这块代码肯定是写错了,但我搞了好几天,能力有限,实在想不出来解决方法,故此发帖求助。
减值这块有点绕,但愿我上面说清楚了。下面贴出单片机代码,请大佬不吝指导。
#include "STC8G.h"
#include "TM1650.h"
char n=3; //闪动位数
unsigned char flag_1ms=0; //时间基线1ms
unsigned int flag_300ms=0; //闪动间隔时长
bit Active_Menu=0; //激活设置标志
bit flag=0; //闪动标志
//sbit LED=P1^1; //按钮测试
sbit EC11_A=P3^2; //加值
sbit EC11_B=P3^3; //减值
sbit K3 = P3^4; //设置键
int number=134;//显示数值初始化
//-----------------------------------------------------------------
unsigned char code SEG7[] = {0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char LedBuff[] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char ucDigDot[8];//要显示的8个小数点
int num[] = {0, 0, 0, 0};
void display();
void EC11_K3_Scan();
int Jia_jian(int Value);
int EC11_Scan(int EC11_value);
void EC11_K3_Scan() //EC11按键功能
{
static unsigned int K3_press_time=0; //按键计时变量
static bit K3_sign=0; //按键状态标志
if(K3==0) //按键按下
{
K3_press_time++;
if(K3_press_time>3000)
K3_press_time=3001; //防止溢出
if(K3_press_time>10 && K3_sign==0) //10ms消抖
K3_sign=1; //确认按键按下
if(K3_press_time==3000) //判断按下3s有效
{
Active_Menu=~Active_Menu;
if(Active_Menu==0) flag=0;
//LED=!LED; //按键测试
}
}
else //短按或按下后松手
{
if(K3_sign==1)//判断是按键按下后松手
{
K3_sign=0;
if(K3_press_time<1000)//小于1s判断短按
if(Active_Menu==1)
{
n--; //个位、十位、百位切换
if (n <0) n = 3;
}
//LED=!LED; //任务按键测试
if(K3_press_time>=1000 && K3_press_time<3000);//大于1s有效
//任务
}
K3_press_time=0;
}
}
int Jia_jian( int Value) //加减值函数
{
{num[0]=Value/1000;
num[1]=(Value/100)%10;
num[2]=(Value/10)%10;
num[3]=Value%10;}
Value=EC11_Scan(Value);
if (Value<100&&Value>10) //有问题的代码
n=2; //有问题的代码
else if (Value<10&&Value>0)//有问题的代码
n=3; //有问题的代码
if (Value<0)
Value=0;
if (Value>9999) Value=0;
display();
return Value;
}
void display()//1650显示
{
unsigned char i;
unsigned char j;
for(i = 0; i < 4; i++)
LedBuff[ i] = num[ i];
if (flag)
LedBuff[n] = 10;
for(j=0;j<4;j++)
Set1650(DIG_BIT_CODE[j],SEG7[LedBuff[j]]);
}
void Timer1Init(void) //1毫秒@11.0592MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x66; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA=1; //开总中断
ET1=1; //开定时器T1中断
}
//---------------------------------------
void main()
{
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
P_SW2 |= 0x80; //准双向口(或开漏模式) + 内部上拉
P3PU=0xc0;
Timer1Init();//定时器1初始化
Init1650();//1650初始化
while(1)
{
if(flag_1ms==1)
{
flag_1ms=0;
number=Jia_jian(number);
EC11_K3_Scan();
}
}
}
//---------------------------------------
void T1_time() interrupt 3 //定时器T1的中断序号为3,T1的中断服务函数
{
flag_1ms=1;
if(Active_Menu==1)
flag_300ms++;
if(flag_300ms==300)
{
flag_300ms=0;
flag = ~flag;//闪动标志
}
}
/*********************************
* @函数名:EC11_Scan
* @描 述:判断方向,计算旋转的值。个位闪动+/-1;十位闪动+/-10;百位闪动+/-100。
* @参 数:EC11_value
* @返回值:EC11_value
*********************************/
int EC11_Scan(int EC11_value)
{
static bit EC11_Flag=0,Left_Flag=0,Right_Flag=0;
if((EC11_A)&&(EC11_B)) //两个都是1,表示开始第一个脉冲
{
EC11_Flag =1 ;//标记为第一个信号收到,可以进行下一个信号
}
if(EC11_A!=EC11_B)//第二个信号
{
Left_Flag = EC11_A ; //记录AB的信号状态
Right_Flag = EC11_B ;
}
if(EC11_Flag)
{
if((EC11_A==0)&&(EC11_B==0)) // 第三个信号,处理第二个信号的值
{
if(Left_Flag) //左转
{
if (n==1) //百位闪动
EC11_value-=100; //百位闪动-100
else if (n==2) //十位闪动
EC11_value-=10; //十位闪动-10
else if (n==3) //个位闪动
EC11_value--; //个位闪动-1
}
else if(Right_Flag)
{
if (n==1) //百位闪动
EC11_value+=100; //百位闪动+100
else if (n==2) //十位闪动
EC11_value+=10; //十位闪动+10
else if (n==3) //个位闪动
EC11_value++; //个位闪动+1
}
EC11_Flag = 0; //把标志位清零,等待下一个周期
}
}
return EC11_value;
}
|
|