i = P1 >> 4 ^ 0x0f;
时间: 2024-05-18 17:17:43 浏览: 10
这行代码将P1口的高4位右移4位,得到按键状态的低4位,再与0x0f异或,得到按键状态的补码,即按键为1则对应的位变为0,按键为0则对应的位变为1。这样做是因为矩阵按键的列连接P1的高4位,行连接P1的低4位,将高4位右移4位可以将按键状态的高4位移到低4位,方便后面的switch语句判断哪个按键被按下。
相关问题
修改下述程序,实现用定时器0定时,使得LED灯每1ms闪烁一次:// // INT0---P3.2 ---connect to a button // when the button is pressed, the LED changes between fast blink and slow blink // ------CH 2021.7.29 //************************************************************* #include "STC32G.h" #include "stdio.h" #include "intrins.h" typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; #define MAIN_Fosc 24000000UL //========================================================================== // sbit INT1 = P3^3; bit flag=0; // /************* function declaration **************/ void delay_ms(u8 ms); /******************** Main function**************************/ void main(void) { u8 i; WTST = 0; P0M1 = 0x00; P0M0 = 0x00; //IO set up P1M1 = 0x00; P1M0 = 0x00; P2M1 = 0x00; P2M0 = 0x00; P3M1 = 0x0f; P3M0 = 0x00; P4M1 = 0xff; P4M0 = 0x00; P5M1 = 0x00; P5M0 = 0x00; P6M1 = 0x00; P6M0 = 0x00; P7M1 = 0x00; P7M0 = 0x00; EX0 = 1; //interrupt enable EA = 1; //all interrupt enable IT0=1; // edge trigger while(1) { if(flag==0) { i=1000; } else {i=10; } P2=0xff; delay_ms(i); P2=0x00; delay_ms(i); } } //======================================================================== void delay_ms(u8 ms) { u16 i; do{ i = MAIN_Fosc / 6000; while(--i); }while(--ms); } /********************* INT0*************************/ void INT0_int (void) interrupt 0 { flag=~flag; }
下面是修改后的程序,使用定时器0实现LED每1ms闪烁一次:
```c
#include "STC32G.h"
#include "stdio.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#define MAIN_Fosc 24000000UL
bit flag = 0;
void delay_ms(u8 ms);
void main(void)
{
u8 i;
WTST = 0;
P0M1 = 0x00;
P0M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P3M1 = 0x0f;
P3M0 = 0x00;
P4M1 = 0xff;
P4M0 = 0x00;
P5M1 = 0x00;
P5M0 = 0x00;
P6M1 = 0x00;
P6M0 = 0x00;
P7M1 = 0x00;
P7M0 = 0x00;
EX0 = 1;
EA = 1;
IT0 = 1;
TMOD |= 0x01; // 设置定时器计数模式为模式1
TH0 = (65536 - (MAIN_Fosc / 1000)) / 256; // 设置定时器初值
TL0 = (65536 - (MAIN_Fosc / 1000)) % 256;
TR0 = 1; // 启动定时器
while (1)
{
if (flag == 0)
{
i = 1000;
}
else
{
i = 10;
}
P2 = 0xff;
delay_ms(i);
P2 = 0x00;
delay_ms(i);
}
}
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 6000;
while (--i)
;
} while (--ms);
}
void INT0_int(void) interrupt 0
{
flag = ~flag;
}
```
这个修改后的程序使用了定时器0来实现延时,每1ms触发一次中断,控制LED的闪烁。请确保定时器计数频率正确设置,并且定时器的中断向量正确配置为中断0。
代码解释#include <reg51.h> #define uchar unsigned char #define uint unsigned int // c0de for 7Seg MPX CA, from 0 to 9 and A to F and - // if want to use in CC, add ~ uchar code numberDisplayTable[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, 0xbf}; // delay time for notes uint code noteDelayTime[] = {64021, 64103, 64260, 64400, 64524, 64580, 64684, 64777, 64820, 64898, 64968, 65030, 65058, 65110, 65157, 65178}; sbit BEEP = P3 ^ 0; uchar keyNumber; void delay(uchar x) { uchar i; while (x--) for(i = 0; i < 120; i++); } void scanKey() { uchar tmp, k; P1 = 0x0f; delay(2); tmp = P1 ^ 0x0f; switch (tmp) { case 1: k = 0; break; case 2: k = 1; break; case 4: k = 2; break; case 8: k = 3; break; default:// no key down? return; } // set low 4 bits to 0, so place in 4 rows P1 = 0xf0; delay(2); // after button push, 11110000 will turned into XXXX0000, 1 0 in X, 3 1 in X // so we extract the 0 out tmp = (P1 >> 4) ^ 0x0f; // set 0,4,8,12 for row 0 ~ 3 switch (tmp) { case 1: k += 0; break; case 2: k += 4; break; case 4: k += 8; break; case 8: k += 12; break; default: return; } keyNumber = k; } // play sound via int0 void playNote() interrupt 1 { TH0 = noteDelayTime[keyNumber] / 256; TL0 = noteDelayTime[keyNumber] % 256; BEEP = ~BEEP; } void main() { // display - at start P0 = 0xbf; TMOD = 0x01; IE = 0x82; while (1) { // send scanner P1 = 0xf0; // if button down if (P1 != 0xf0) { scanKey(); P0 = ~numberDisplayTable[keyNumber]; // enable timer TR0 = 1; } else { // stop timer TR0 = 0; } delay(2); } }
这是一段8051单片机的程序代码,主要实现了一个数字键盘的输入和对应的数字音符的播放功能。具体来说,代码中使用了一个数字表来表示0~9和A~F以及“-”这些数字在数码管上的显示方式(使用了共阴极的7段数码管),同时也定义了一个数组来表示每个音符需要延时的时间。在主函数中,程序通过扫描数字键盘的输入来获取用户按下的键号,并根据键号找到对应的音符延时时间,然后通过定时器来实现音符的播放。同时,程序也根据键号将对应的数字在数码管上进行显示。整个程序的逻辑比较清晰,主要是通过数字表和延时时间表来实现功能。