|
小弟初學單片機,正在寫一個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;
}
|
|