📄 testcom.c
字号:
// 。将奇偶值P代替发送字节的bit7(奇偶位);若为奇校验,则将bit7求反;
// 。发送该字节;
//
// (1B、7D、0P、2S)1位起始位、7位数据位、0位奇偶位、2位停止位;
// 。将发送字节的bit7置1(停止位);
// 。发送该字节;
//
// (1B、8D、1P、1S)1位起始位、8位数据位、1位奇偶位、1位停止位;
// 。将发送的字节送入A,可以得到奇偶值P;
// 。将奇偶值P复制到TB8(奇偶位);若为奇校验,则将TB8求反;
// 。发送该字节;
//
// (1B、8D、0P、2S)1位起始位、8位数据位、0位奇偶位、2位停止位;
// 。将TB8置1(停止位);
// 。发送A;
//
// 数据接收(接收时可以忽略奇偶校验错误):
// (1B、8D、0P、1S)1位起始位、8位数据位、0位奇偶位、1位停止位;
// 。接收该字节
//
// (1B、7D、1P、1S)1位起始位、7位数据位、1位奇偶位、1位停止位;
// 。将接收的字节送入A,然后清零A.7,可以得到奇偶值P;
// 。接收字节的bit7和奇偶值P是否相同;若为奇校验,则将bit7求反;
// 。若相同,接收该字节;否则,丢弃改字节;
//
// (1B、7D、0P、2S)1位起始位、7位数据位、0位奇偶位、2位停止位;
// 。将接收字节的bit7清0(停止位);
// 。保存该字节;
//
// (1B、8D、1P、1S)1位起始位、8位数据位、1位奇偶位、1位停止位;
// 。将接收的字节送入A,可以得到奇偶值P;
// 。RB8(奇偶位)和奇偶值P是否相同;若为奇校验,则将RB8求反;
// 。若相同,接收该字节;否则,丢弃改字节;
//
// (1B、8D、0P、2S)1位起始位、8位数据位、0位奇偶位、2位停止位;
// 。若RB8(停止位)为1,则停止位收取;
// 。RB8为1,则接收字符;否则丢弃字符;
// 。也可以不管以上两个条件,直接接收字符。
// -----------------------------------------------------------------------------------
ULNG ulTemp = 0, ulTemp1 = 0;
EA = 0; // 禁止中断
REN = 0; // 停止接收
// ===============================================
// TMOD: 定时器工作方式控制寄存器,复位后TMOD = 0x00
// ===============================================
// D7 D6 D5 D4 D3 D2 D1 D0
// -------------------+---------------------------
// GATE C//T M1 M0 | GATE C//T M1 M0
// -------------------+---------------------------
// ------ 定时器1 -----+--- 定时器0 ---------------
// M1、M0:工作方式设置;
// 00-13位计数器;
// 01-16位计数器;
// 10-可自动再装入的8位计数器(从THx中自动装到TLx中);
// 11-把定时器分为两个8为的计数器或关闭定时器1;
// C//T:1-计数器功能,0-定时器功能;
// GATE:选通控制;1-同时/INTx为高电平且TRx为1时选通定时器x;
// 0-每当TRx为1时就选通定时器x;
// -----------------------------------------------------
TMOD = TMOD & 0x0F;
TMOD = TMOD | 0x20;
// 计算波特率
// ----------
// bTHL = 256 - (SMOD ? 2:1) * fosc / 384 / baudrate;
// fosc / 384 / baudrate 部分是否为零?
// 为了说明波特率太高,或者晶振频率太低。
ulTemp1 = cnFosc / 384;
ulTemp = ulTemp1 / cnBaudRate;
if (ulTemp) // 晶振频率够高
{
// 波特率不是(2^n);则应定时器初值*2,并倍频;如38400时ulTemp=1.5
if (cnBaudRate * ulTemp != ulTemp1)
{
PCON = PCON | 0x80;
// ulTemp = cnFosc / 384;
// ulTemp = 2 * ulTemp / cnBaudRate;
ulTemp = cnFosc / 192;
ulTemp = ulTemp / cnBaudRate;
}
else
PCON = PCON & 0x7F;
}
else
{
// 说明晶振太低,应倍频
PCON = PCON | 0x80;
ulTemp = 1;
}
// 定时器1计数初值
TH1 = 256 - ulTemp;
TL1 = TH1;
SM0 = 0; SM1 = 1; SM2 = 0; // 异步收发,定时器控制;8位数据的异步工作方式;收到字符RI就置1;
// ======================================================
// TCON:定时器/计数器控制寄存器;复位后:TCON = 0x00
// ======================================================
// D7 D6 D5 D4 D3 D2 D1 D0
// --------------------------------------------------------
// TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
// --------------------------------------------------------
// TF1,TF0:定时器x溢出中断标志,当定时器x溢出时由内部硬件至置位,
// 当CPU转向中断服务程序时,由内部硬件清除;
// TR1,TR0:定时器运行控制位,由软件置位、清除来控制定时器开启、关闭;
// IE1,IE0:外部触发中断请求标志;
// IT1,IT0:外部中断触发方式,1-下降沿触发;0-低电平触发;
// --------------------------------------------------------
TR1 = 1; // 开启定时器1
EA = 1; // 开放中断
REN = 1; // 允许接收
}
// T0中断服务程序: 100us中断一次
void timer0() interrupt 1 /* 1 0x0B Timer 0 */
{
ucMsCount ++; // 用于1ms计时
if (ucMsCount >= 10)
{
ucMsCount = 0;
uiMsNow ++; // 当前毫秒数(受GPS脉冲控制)
if ((uiMsNow % 250) == 0)
b250MsPassed = 1; // 已经过了250毫秒, LED-RUN
if (uiMsNow >= 1000)
{
uiMsNow = 0;
bOneSecPassed = 1; // 已经过了1秒
ucSecCount ++; // 用于1s计时(受GPS脉冲控制)
if (ucSecCount >= 60)
{
ucSecCount = 0; // 用于1s计时(受GPS脉冲控制)
bOneMinPassed = 1; // 每分钟,重新初始化一次串口,以提高可靠性
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
// 以下为串口访问子程序
// -----------------------------------------------------------------------------
// 设计思想:
// 1、接收和发送均采用中断完成;
// 2、接收中断由RI自动完成;串口每收到完整的1个字节时自动将RI置1;
// 3、发送中断由TI和bComSendBufEmpty配合完成;串口每发送完成1个字节时自动将TI置1;
// 因此,当首次发送时应由程序控制将TI置为1;即,首次使用时因bComSendBufEmpty为0,
// 发送字节时程序将TI置1,强制执行串口中断服务程序,以检查是否需要发送和接收串口
// 信息;
/////////////////////////////////////////////////////////////////////////////////
bit bRecv = 0;
BYTE ucChar;
// 串口中断服务程序
void serial(void) interrupt 4 /* 4 0x23 Serial port */
{
if (TI) // 发送中断有效,可以发送
{
TI = 0; // 复位中断标志
if (bRecv)
{
SBUF = ucChar;
bRecv = 0;
}
}
if (RI)
{
// 接收中断有效,接收数据
RI = 0; // 复位中断标志
bRecv = 1;
ucChar = SBUF; // 接收一个字节
TI = 1; // 置位中断标志
}
}
main()
{
ucMsCount = 0; // 用于1ms计时
uiMsNow = 0; // 当前毫秒数(受GPS脉冲控制)
b250MsPassed = 0; // 已经过了250毫秒, LED-RUN
bOneSecPassed = 0; // 已经过了1秒
ucSecCount = 0; // 用于1s计时(受GPS脉冲控制)
bOneMinPassed = 0; // 每分钟,重新初始化一次串口,以提高可靠性
bCSX = 0; // 看门狗清零
vInterruptInitialize(); // 中断初始化
vSerialInitialize(); // 串口初始化
do
{
if (b250MsPassed)
{
b250MsPassed = 0; // 已经过了250毫秒, LED-RUN
bCSX = ~bCSX; // 看门狗清零;
} // if (b250MsPassed)
} while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -