从单片机基础到程序框架(全集 2019pdf版).pdf - 第778页

for(;u32 DelayTime>0 ;u32DelayT ime--); } void Perip heralInit ial(void) { } void BeepO pen(void) { P3_4=0; } void BeepC lose(void ) { P3_4=1; } void Voice Scan(void ) { static u nsigned cha r Su8Lock= 0; if(1==vGu8 B…

100%1 / 836
{
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)
{
}
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();
}
}
}
}
第一百三十一节: 灵活切换各种不同大小“接收内存”的串口程序框架。
【131.1 切换各种不同大小“接收内存”
很多 32 位的单片机,只要外挂 SRAM 或者 SDRAM 这类内存芯片,就可以轻松的把一个全局变量的数组开
辟到几百 K 甚至几兆的容量开辟这么大的数组,往往是用来处理一些文件类的大数据比如串口接收一
480x272 点阵大小的.BMP 格式的图片文件就需要开辟一个几百 K 的全局变量大数组串口通信中,从接收
内存的容量来划分,常用有两种数据类型,一种是常规控制类(容量小)一种是文件类(容量大),要能做
到在这两种“接收内存”中灵活切换,关键是用到“指针的中转切换”技术
“常规控制类内存”负责两块事务一块是接收“前部分的”[数据头,数据类型,数据长度],另一块
是“后部分的”[常规控制类的专用数据]。
“文件类内存”只负责“后部分的[文件类的专用数据],而“前部分的”[数据头,数据类型,数据
长度]是需要借助“常规控制类内存”来实现的。
本节破题的关键在于,根据不同的数据类型,利用“指针的中转切换”实现不同接收内存的灵活切换。
关键代码是串口中断函数这部分的处理,片段代码的讲解如下:
unsigned char Gu8ReceBuffer[20]; //常规控制类的小内存
unsigned char Gu8FileBuffer[40]; //文件类的大内存
unsigned char *pGu8ReceBuffer; //用来切换接收内存的“中转指针”
unsigned long Gu32ReceCntMax=20; //最大缓存(初始值 20 或者 40 都没关系,因为后续会动态改变)
void usart(void) interrupt 4
{
if(1==RI)
{
RI = 0;
if(0==Gu8FinishFlag)
{
Gu8ReceFeedDog=1;
switch(Gu8ReceStep)
{
case 0: //“前部分的”数据头。接头暗号的步骤
Gu8ReceBuffer[0]=SBUF;
if(0xeb==Gu8ReceBuffer[0])
{
Gu32ReceCnt=1;
Gu8ReceStep=1;
}
break;
case 1: //“前部分的”数据类型和长度
Gu8ReceBuffer[Gu32ReceCnt]=SBUF;