Ⅰ 我正在写一个单片机串口与PC机通信的程序,开始:0xf0,数据,结束0xff. 怎么写啊
单片机作为从机,定义为接收状态,PC机的通信软件应主动向单片机发送询问数据,单片机接受到规定格式的数据后,即进行回答。若规定通信协议格式就是 开始0xf0, 数据,结束0xff。应在单片机接受中断中进行判断,若接收到0xf0,即认为数据流开始, 将其后接受的数据依次存在接收缓冲区里,直到检索到0xff,视为数据流结束。 接收结束后,作为应答, 仍然依照规定的数据格式发送数据串即可, 上位机软件同样依据以上流程做接受处理。
但是,你这个通信协议规定的过于简单,不能实用。如果数据中出现0xff也可能被误认为结束符。如果想以特定的字头作为数据流起始标志,可以多设几个字节,比如3个字节, 如规定0xf0,0x2a,0x7e三个数据连续出现时,作为数据流的开始,那么可靠性就会提高,另外,通信协议必须具有校验字节,例如校验和,或者CRC校验,校验字节后,才是结束符。如果没有校验,数据常常错乱,不能使用。 当接受到校验不能通过的数据流后,数据应当丢弃,重新接收。校验字节是必须要有的。
如果是简单的一对一通信,可以规定固定的数据流个数,那么此时可以没有结束符和起始符,只有固定的数据流个数和校验字节,就可满足通信要求。
Ⅱ 51单片机F0是什么意思
F0是程序状态字尺做局PSW的第6位,是用户胡败标志位。供用户使用的软件标志,其功能和内部RAM中位寻址区的陵让各个位相似。
还有一个F1是PSW的第2位,用法与F0相似,你看看单片机的书,找到PSW状态字就清楚。
Ⅲ 51单片机psw各个标志位的定义
Bit7
Cy
Bit6
AC
Bit5
F0
Bit4
RS1
Bit3
RS0
Bit2
OV
Bit1
-
Bit0
P
1.
CY(Carry):
CY表示加法进算中的进位和减法运算中的借位,加法运算中有进位或减法运算中有借位则CY位置1,否则为0。
2.
AC(Auxiliary
Carry):
与CY基本相同,不同的是AC表示的是低4位向高4位的进、借位。
3.F0:
该位是用户自己管理的标志位,用户可以根据自己的需要来设定。
4.
RS1、RS0:
这两位用于选择当前工作寄存器区。8051有8个8位寄存器R0~R7,它们在RAM中的地址可以根据用户需要来确定。
5.OV:
该位表示运算是否发生了溢出。若运算结果超过了8位有符号数所能表示的范围,即-128
~
+127,则
OV
=
1。
6.P:
P是奇偶标志位。若累加器A中1的个数为奇数,则P
=
1;若累加器A中1的个数为偶数,则P
=
0。
Ⅳ 求单片机片内固定的P1.0等等的地址。。 P1 是0x90~97 P2是0xa0~a7 P3.......
如果你用keil 的话,一般主程序都会有 “#include <regx52.h>”, 打开这个文件就有你想要的内容,下图更直观一点
附 REG52.H 内容
/*--------------------------------------------------------------------------
REG52.H
Header file for generic 80C52 and 80C32 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
#ifndef __REG52_H__
#define __REG52_H__
/* BYTE Registers */
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
sfr B = 0xF0;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr IE = 0xA8;
sfr IP = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;
/* 8052 Extensions */
sfr T2CON = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC;
sfr TH2 = 0xCD;
/* BIT Registers */
/* PSW */
sbit CY = PSW^7;
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit P = PSW^0; //8052 only
/* TCON */
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;
/* IE */
sbit EA = IE^7;
sbit ET2 = IE^5; //8052 only
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;
/* IP */
sbit PT2 = IP^5;
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX0 = IP^0;
/* P3 */
sbit RD = P3^7;
sbit WR = P3^6;
sbit T1 = P3^5;
sbit T0 = P3^4;
sbit INT1 = P3^3;
sbit INT0 = P3^2;
sbit TXD = P3^1;
sbit RXD = P3^0;
/* SCON */
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;
/* P1 */
sbit T2EX = P1^1; // 8052 only
sbit T2 = P1^0; // 8052 only
/* T2CON */
sbit TF2 = T2CON^7;
sbit EXF2 = T2CON^6;
sbit RCLK = T2CON^5;
sbit TCLK = T2CON^4;
sbit EXEN2 = T2CON^3;
sbit TR2 = T2CON^2;
sbit C_T2 = T2CON^1;
sbit CP_RL2 = T2CON^0;
#endif
Ⅳ 51单片机F0字节地址后面存的是什么
51单片机高128字节地址80H~FFH分配给特殊功能寄存器,但因为并没有128个寄存器,所以,有很多地址是空的,什么也没有。见下表,寄存器B的字节地址是F0H,再大的地址F1H~FFH就全部是空的,什么也不存,什么也不是。
Ⅵ 单片机c51的按键0~f的代码
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar key;
unsigned char code disp_code[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code key_code[]={
0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,
0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77 };
/**********************************************************
延时子函数
**********************************************************/
void delayms(uint ms)
{
uchar t;
while(ms--)
{
for(t = 0; t < 120; t++);
}
}
/**********************************************************
键盘扫描子函数
**********************************************************/
uchar keyscan()
{
uchar scan1,scan2,keycode,j;
P3=0xf0;
scan1=P3;
if((scan1&0xf0)!=0xf0) //判键是否按下
{
delayms(30); //延时30ms
scan1=P3;
if((scan1&0xf0)!=0xf0) //二次判键是否按下
{
P3=0x0f;
scan2=P3;
keycode=scan1|scan2; //组合成键编码
for(j=0;j<=15;j++)
{
if(keycode== key_code[j]) //查表得键值
{
key=j;
return(key);
}
}
}
}
else P3=0xff;
return (16);
}
/**********************************************************
判键是否按下子函数
**********************************************************/
void keydown()
{
P3=0x0f;
if((P3&0x0f)!=0x0f)
{
keyscan();
P0=disp_code[key];
beep();
}
}
/**********************************************************
主函数
**********************************************************/
main()
{
P0 = 0xbf;
P2 = 0x7f; //数码管显示"-"
P3 = 0xff;
while(1)
{
keydown();
}
}