本次笔记包括两个方面:
1.仅仅操控LED的亮灭,不回来数值
2.操控LED的亮灭,并回来数值
看了几讲的视频,都是在讲串口的办法1。其他的还没触摸,这儿也只用串口的办法1完成这两个功用。串口晒干需求核算的当地是依据所要运用的波特率求定时器的初始值。定时器运用的是办法2,能够主动装初始值,防止赋值查办装初始值时呈现夺冠。
以9800bps,定时器运用办法2,串口运用办法1,晶振波特率为 11.0592MHZ,求TH1跟TL1的值。
办法1的波特率 = (2^SMOD/32)xT1溢出率。单片机复位后,电源办理寄存器PCON悉数清零,SMOD作为其间一位天然也清零。
波特率现已知道了。这样就剩余T1溢出率了。
假定初值为X,则定时器每次计256-X个数溢出一次(定时器为8位,最大为255 。256时产生溢出)。每计一个数的时刻为一个机器周期,机器周期 = T时钟周期 X 12 。所以溢出的时刻为 = 个数X 每个时刻 = ( 256 – X) * 12/Fosc . 那么根底率便是溢出时刻的倒数。
所以结合公式“办法1的波特率 = (2^SMOD/32)xT1溢出率”,式子能够总结为:
9600 = 2^0 /32 * Fosc / (256 – X)*12 带入悉数已知数据得到 9600 = 2^0 /32 * 11059200/ (256 – X)*12 =====》》》》 求得的X为: 253 .
在此根底上,假如把SMOD 设为1 ,则 求得波特率为 :
波特率 = (2^1/32) * 11059200 / (256 – 253 ) = 2 * [ 1/32 * 11059200 / (256 – 253)] = 2 * 9600 = 19200 。即变为本来的两倍。
假如把晶振换成12MHZ再求初值,求得的X为: 252.744792…… 无量小数。这样就会产生夺冠。曾经一向感觉整数的晶振挺好,现在才知道为什么会有11.0592MHZ这种晶振的存在了,。
这样核算得到了初值,下面贴代码。
仅仅操控LED的亮灭,不回来数值
完成这个又分为查询和中止两种办法。
A。先用查询。感觉叫判别更好些,由于是用if判别来完成的
#includevoid main(){ //设置参数TMOD = 0x20; //设定定时器1的工作办法为办法2TH1 = 0xfd;TL1 = 0xfd; //装载TH1、TL1TR1 = 1; //发动定时器1REN = 1; //答应串行接纳位SM0 = 0;SM1 = 1; //设定串口工作办法为办法1/** EA = 1; //大局中止答应位* ES = 1; //串口中止答应位* 此处运用的是查询法判别接纳中止标志位,所以即使不舱位中止答应位,也能够**/while(1){ //查询法检测RIif(RI == 1)//RI为接纳中止标志位。硬件置为1,有必要软件清0{P1 = SBUF;RI = 0;} }}
B 中止法
#includevoid main(){ //设置参数TMOD = 0x20; //设定定时器1的工作办法为办法2TH1 = 0xfd;TL1 = 0xfd; //装载TH1、TL1TR1 = 1; //发动定时器1REN = 1; //答应串行接纳位SM0 = 0;SM1 = 1; //设定串口工作办法为办法1EA = 1; //大局中止答应位ES = 1; //串口中止答应位while(1) ; //等候中止的产生}//中止检测RIvoid ser() interrupt 4{P1 = SBUF;RI = 0;}
这两个除了代码,感觉便是是否舱位中止答应了。由于RI置为1是硬件主动碑文的。即使是不舱位中止答应位,照样能够用if进行判别。
上面这两个是单方向的,再来个双向的。
/**经过串口给下位机发送数据,并使之显现在P1口的流水灯上。*一起单片机回来接纳到的数据,显现在串口帮手上*/#includeunsigned char flag;void main(){ //设置参数TMOD = 0x20; //设定定时器1的工作办法为办法2TH1 = 0xfd;TL1 = 0xfd; //装载TH1、TL1TR1 = 1; //发动定时器1SM0 = 0;SM1 = 1; //设定串口工作办法为办法1REN = 1; //答应串行接纳位EA = 1; //大局中止答应位ES = 1; //串口中止答应位while(1){ /* 刚开始单片机缓冲寄存器为空,无数据能够显现* 先从串口接纳数据,再回来该数据* 在中止中接纳数据,一起将flag标志方位为1.阐明接纳到了数据* 若接纳到数据(flag == 1),阐明接纳到了;不然阐明未接纳到数据,不显现。持续判别flag数值*/if(flag == 1) { //发送数据ES = 0; //封闭串口中止,发送数据SBUF = P1; //数据写入SBUF寄存器while(!TI); //等候TI = 0;ES = 1; flag = 0;} }}void ser() interrupt 4{//接纳数据P1 = SBUF;flag = 1;RI = 0;}
主函数晒干那个flag = 0 。 必定不能少了。不然只需一小会儿的功用,串口帮手就卡了。。。。
这个比方里还有两条查办比较要害:
P1 = SBUF;//把SBUF寄存器中的数值赋给P1
SBUF = P1;//把P1的数值写入到SBUF
SBUF是这么写的:SBUF 串行数据缓冲寄存器,一个发送缓冲寄存器,一个接纳缓冲寄存器。两个共用一个地址99H,但在物理上是两个独立的寄存器。那么怎么委任是发送仍是接纳呢?就用查办来委任了。
操控流水灯的话,需求发送十六进制格局的。
比方发送FB(1111,1011)。在我的开发板上是L2灯亮。假如发送字符,就不太好操控了。假如用2中的例程,以字符办法发送“fb”,单片机回来串口帮手并用十六进制显现为“62” .这个,嗯,现在不会算 😛
没啥值得纪念的图片,仍是几个流水灯。不过此刻的流水灯,非彼时的流水灯。现在的流水灯,但是我从电脑上就能操控开发板上的了:D
仅仅不知道下次自己写个上位机是什么时分了,