記事ディレクトリ
授業後の演習問題の解答
追加ボタン3. 押すと起動となり、選択した機能のLEDが点滅し続け動作中を示し、動作中は機能の切り替えはできません。
要件の分解
- 1 追加ボタン 3
#define KEY3 P34 //增加按键3
- 2 を押してレベルコントロールを開始します
- 3 動作ステータスがロックされているとは、
動作中であることを意味し、動作中に機能を切り替えることはできません。
この機能はフラグビットを検出する必要があり、動作中に切り替えることはできません。
追加: bit Run_Now = 0; //0 は動作を停止し、1 は動作を開始します。
次のように KEY3 制御コードを追加します。
/*=======================按下按键3,执行本段代码=====================*/
if (KEY3 == 0) //必须是按键按下才会执行以下代码,key3被点击,灯在一闪一闪的时候,KEY3非按下模式
{
delay_ms(10); //防抖
if (KEY3 == 0)
{
while(KEY3 == 0); //等待按键松开,将要执行按下蜂鸣
if(Run_Mode > 0) //表示有模式,已经选择了模式,Run_Mode=0时,未选择模式,不执行
{
BEEP = 0; //打开蜂鸣
delay_ms(10); //延迟10ms
BEEP = 1; //关闭蜂鸣
Run_Now = !Run_Now; //运行和停止之间的切换
}
}
}
if( Run_Now = 1) //正在运行
{
P2 = 0XFF; //全部熄灭
delay_ms(200); //延迟200ms
P2 = ~(1<< (Run_Mode - 1)); //点亮这个灯
delay_ms(200); //延迟200ms
}
else //停止运行时,没有工作,灯和上面的一样
{
P2 = ~(1<< (Run_Mode - 1));
}
KEY2を押しても0桁のLEDが点滅し続け、意図した機能が実現できません。
最初のバージョンのコードの問題の分析
これはコンパイルプロンプトの「警告 C137: 条件式の定数」に関係するもので、代入ではなく判断となります。改訂。
調整後、ステータスやその他の点滅を制御できますが、KEY2 を押します。動作は影響を受けません。論理エラーが発生しています。トラブルシューティングを続行します。
つまり、作業時には機能を切り替えることができず、実装されません。動作ステータス、変数 Run_Now は 1、KEY2 の切り替えの前提条件は Run_Now ステータスが 0 であるため、条件付き制限が追加されます: "if (Run_Now == 0) //切り替えは Run_Now ステータスの場合にのみ実行できます。は 0 (機能していません)。」
また、KEY2のコードは指を離さないと実行できませんが、実際の動作では押してから指が離れるか分かりませんので、押したときに実行するように変更してください。指が離れるまで待って、whileの位置を調整してください。最後までループ: while(KEY3 == 0); //ボタンが放されるまで待ちます。KEY1 が押されるとブザーが鳴ります
。それに応じて KEY2 も調整できます。
注: if...else は全体としてみなされ、while などの他の予約語を途中に追加することはできません。
コンパイル、開発ボードへの書き込み、ダウンロードが成功し、正常に機能します。
ヒント: STC-ISP 設定
保存して簡単に呼び出すことができます。
ボタンを少し長く押す必要がありますが、その理由はコースの後半で分析され、タイマーについて説明するときに最適化されます。
ヒント: タイマー
参考リンク:マイコンタイマーの動作原理とは マイコンタイマーの動作方法は何ですか?
マイクロコントローラを使用するときによく使用されるコンポーネントの 1 つはマイクロコントローラ タイマーです。マイクロコントローラ タイマーの主な機能は、ソフトウェア障害が発生したときに (ソフトウェアがデバイスをクリアしない場合に) デバイスをリセットすることによってマイクロコントローラをリセットすることです。マイクロコントローラをリセットするために使用されます. デバイスはスリープまたはアイドルモードからウェイクアップし, 正確な遅延処理にも使用できます. 時間制御, プログラム遅延, 外部時間カウントと検出などによく使用されます. では、マイコン タイマーの原理は何ですか?
マイコン タイマーは本質的にはカウンターです。パルスが立ち下がりエッジに達するたびに、カウント レジスタの値は 1 ずつ増加します。カウントされたパルスがマイコン内の水晶発振器からのものである場合、その周期は非常に正確であるため、タイマーと呼ばれますが、カウントされたパルスがマイクロコントローラーの外部ピンからのものである場合、その周期は一般に不正確であるため、カウンターと呼ばれます。
マイクロコントローラー タイマーの動作モードは何ですか?
マイクロコントローラー タイマーには多くの動作モードがあり、おおまかに次のカテゴリに分類できます: 1. モード 0
モード 0 は 13 ビットのカウントで、TLO (TLO) の下位 5 ビットで構成されます。 8 ビット TLO の下位 5 ビットがオーバーフローすると THO にキャリーされ、THO がオーバーフローすると TCON の TFO フラグがセットされ、CPU に割り込み要求が送信されます。
2. モード 1
モード 1 のカウント数は 16 ビットで、下位 8 ビットが TLO (TL1)、上位 8 ビットが THO (TH1) となり、16 ビットプラス 1 のカウンタとなります。3. モード 2
モード 2 は、初期値を自動的にリロードする 8 ビットのカウント モードです。モード 2 では、タイマーが 255 (FFH) に達してオーバーフローすると、ユーザーの介入なしに CPU が自動的に TH の値を TL にロードするため、より正確なパルス信号発生器としての使用に適しています。
4. モード 3
モード 3 はタイマ/カウンタ TO にのみ適用され、タイマ T1 のモード 3 は TR1=0 と等価でカウントを停止します。モード 3 は、TO を 2 つの独立した 8 ビット カウンタ TLO および THO に分割します。
完全な電磁調理器の表示機能を実現するコード
void Test(void) //电磁炉的功能
{
if (KEY1 == 0) //开关机键
{
delay_ms(1000); //长按1s开机
if (KEY1 == 0)
{
/*=======================还没有开机的情况下,执行本段代码=====================*/
if (Run_Flag == 0) //表示还没有开机
{
Run_Flag = 1; //开机变量改为1,表示已经开机
BEEP = 0; //打开蜂鸣
delay_ms(10); //延迟10ms
BEEP = 1; //关闭蜂鸣
P40 = 0; //打开了LED总电源
P2 = 0X00; //全部点亮
delay_ms(300); //延迟200ms
P2 = 0XFF; //全部关闭
}
else
{
Run_Flag = 0; //标记已关机
BEEP = 0; //打开蜂鸣(提醒)
delay_ms(10); //延迟10ms
BEEP = 1; //关闭蜂鸣
P2 = 0XFF; //状态指示全部关闭
P40 = 1; //关闭总电源LED
Run_Mode = 0; //模式清零
Run_Now = 0; //运行状态清零(改成停止)
}
while(KEY1 == 0); //按钮按下,先执行并等待按钮松开
}
}
/*=======================按下按键2,执行本段代码=====================*/
if (KEY2 == 0 && Run_Flag == 1 ) //切换模式,且处于开机状态,状态选择键有效
{
delay_ms(10); //防抖
if (KEY2 == 0)
{
if (Run_Now == 0) //Run_Now状态为0(未工作)时才能切换
{
BEEP = 0; //打开蜂鸣
delay_ms(10); //延迟10ms
BEEP = 1; //关闭蜂鸣
Run_Mode++; //每次按下,模式+1(移至下一个led)
if (Run_Mode > 8) //如果模式大于8,回到模式1
Run_Mode = 1; //Run_Mode超过8后清零,回到第一个灯
//错误写法,执行结果是8个灯中仅1个不亮
//灯是低电平点亮,1<< Run_Mode,即1<<1,左移以后为0000 0010,仅1个LED灭,继续左移,尾部补0,还是只有1个LED灭
//解决方法:RunMode先减1,再左移,最后全部取反。这里用~为全取反。而!是位取反。
//P2 = 0XFX; P6<< 1 + 1; 也可以实现
P2 = ~(1<< (Run_Mode - 1));
}
while(KEY2 == 0); //按钮按下,并等待按钮松开
}
}
/*=======================按下按键3,执行本段代码=====================*/
if (KEY3 == 0) //必须是按键按下才会执行以下代码,key3被点击,灯在一闪一闪的时候,KEY3非按下模式
{
delay_ms(10); //防抖
if (KEY3 == 0)
{
if(Run_Mode > 0 ) //表示有模式,已经选择了模式且处在开机状态下,Run_Mode=0时,未选择模式,不执行
{
BEEP = 0; //打开蜂鸣
delay_ms(10); //延迟10ms
BEEP = 1; //关闭蜂鸣
Run_Now = !Run_Now; //运行和停止之间的切换
}
while(KEY3 == 0); //等待按键松开,先执行
}
}
if( Run_Now == 1) //正在运行
{
P2 = 0XFF; //全部熄灭
delay_ms(200); //延迟200ms
P2 = ~(1<< (Run_Mode - 1)); //点亮这个灯
delay_ms(200); //延迟200ms
}
else //停止运行时,没有工作,灯和上面的一样
{
P2 = ~(1<< (Run_Mode - 1));
}
}
テストプロセス
まず、電源
が入るとKEY1が1回ビープ音を鳴らしてLEDが点灯しますが、KEY2のモードを切り替えるには(電源が入っている
状態である必要があります)、KEY3を押すと現在のLEDが点滅します(モードで動作)。実行状態では、モード切り替え時に短押し、長押しが無効になり、再度
KEY3を押すと、LEDの点滅が止まり(動作が停止)、モードが切り替わります。
後で、タイマーに関する章を完了すると、ボタンの反応が遅いという問題を解決できます。または、デジタル管を学習した後、修理することもできます。
要約する
通常の単純なロジックを明確にします。クレイジーはifとelseで判断しています。