单片机逻辑取反和按位取反差异

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机逻辑取反和按位取反差异相关的知识,希望对你有一定的参考价值。

单片机C语言开发逻辑取反和按位取反差异


新手入门容易犯的小错误。

示例程序


/*---------------------------------------------------------------------*/
/* --- STC MCU International Limited ----------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

/*************	功能说明	**************

双串口全双工中断方式收发通讯程序。

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.

******************************************/

#define 	MAIN_Fosc			11059200L	//定义主时钟
#include	"STC15Fxxxx.H"
#include "stdio.h"
#define		BaudRate1		9600L
#define		UART1_BUF_LENGTH	32
#define	RX1_Lenth		32			//串口接收缓冲长度
#define	Timer1_Reload	(65536UL -(MAIN_Fosc / 4 / BaudRate1))		//Timer 1 重装值, 对应300KHZ

u8	TX1_Cnt;	//发送计数
u8	RX1_Cnt;	//接收计数
bit	B_TX1_Busy;	//发送忙标志

u8 	idata RX1_Buffer[UART1_BUF_LENGTH];	//接收缓冲
unsigned char *pchar;				//定义一个全局指针

void	UART1_config(u8 brt);	// 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
void 	PrintString1(u8 *puts);
//========================================================================
// 函数: void  delay_ms(unsigned int ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数,  自动适应主时钟.

//========================================================================
void  delay_ms(unsigned int ms)

     unsigned int i;
	 do
	      i = MAIN_Fosc / 13000;
		  while(--i)	;   //14T per loop
     while(--ms);


void InitSerialPort(void)
 
	SCON = 0x50;			//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TH1 = (u8)(Timer1_Reload >> 8);
	TL1 = (u8)Timer1_Reload;
	
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
			ES=1; 				//串口中断开关,采用查询法时不用打开中断      
    	REN=1;      			//串口为工作方式1,允许接收数据
    	SM0=0;					//SM0 SM1串口工作方式选择,01:8位异步收发,波特率由定时器决定
    	SM1=1;


//========================================================================
// 函数: void main(void)
// 描述: 主函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注: 
//========================================================================
void main(void)

	unsigned int n;
	P0M1 = 0;	P0M0 = 0;	//设置为准双向口
	P1M1 = 0;	P1M0 = 0;	//设置为准双向口
	P2M1 = 0;	P2M0 = 0;	//设置为准双向口
	P3M1 = 0;	P3M0 = 0;	//设置为准双向口
	P4M1 = 0;	P4M0 = 0;	//设置为准双向口
	P5M1 = 0;	P5M0 = 0;	//设置为准双向口
	P6M1 = 0;	P6M0 = 0;	//设置为准双向口
	P7M1 = 0;	P7M0 = 0;	//设置为准双向口

		InitSerialPort();//串口初始化

	EA = 1;	//允许总中断

	PrintString1("STC15F2K60S2 UART1 Test Prgramme!\\r\\n");	//SUART1发送一个字符串

	while (1)
	
		delay_ms(500);
		n = ~0;
		printf("uint = ~0:%u \\r\\n",n);	//SUART1发送一个字符串
		n = !0;
		printf("uint = !0:%u \\r\\n",n);	//SUART1发送一个字符串
		P10 = !P10;
	



//========================================================================
// 函数: void PrintString1(u8 *puts)
// 描述: 串口1发送字符串函数。
// 参数: puts:  字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注: 
//========================================================================
void PrintString1(u8 *puts)	//发送一个字符串

    for (; *puts != 0;	puts++)   	//遇到停止符0结束
	
		SBUF = *puts;
		B_TX1_Busy = 1;
		while(B_TX1_Busy);
	

//重写putchar函数,方便调用printf串口打印输出
 char putchar(unsigned char c)

	     SBUF = c; 					//发送数据
     while(!TI); 					//等待发送完成
     TI=0; 							//清零发送标志位;
	return c;






//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: UART1中断函数。
// 参数: nine.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注: 
//========================================================================
void UART1_int (void) interrupt UART1_VECTOR

	if(RI)
	
		RI = 0;
		RX1_Buffer[RX1_Cnt] = SBUF;		//保存一个字节
		if(++RX1_Cnt >= RX1_Lenth)	RX1_Cnt = 0;	//避免溢出处理
	

	if(TI)
	
		TI = 0;
		B_TX1_Busy = 0;		//清除发送忙标志
	




  • 无符号整型数值0按位取反就是:65535;逻辑取反值:1

以上是关于单片机逻辑取反和按位取反差异的主要内容,如果未能解决你的问题,请参考以下文章

复习一个小知识点(反码与按位取反)

C#'~'按位取反运算符的使用

按位取反运算符与补码

XMM 寄存器的按位取反

第41题按位取反~的应用(更新中)

按位与,按位或,按位异或,按位取反