この記事は私のレビュー段階の要約です。私はレビューノートを書きました、そしてそれを共有できてうれしいです。Xiaobaiはそれを監視し、より早く始めることもできます。
LEDの初期化
初期化の部分は比較的単純であり、要点ではなく、コードを直接貼り付けます。
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
// RCC_AHBPeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);//时钟使能
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_Init(GPIOD,&GPIO_InitStructure);
}
2つの異なるLEDドライブコード
最初の方法は、ドライバー関数を作成することです。
void LED_Control(u16 cont,int status)
{
if(status==1)
{
GPIO_ResetBits(GPIOC,cont<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
if(status!=1)
{
GPIO_SetBits(GPIOC,cont<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
この書き込み方法は、直接使用する方が便利です。書き方の詳細については、この大物が追加したリンクの説明
を参照してください。ここで、GPIO_ResetBits()とGPIO_SetBits()はGPIOx_BRRとGPIOx_BSRRに対する操作であることに言及する必要があります。これら2つのレジスターの紹介を以下に掲載しました。**詳細については、中国語版のSTM32リファレンスマニュアルを参照してください。** BSRRレジスタは他のビットに影響を与えることなく1つのビットで独立して動作できることがわかります。簡単な説明は、1つのLEDライトしか制御できないということです。
2番目の方法は、レジスタを直接操作することです。
GPIOC-> ODR = 0XFFFF;
GPIOD-> ODR |= (1<<2);
GPIOD-> ODR &=~(1<<2);
これは初期化コードであり、特定の機能はすべてのLEDライトをオフにすることです。
ここで使用するODRレジスタはBSRRレジスタとは異なります。ODRレジスタがすべてのビットで動作していることがわかります。したがって、0XFFFFはすべてのLEDライトをオフにする効果を実現できます。
2つの方法の比較
最初は、その便利さから、最初の関数法を学びました。2番目の方法は不快です。結局のところ、ライブラリ関数の操作はレジスタの操作よりも直感的で便利であり、非常に多くのビット操作を覚えておく必要があります。しかし、深く研究すると、2番目の方法には利点があることがわかります。
詳細については、第8回州コンテストの模擬質問を参照してください。
温度と湿度の2つの基準が同時に上限を超える可能性があることがわかります。つまり、L1が点滅しているときは、L2も点滅し、L3も点滅します。3つのライトの状態は、互いに影響を与えることなく独立して切り替えることができます。これは難しい点です。最初の方法で関数を書くと、ライトの点滅を実現するのが非常に面倒で、多くの関数を設定する必要があり、1つの点滅状態から2つの点滅状態に切り替えるのが難しくなります。上記のBSRRレジスタは1ビットのみで動作します。2ビットに変換したい場合はスムーズではありません。つまり、3つのライトを個別に切り替える機能は困難です。あなたはそれを試してみることができます。
しかし、レジスターの操作は非常に簡単です。
u16 LED_MODE = 0XFFFF;
if(LED_Flag)
{
if(Temperature > TH_compare)//当达到温度上限
{
LED_MODE ^= (1<<8);//实现灯的状态反转
}else //没有达到温度上限
{
LED_MODE |= (1<<8);//熄灭
}
if(RH > RH_cpmpare)
{
LED_MODE ^= (1<<9);
}else
{
LED_MODE |= (1<<9);
}
GPIOC-> ODR = LED_MODE;
GPIOD-> ODR |= (1<<2);
GPIOD-> ODR &=~(1<<2);
LED_Flag = 0;
}
これにはビット演算が含まれます。
int led_mode =0xffff
led_mode &=~(1<<2);//第三位置零,计算结果为led_mode=0xfffB
led_mode |=(1<<2);//第三位置1,计算结果为led_mode=0xffff
led_mode ^=(1<<2);//第三位取反,计算结果为led_mode=0xfffB
led_mode ^=(1<<2);//第三位再次取反,计算结果为led_mode=0xffff
1つの機能だけでランプの状態を反転できることがわかります。そして最も重要なことは、各ランプの状態が互いに影響を与えないということです。あなたはあなたの理解を深めるためにあなた自身でそれをすることができます。
総括する
理解を深めるために、両方の方法を試すことをお勧めします。開始するときは、最初に関数メソッドを使用してから、レジスタの操作方法を学習してください。