目次
1. デザイン内容
この設計では 2 つのボタンを使用しており、ボタンが押されていない場合は下の LED が点灯し、KEY1 が押されると外部割り込み 0 が割り込みを要求し、下から上に LED が 3 回点灯するように制御され、KEY2 を押すと、外部割り込み 1 が割り込みを要求し、制御 LED が 3 回点滅します。(外部割り込み 1 の優先順位が外部割り込み 0 の優先順位よりも高い、つまり KEY2 を押した後に水ランプの動作を中断できる必要があり、外部割り込み 1 の処理が完了すると、外部割り込み 0 が再開され、前回中断された外部割り込み 0 を中断できます。LED が循環を開始します)。
2. 割り込み関連の知識
1.51 MCU割り込み要因
割り込みソース |
割り込み番号 |
エントリーアドレス |
外部中断0 |
0 |
0003H |
外部中断1 |
2 |
0013H |
タイマーT0 |
1 |
000BH |
タイマーT1 |
3 |
001BH |
シリアル割り込み |
4 |
0023H |
2. 割り込み系特殊機能レジスタ
割り込みイネーブルレジスタIE、タイマ/カウンタT0/T1制御レジスタTCON、タイマ/カウンタT2制御レジスタT2CON、シリアルポート制御レジスタSCON
3. 割り込み関数と関数呼び出しの違い
割り込み関数は戻り値を持つことができず、割り込み関数はパラメータを渡すことができません。また、割り込み関数プログラムは短く簡潔である必要があります。
3. シミュレーションの概念図
4. プログラミング
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 外部中断
* 创作者 : 薄情书生
* 创作时间 : 2022.9.27
*******************************************************************************/
main.c文件
#include "reg52.h"
#include "led.h"
#include "exit.h"
/*************38译码器**************/
void SelectHC138(unsigned char channel)
{
switch(channel)
{
case 0:
P1 = (P1 & 0x1f)|0x00;break; //发光二极管(LEDS0)
}
}
/*************主函数******************/
void main()
{
SelectHC138(0);
Exint_Init();
while(1)
{
P0 = 0x7f;
}
}
delay.c文件
#include "delay.h"
/*********毫秒延时*********/
void delay_ms(u16 ms)
{
u16 x,y;
for(x=ms;x>0;x--)
for(y=114;y>0;y--);
}
led.c文件
#include "led.h"
#include "reg52.h"
#include "delay.h"
#include "intrins.h"
/*************LED由下至上**************/
void Bottom_Up()
{
u8 i,j;
for(j=0;j<3;j++)
{
for(i=0,P0 = 0xff;i<8;i++)
{
P0 = P0<<1;
delay_ms(200);
}
}
P0 = 0xff;
}
/*************LED由上至下**************/
void Up_Bottom()
{
u8 i,j;
for(j=0;j<3;j++)
{
for(i=0,P0 = 0xff;i<8;i++)
{
P0 = P0>>1;
delay_ms(100);
}
}
P0 = 0xff;
}
/*************LED齐闪烁**************/
void LED_twinkle()
{
u8 i,j;
for(j=0;j<3;j++)
{
for(i=0,P0 = 0x00;i<3;i++)
{
P0 = ~P0;
delay_ms(500);
}
}
P0 = 0xff;
}
/*************LED保持3s**************/
void Hold_3s()
{
P0 = 0x00;
delay_ms(3000);
P0 = 0xff;
}
/*************两边至中间**************/
void LED_sides()
{
u8 i,j,ri,lf;
for(j=0;j<3;j++)
{
for(i=0,ri=0x7f,lf=0xfe;i<4;i++)
{
P0 = ri&lf;
ri = _cror_(ri,1);
lf = _crol_(lf,1);
delay_ms(1000);
}
}
P0 = 0xff;
}
/*************中间至两边**************/
void LED_middle()
{
u8 i,j,ri,lf;
for(j=0;j<3;j++)
{
for(i=0,ri=0xef,lf=0xf7;i<4;i++)
{
P0 = ri&lf;
ri = _crol_(ri,1);
lf = _cror_(lf,1);
delay_ms(1000);
}
}
P0=0xff;
}
exit.c文件
#include "exit.h"
#include "reg52.h"
#include "led.h"
/*********外部中断0、1初始化***********/
void Exint_Init()
{
IT0 = 0;
IT1 = 0;
PX0 = 0;
PX1 = 1;
EA = 1;
EX0 = 1;
EX1 = 1;
}
/*********外部中断0服务函数***********/
void Exint0_Service() interrupt 0
{
Up_Bottom();
}
/*********外部中断1服务函数***********/
void Exint1_Service() interrupt 2
{
LED_twinkle();
}
5. シミュレーション結果
ボタンが押されていないときは、下の LED が点灯します。
KEY1 が押され、外部割り込み 0 により割り込みが要求され、LED が下から上に 3 回点灯制御されます。
KEY2 を押すと、外部割り込み 1 により割り込みが要求され、制御 LED が 3 回点滅します。
KEY2 を押すと KEY1 の水ランプの動作を中断することができ、外部割り込み 1 の処理後、外部割り込み 0 の処理を再開し、前回中断した LED からサイクルを開始することができます。
6.考える質問
プログラムを修正して、INT0 と INT1 の優先順位を 0 に設定し、最初に KEY2 を押し、次に LED の点滅中に KEY1 を押して、LED の点滅を中断できるかどうかを確認してください。理由は何ですか?問題を考えるための参考プログラムは、「設計 3: 51 MCU ニキシー管ディスプレイ制御」で提供されます。
作者が言いたいことがある
このコラムは、51 シングルチップ マイコンの実践的なチュートリアルであり、実践を通じて学習を促進し、友人が 51 シングルチップ マイコンをすぐに使い始めるのを助けることを目的としています。この設計に関連する関連する理論的知識: 51 個のシングルチップ マイコンの外部割り込み制御、独立したボタンの使用、モジュラー プログラミングなどは、資料を参照して自分で学習してください。
この設計ソース プログラムとシミュレーション ソース ファイル Baidu ネットワーク ディスク リンク: リンク: https://pan.baidu.com/s/1TNwn74gbOoMzb3Wcqopvrg
抽出コード: vga5
設計 1: 51 シングルチップマイコン制御流水ランプ思考質問参照ソース プログラムとシミュレーション ソース ファイル百度ネットワーク ディスク リンク: https://pan.baidu.com/s/1bdtvHcNLI8ydR_t94DWQXw
抽出コード: gnv6