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也可以实现取反。