51单片机——串口通信详解(STC89C51为例)_佛科院深夜学习的博客-CSDN博客
(1)波特率与SMOD无关
(2)波特率等于溢出率除4
(1)T2R:控制定时器2是否允许使用,置“1”为允许
(2)T2_C/T:控制定时器2用作定时器还是计数器,置“0”为定时器(默认)
(3)T2X12:控制定时器2速度,置“0”为12T模式(传统模式);置“1”为1T模式
(4)S1ST2:串口1定时器选择位,置“0”选择定时器1;置“1”选择定时器2(默认)
(1)串口1可以使用定时器1、定时器2为波特率发生器
(2)定时器2默认为16位自动重装载模式
(3)定时器2的时间常数保存在T2H、T2L
假设我们使用的是1T模式,溢出一次需要的时间 = (65536 - 初值)*(1/晶振频率),即
溢出率 = 1/溢出一次需要的时间 = 晶振频率/(65536 - 初值)
波特率 = 溢出率/4 =晶振频率/(65536 - 初值)/4
初值 = 65536 - 晶振频率/(波特率*4)(误差的绝对值要小于3%)
先配置并开启定时器2,然后配置并开启串口1,最后实现数据的收发。
STC-ISP中的IRC频率需要设置为12MHZ
// 使用程序前,将J13调整为IO模式(2-3脚短接)
#include "Public.h"
u8 R_sign;
u8 R_dat;
void Uart_1_TX(u8 dat);
void Uart_1_Init();
// 主函数
void main(void)
{
Close_All();
Uart_1_Init();
Uart_1_TX(0x5a);
Uart_1_TX(0xa5);
while(1)
{
if(R_sign)
{
Uart_1_TX(R_dat+1);
R_sign = 0;
}
}
}
/*****************串口**********************/
/*
输入变量:无
输出变量:无
功能:配置并开启定时器2和串口2
*/
void Uart_1_Init() //9600bps@12MHz
{
//使用了SCON、AUXR、IE、T2H、T2L寄存器
//方式1 8位数据 波特率可变
SM0 = 0;
SM1 = 1;
//定时器2速度为1T模式
AUXR |= 0x01<<2;
//串口1选择使用定时器2
AUXR |= 0x01<<0;
//定时器初值
T2L = 0xC7;
T2H = 0xFE;
//允许串口接受
REN = 1;
//开启串口中断
ES = 1;
//开启总中断
EA = 1;
//开启定时器2
AUXR |= 0x01<<4;
}
/*
输入变量:发送的八位数据
输出变量:无
功能:使用串口1发送8位数据
*/
void Uart_1_TX(u8 S_dat)
{
SBUF = S_dat;
while(!TI);
TI = 0;
}
void Uart_1_IT() interrupt 4
{
if(RI)
{
R_dat = SBUF;
RI = 0;
R_sign = 1;
}
}
首先将无关设备关闭,然后配置并打开串口,编写发送字符串代码(记得回车换行),接着编写控制函数和读取函数
// 使用程序前,将J13调整为IO模式(2-3脚短接)
#include "Public.h"
u8 R_sign;
u8 R_dat;
u8 last_led = 0xff;
void Uart_1_TX_String(u8 *S_dat);
void Uart_1_Init();
void LED_ON_Low(u8 dat);
void LED_ON_High(u8 dat);
// 主函数
void main(void)
{
Close_All();
Uart_1_Init();
Uart_1_TX_String("Welcome come to XMF system!\r\n");
while(1)
{
if(R_sign)
{
R_sign = 0;
switch(R_dat>>4)
{
case 0x0A:
LED_ON_Low(R_dat);
break;
case 0x0B:
LED_ON_High(R_dat);
break;
case 0x0C:
Uart_1_TX_String("The system is running!\r\n");
break;
}
}
}
}
/*****************串口**********************/
/*
输入变量:无
输出变量:无
功能:配置并开启定时器2和串口2
*/
void Uart_1_Init() //9600bps@12MHz
{
//使用了SCON、AUXR、IE、T2H、T2L寄存器
//方式1 8位数据 波特率可变
SM0 = 0;
SM1 = 1;
//定时器2速度为1T模式
AUXR |= 0x01<<2;
//定时器初值
T2L = 0xC7;
T2H = 0xFE;
//允许串口接受
REN = 1;
//开启串口中断
ES = 1;
//开启总中断
EA = 1;
//开启定时器2
AUXR |= 0x01<<4;
}
void Uart_1_IT() interrupt 4
{
if(RI)
{
R_dat = SBUF;
RI = 0;
R_sign = 1;
}
}
/*
输入变量:发送的字符串
输出变量:无
功能:使用串口1发送字符串
*/
void Uart_1_TX_String(u8 *S_dat)
{
while(*S_dat != '\0')
{
SBUF = *S_dat;
while(TI == 0);
TI = 0;
S_dat++;
}
}
/*********************LED******************/
/*
输入变量:低四位灯亮灭数据。‘1’表示开灯,‘0’关灯
输出变量:无
功能:控制前四个灯亮灭,保持后四个灯灭
注意:使用前要对u8 last_led = 0XFF;进行宏定义
*/
void LED_ON_Low(u8 dat)
{
//由于P0口是公用的口,我们要对每次点灯的数据进行记录,不然会受其他操作的影响
P0 = (last_led & 0xf0) | (~dat & 0x0f);
last_led = P0;
P2 = (P2 & 0x1f) | 0x80;
P2 &= 0x1f;
}
/*
输入变量:高四位灯亮灭数据。‘1’表示开灯,‘0’关灯
输出变量:无
功能:控制后面四个灯亮灭,保持前面四个灯灭
注意:使用前要对u8 last_led = 0XFF;进行宏定义
*/
void LED_ON_High(u8 dat)
{
//由于P0口是公用的口,我们要对每次点灯的数据进行记录,不然会受其他操作的影响
P0 = (last_led & 0x0f) | (~dat & 0x0f)<<4;
last_led = P0;
P2 = (P2 & 0x1f) | 0x80;
P2 &= 0x1f;
}
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时