1. 程式人生 > >例項分析嵌入式程式碼

例項分析嵌入式程式碼

1、SEG8c.s

首先是對數碼管點亮方式的理解,

上課的時候老師將講到用數碼管顯示的數字為31+80,怎麼也想不通。

回來看到老師的逐個點亮數碼管每一段的程式碼如下:

myRCC.APB2ENR |=
(1 << RCC_APB2ENR_bIOPEEN); // 使能PE
PE.CRL = 0x22222222; // 配置PE7:0為推輓輸出(頻寬2MHz)
PE.CRH = 0x44222222; // 配置PE13:8為推輓輸出(頻寬2MHz)
PE.ODR = 0x101;
PE.ODR = 0x102;
PE.ODR = 0x104;
PE.ODR = 0x108;
PE.ODR = 0x110;
PE.ODR = 0x120;
PE.ODR = 0x140;
PE.ODR = 0x180;

可見ODR暫存器的高16位保留,低16位用於控制。低16位的低8位中,如果某段要亮的話,對應的位置1,這樣的話低8位就可以控制一個數碼管的8段了。

第1段:低8位為00000001->01;

第2段:低8位為00000010->02;

第3段:低8位為00000100->04;

第4段:低8位為00001000->08;

第5段:低8位為00010000->10;

第6段:低8位為00100000->20;

第7段:低8位為01000000->40;

第8段:低8位為10000000->80;

 所以老師說的31+80=01+10+20+80。

2、tsKey2LED.c中

Init(void)
{
    GPIO_InitTypeDef  GPIO_Info;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB 
| RCC_APB2Periph_GPIOD, ENABLE); // // 使能PB,PD埠時鐘 // 按鍵: PB7:4 GPIO_Info.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4; // // 指定引腳 GPIO_Info.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空輸入
GPIO_Init(GPIOB, &GPIO_Info); // 根據設定引數初始化 // LED: PD6:3 GPIO_Info.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3; // // 指定引腳 GPIO_Info.GPIO_Mode = GPIO_Mode_Out_PP; // 推輓輸出 GPIO_Info.GPIO_Speed = GPIO_Speed_2MHz; // IO口速度為2MHz GPIO_Init(GPIOD, &GPIO_Info); // 根據設定引數初始化 }
int
main(void)
{
    uint16_t    Res;

    Init();                     //  初始化
    do
    {
        Res = GPIO_ReadInputData(GPIOB);            //  讀取PB
        GPIO_Write(GPIOD, ((~Res & 0xF0) >> 1));    //  用按鍵控制LED
    }
    while ((Res & 0xF0) != 0x80);//退出條件
    return 0;
}
GPIO_Write(GPIOD, ((~Res & 0xF0) >> 1)); 

 由於按鍵是低電平接通,且是PB的4,5,6,7口,而LED燈是PD的3,4,5,6口,所以將按鍵的電平翻轉之後再與上0xF0的效果就是PB的高4位取反,而低4位置0,再向右邊移1位,就可以將LED等點亮。

 3、Flow.c中   

 Pins = Pattern[k][k2];  //  圖案
PE.BSRR = Pins | // 點亮指定位置LED ((Pins ^ 0xFFF) << 16); // 熄滅其它位置LED

pins裡面的1對應著要要點亮的數碼管的段數,如何熄滅其他位置的燈呢?

BSRR對高16位是寫1清0,所以我們將不需要點亮的引腳位置設定為1,放到BSRR暫存器中去,就可以熄滅他們。
pins中已經將需要點亮的設定為1了,不需要點亮的設定為0了,所以將pins取反就可,Pins ^ 0xFFF是一種取反方式,~Pins也可以實現取反。