1. 位运算在单片机中的使用
& : 按位与 (与0得0、与1不变)(全1为1,有0得0)指定位置0
1. 让一个字节第n位(从右往左第n位)置0
P0 &= ~(1 << n);
2. 让一个字节第n位(从右往左第n位)和第m位(从右往左第m位)置0:
P0 &= ~((1 << n) | (1 << m));
3. 判断一个字节某一位是否为1
int i = 0xaaaaaaaa;if ((i & (1 << n) != 0)
{printf("第n位是 1 \n");
}else
{printf("第n位是 0 \n");
}
4. 判断一个字节某一位是否为0
int i = 0xaaaaaaaa;if ((i & (1 << n)) == 0)
{printf("第n位是 0 \n");
}else
{printf("第n位是 1 \n");
}
| : 按位或 (或1得1、或0不变)(全0为0,有1得1)指定位置1
1. 让一个字节第n位(从右往左第n位)置1:
P0 |= (1 << n);
2. 让一个字节第n位(从右往左第n位)和第m位(从右往左第m位)置1:
P0 |= ((1 << n) | (1 << m));
^ :按位异或 (相同为0、相异为1) (异或1翻转原位, 异或0原位不变) 指定位翻转
1. num ^ num == 0 num ^ 0 == num
2. 让一个字节整体翻转
P0 ^= 0XFF;
<< 左移 放大:乘以2^n
>> 右移 缩小:除以2^n
~ 按位取反
2. 单片机流水灯程序
1. 主函数
#include <reg51.h>
#include "led.h"void delay(unsigned int n)
{while (n--);
}int main(void)
{while (1){int i = 0;for (i = 0; i < 8; i++){led_on_n(i);delay(0xffff);}for (i = 7; i >= 0; i--){led_on_n(i);delay(0xffff);} }return 0;
}
2. 头文件
#ifndef _LED_H_
#define _LED_H_extern void init_led(void);
extern void led_all_on(void);
extern void led_all_off(void);
extern void led_all_nor(void);
extern void led_on_n(unsigned int n);#endif
3. 源文件
#include <reg51.h>
#include "led.h"void init_led(void)
{P2 = 0XFF;
}void led_all_on(void)
{P2 = 0;
}void led_all_off(void)
{P2 = 0XFF;
}void led_all_nor(void)
{P2 ^= 0XFF;
}void led_on_n(unsigned int n)
{P2 = ~(1 << n);
}
3. 单片机数码管程序
1. 主函数
#include <reg51.h>
#include "digit.h"void delay(unsigned int n)
{while (n--);
}int main(void)
{int cnt = 0;int n = 0;while (1){cnt = 0x5f;while (cnt != 0){show_number(n);cnt--; }n++;}return 0;
}
2. 头文件
#ifndef _DIGIT_H_
#define _DIGIT_H_extern void display(int digit, int n);
extern void show_number(unsigned int n);#endif
3. 源文件
#include <reg51.h>
#include "digit.h"void display(int digit, int n)
{unsigned char a[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};P1 &= ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));P1 |= (1 << digit);P0 = a[n];
}void show_number(unsigned int n)
{int i = 0;int j = 0;while (n != 0){i = n % 10;n /= 10;display(j++, i);}
}