从单片机基础到程序框架(全集 2019pdf版).pdf - 第825页
TMOD=0x01; TH0=0xfc; TL0=0x66; EA=1; ET0=1; TR0=1; //以下是串口 接收中断的配 置 //串口的波特 率与内置的定 时器 1 直接 相关,因此配 置此定时器 1 就等 效于配置波特 率。 u8_TMOD_Te mp=0x20; // 即将把定时 器 1 设置为:工 作方式 2,初值自动 重装的 8 位定 时器。 TMOD=TMOD& 0x0f; //此寄 存器低 4 位是 跟定时…

Su8KeyLock1=0; //按键解锁
Su16KeyCnt1=0; //按键去抖动延时计数器清零,此行非常巧妙,是全场的亮点。
}
else if(0==Su8KeyLock1)//有按键按下,且是第一次被按下。
{
Su16KeyCnt1++; //累加定时中断次数
if(Su16KeyCnt1>=KEY_FILTER_TIME) //滤波的“稳定时间”KEY_FILTER_TIME,长度是 25ms。
{
Su8KeyLock1=1; //按键的自锁,避免一直触发
vGu8KeySec=1; //触发 1 号键
}
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
if(1==vGu8BigBufferUsartTimerFlag&&vGu16BigBufferUsartTimerCnt>0) //过程控制的超时定时器
{
vGu16BigBufferUsartTimerCnt--;
}
if(1==vGu8QueueSendTimerFlag&&vGu16QueueSendTimerCnt>0) //队列发送的超时定时器
{
vGu16QueueSendTimerCnt--;
}
if(1==vGu8ReceTimeOutFlag&&vGu16ReceTimeOutCnt>0) //通讯过程中字节之间的超时定时器
{
vGu16ReceTimeOutCnt--;
}
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
unsigned char u8_TMOD_Temp=0;
//以下是定时器 0 的中断的配置

TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
//以下是串口接收中断的配置
//串口的波特率与内置的定时器 1 直接相关,因此配置此定时器 1 就等效于配置波特率。
u8_TMOD_Temp=0x20; //即将把定时器 1 设置为:工作方式 2,初值自动重装的 8 位定时器。
TMOD=TMOD&0x0f; //此寄存器低 4 位是跟定时器 0 相关,高 4 位是跟定时器 1 相关。先清零定时器 1。
TMOD=TMOD|u8_TMOD_Temp; //把高 4 位的定时器 1 填入 0x2,低 4 位的定时器 0 保持不变。
TH1=256-(11059200L/12/32/9600); //波特率为 9600。11059200 代表晶振 11.0592MHz,
TL1=256-(11059200L/12/32/9600); //L 代表 long 的长类型数据。根据芯片手册提供的计算公式。
TR1=1; //开启定时器 1
SM0=0;
SM1=1; //SM0 与 SM1 的设置:选择 10 位异步通讯,波特率根据定时器 1 可变
REN=1; //允许串口接收数据
//为了保证串口中断接收的数据不丢失,必须设置 IP = 0x10,相当于把串口中断设置为最高优先级,
//这个时候,串口中断可以打断任何其他的中断服务函数实现嵌套,
IP =0x10; //把串口中断设置为最高优先级,必须的。
ES=1; //允许串口中断
EA=1; //允许总中断
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
GtBigBufferUsart.u8Start=0; //通讯过程的启动变量必须初始化为 0!这一步很关键!
}
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)

{
P3_4=1;
}
void VoiceScan(void)
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
【134.8 例程的下位机程序。】
下位机作为从机应答上位机的指令,程序相对简化了很多。不需要“通讯过程的控制涵数”,直接在
“接收数据后的处理涵数”里启动“发送的队列驱动涵数”来发送应答的数据即可。发送应答数据后,也不
用等待上位机的应答数据。
#include "REG52.H"
#define RECE_TIME_OUT 2000 //通讯过程中字节之间的超时时间 2000ms
#define REC_BUFFER_SIZE 30 //常规控制类数组的长度
void usart(void); //串口接收的中断函数