第十一章 UART原理和应用_第1页
第十一章 UART原理和应用_第2页
第十一章 UART原理和应用_第3页
第十一章 UART原理和应用_第4页
第十一章 UART原理和应用_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第十一章UART原理和应用何宾2023.09设计实例一:串口重定位的设计与实现串口重定位技术是嵌入式系统应用中经典的设计案例,本节将详细介绍串口重定位的实现方法串口重定位的目标是将C语言中的输入函数scanf()和输出函数printf()重新定位到到串口上,即把串口作为scanf()函数的输入设备,以及将串口作为printf()函数的输出设备设计实例一:串口重定位的设计与实现

--串口重定位的背景很多读者在学习单片机课程之前就已经学习过C语言程序设计课程在学习C语言程序设计时,大家知道C语言提供了输入和输出函数语句,比如scanf()和printf()在PC/笔记本电脑上,调用输入和输出语句时,键盘作为scanf()函数的输入设备,屏幕作为printf()函数的输出设备设计实例一:串口重定位的设计与实现

--串口重定位的背景但是在嵌入式系统中,尤其是在由单片机构成的嵌入式系统中,并没有像PC/笔记本电脑上的键盘和屏幕,那如何使用scanf()函数和printf()函数呢?这就成为一个非常棘手的问题但是,在由单片机构成的嵌入式硬件系统中,串口是最基本的外设,那么能不能让串口充当输入/输出语句的输入/输出设备呢?答案是肯定的要想实现这个目标,就需要对scanf()函数和printf()函数的底层输入和输出进行修改,使得通过串口接收到的数据可以作为scanf()函数的底层输入,通过串口发送的数据可以作为printf()函数的底层输出设计实例一:串口重定位的设计与实现

--串口重定位的背景在这里需要指出,当嵌入式系统使用的处理器的指令集架构和编译环境不同时,串口的输入和输出所使用的代码是不通用的此时,读者可以重新阅读教材第8章8.11.1一节的内容,其中在表8.12中对PUTCHAR.C有这样的描述即程序开发人员可以根据自己的硬件(例如LCD或LED显示器)修改这个程序默认是通过串口输出字符对GETKEY.C有这样的描述即程序开发人员可以根据自己的硬件(例如矩阵键盘)修改该程序。默认是通过串口读取字符设计实例一:串口重定位的设计与实现

--添加type.h文件#ifndef__TYPE_H_//如果没有定义__TYPE_H_#define__TYPE_H_//定义__TYPE_H_

#include"stdio.h"//包含头文件stdio.h#include"stc32g.h"//包含头文件stc32g.htypedef unsignedcharu8;//自定义无符号字符类型u8typedef unsignedint u16;//自定义无符号整数类型u16typedef unsignedlongu32;//自定义无符号长整数类型u32#defineMAIN_Fosc22118400L//定义IRC主时钟频率22118400Hz

#endif//结束设计实例一:串口重定位的设计与实现

--添加uart.h文件#ifndef__UART1_H_//如果没有定义__UART1_H_#define__UART1_H_//定义__UART1_H_#include"type.h"//包含头文件type.h

#defineBaudrate2115200L//定义波特率常数115200

voidUART1_init();//定义函数UART1_INIT()charputchar(charc);//重定位函数putchar()char_getkey();//重定位函数_getkey()voidMCU_init();//定义函数MCU_init()#endif//结束设计实例一:串口重定位的设计与实现

--添加uart.c文件#include"uart.h"//包含头文件uart.h

voidUART1_init()//UART1_INIT()初始化函数{u16dat;//定义u16类型的变量dat/**********计算定时器的重加载值************/ dat=(u16)(65536UL-(MAIN_Fosc/4)/Baudrate2);T2R=0; //禁止定时器运行T2_CT=0; //定时器/计数器2作为定时器T2x12=1; //定时器/计数器2在IT模式T2H=(u8)(dat/256);//重加载值高8位保存到寄存器T2H

设计实例一:串口重定位的设计与实现

--添加uart.c文件T2L=(u8)(dat%256);//重加载值低8位保存到寄存器T2LET2=0;//禁止timer2中断T2R=1; //使能定时器运行 SCON=(SCON&0x3f)|0x40;//8位数据,可变波特率REN=1;//允许接收P_SW1&=0x3f;//端口选择}设计实例一:串口重定位的设计与实现

--添加uart.c文件charputchar(charc)//底层putchar()函数重定位{SBUF=c;//字符c写到寄存器SBUFwhile(TI!=1);//等待发送完成

TI=0;//发送完成,TI清零 returnc;//返回字符c}设计实例一:串口重定位的设计与实现

--添加uart.c文件char_getkey()//底层_getkey()重定位{ charvalue;//定义字符型变量valuewhile(RI!=1);//等待串口完成接收 RI=0;//完成接收清零RI value=SBUF;//从寄存器SBUF读取接收的数据value returnvalue;//返回读取的数据value}设计实例一:串口重定位的设计与实现

--添加uart.c文件voidMCU_init()//定义MCU_init()函数{ WTST=0;//将CPU执行指令的速度设置为最快EAXFR=1;//使能访问扩展寄存器(XSFR)CKCON=0;//提高访问XRAM速度P0M1=0x00;P0M0=0x00;//端口P0设置为准双向口P1M1=0x00;P1M0=0x00;//端口P1设置为准双向口P2M1=0x00;P2M0=0x00;//端口P2设置为准双向口P3M1=0x00;P3M0=0x00;//端口P3设置为准双向口P4M1=0x00;P4M0=0x00;//端口P4设置为准双向口

设计实例一:串口重定位的设计与实现

--添加uart.c文件P5M1=0x00;P5M0=0x00;//端口P5设置为准双向口P6M1=0x00;P6M0=0x00;//端口P6设置为准双向口P7M1=0x00;P7M0=0x00;//端口P7设置为准双向口}设计实例一:串口重定位的设计与实现

--添加main.c文件#include"stc32g.h"//头文件stc32g.h包含寄存器定义#include"uart.h"//包含头文件uart.h

voidmain()//定义main主函数{ inta,b;//定义两个整型变量a和b intsum;//定义一个整型变量sum MCU_init();//调用函数MCU_init() UART1_init();//调用函数UART1_init();设计实例一:串口重定位的设计与实现

--添加main.c文件while(1)//while()循环 { printf("pleaseinputtwonumber\r\n");//调用printf函数,打印信息 scanf("%d%d",&a,&b);//调用scanf函数,输入a和b的值 sum=a+b;//a+b的结果赋值给sum printf("\r\n");//调用printf函数,回车换行 printf("%d+%d=%d\r\n",a,b,sum);//调用printf函数,打印信息 }}设计实例一:串口重定位的设计与实现

--串口工具的使用当把程序下载到STC32G12K128单片机内的程序存储器后,读者就可以使用STC-ISP软件中提供的串口调试助手对该程序进行调试和验证,主要步骤包括:去掉用于连接STC32G系列单片机硬件开发平台和PC笔记本电脑的USB电缆按下图所示,通过STC提供的SWD白色电缆,将STC公司提供的STCUSBLink1D硬件工具与STC32G系列单片机硬件开发平台上的LNK1接口连接在一起。并且,通过带有TYPE-C接口的USB电缆,将STCUSBLink1D硬件工具连接到PC/笔记本电脑的USB接口设计实例一:串口重定位的设计与实现

--串口工具的使用设计实例一:串口重定位的设计与实现

--串口工具的使用在STC-ISP软件左侧窗口的“扫描串

口”标题右侧的下拉框中自动弹出STC-USBLink1(LNK1)条项。

此时,展开下拉框,可以看到下拉框

中出现STC-USBLinkID(CDC1)

(COM4)的条项,也就是虚拟出串

口号COM4,要记住该串口号!!!设计实例一:串口重定位的设计与实现

--串口工具的使用在STC-ISP软件的右侧窗口中,单击”USB-CDC/串口助手“标签”,在该标签界面下,按如下设置参数:设计实例一:串口重定位的设计与实现

--串口工具的使用接收缓冲区子窗口中显示“pleaseinputtwonumbe”信息。在发送缓冲区的右侧窗口中,通过PC/笔记本电脑上的按键输入两个整数,比如35和66,两个整数之间需要有空格,并通过按下/释放Enter按键输入回车换行符设计实例二:红外遥控器解码的实现基于红外线的无线通信也是串行通信的一种,但是比前面所介绍的RS-232通信更复杂,这是因为基于红外线的无线通信使用了调制和解调技术本节将通过STC32G系列单片机硬件开发平台上的红外接收器,接收遥控器发出的红外遥控信号,并通过STC32G12K128单片机对接收到的红外遥控信号进行解码,并通过串口1将解码后的信息显示在STC-ISP软件提供的“串口调试助手”标签界面中设计实例二:红外遥控器解码的实现

--红外接收器电路在STC提供的硬件开发平台上集成了一个红外发生器和红外接收器红外发射器和我们所见过的发光二极管外形很像,但是红外发射器发出的光是不可见的红外光红外接收器和红外发射器的电路原理,本节仅对红外接收电路进行介绍设计实例二:红外遥控器解码的实现

--红外接收器电路(a)红外接收电路(b)红外发射电路设计实例二:红外遥控器解码的实现

--红外接收器电路在上图给出的红外接收电路中,使用了HS0038BD红外接收器模块,外观如下所示;基于该模块构成的电路实物,如下所示在该设计中选择R1=100Ω,C1=10μF红外接收模块外观(b)红外接收电路结构IR接收器电路设计实例二:红外遥控器解码的实现

--红外接收器电路HS0038BD的内部结构HS0038BD是用于红外遥控系统的小型接收器。PIN二极管和前置放大器组装在引线框架上,环氧树脂封装用作IR滤镜解调后的输出信号可以由STC32G12K128MCU直接解码设计实例二:红外遥控器解码的实现

--红外接收器电路HS0038BD与所有常见的IR遥控数据格式兼容,并且可以抑制来自节能荧光灯的几乎所有杂散脉冲PIN型二极管这是在P区和N区之间夹一层本征半导体(或低浓度杂质的半导体)构造的晶体二极管设计实例二:红外遥控器解码的实现

--红外接收器电路红外接收模块的输入和输出特性设计实例二:红外遥控器解码的实现

--红外信号的捕获为了方便读者学习下面一节红外通信协议,本节通过测试仪器捕获并分析红外通信信号的波形通过USB电缆,将STC32G系列单片机硬件开发平台的USB接口连接到PC/笔记本电脑的USB接口打开泰克的MDO3104混合域示波器(并安装逻辑分析模块)。将示波器通道1探头正端连接到开发板扩展I/O的P3.5引脚,负端连接到开发板扩展I/O的GND引脚找一个用于控制家里电视用的遥控器。将遥控器对准红外接收器,并按下红外遥控器的按键。同时,让示波器捕获波形设计实例二:红外遥控器解码的实现

--红外接收器电路为了使读者能更清楚地看到波形,将波形前部进行放大设计实例二:红外遥控器解码的实现

--红外信号的捕获将示波器切换到逻辑分析状态,将该示波器提供的逻辑分析插头的D0连接到开发板扩展I/O的P3.5引脚,地线连接到开发板扩展I/O的GND引脚设计实例二:红外遥控器解码的实现

--红外信号的捕获当重复按下遥控器的某个按键时设计实例二:红外遥控器解码的实现

--红外通信协议本节将介绍红外通信协议,包括:在红外发射器一侧,为了使红外线在无线传输的过程中避免受到其他红外信号的干扰,通常是将逻辑“0”(低电平)和逻辑“1”(高电平)调制在某一特定频率的载波上,然后经过红外发光二极管发射出去在红外接收器一侧,接收到这个被调制后的信号。在本设计中,将通过单片机中对接收到的红外信号进行分析,恢复出原始的二进制脉冲码设计实例二:红外遥控器解码的实现

--红外通信协议常用的有脉冲宽度调制(PulseWidthModulation,PWM)和通脉冲位置调制(PulsePositionModulation,PPM)两种方法红外遥控中使用的基带通信协议的类型很多,大概有几十种,常用的就有ITT协议、NEC协议、Sharp协议、Philips协议等注:本节只介绍NEC红外协议。对于其他红外通信协议,读者可以参考相关的协议手册红外通信协议

--红外发射数据载波波形可以使用455KHz晶体,经内部分频电路的12分频,将信号调制在37.91kHz,占空比为1/3红外通信协议

--红外发射数据数据格式数据格式包括了引导码、用户码、数据码和数据码反码。数据反码是数据码取反后的编码,编码时可用于对数据的纠错数据格式包括了引导码、地址码、地址反码、命令码和命令反码。地址反码是地址码按位取反后的编码,编码时可用于对数据的纠错。类似的,命令反码是命令码按位取反后的编码在该数据格式中,编码(包括8位地址码、8位地址反码、8位命令码和8位命令反码)长度总共32位。引导码的前半部分为高电平,时长大约为9ms;后半部分为空闲低电平,时长大约为4.5ms红外通信协议

--红外发射数据位定义用户码或数据码中的每一个二进制位可以是“1”,也可以是“0”,通过脉冲的时间间隔来区分它们。因此,这种编码方式称为PPM调制方式对于逻辑“0”(低电平)来说,前面的高电平周期为0.56ms,后面的低电平周期大约为0.56ms的空闲时刻对于逻辑“1“(高电平)来说,前面的高电平周期为0.56ms,后面的低电平周期大约为1.68ms的空闲时刻红外通信协议

--红外发射数据根据上面逻辑“0“和逻辑”1’’的表示方法,可知:8位地址码和8位命令反码的总时间恒定为(1.125ms+2.25ms)×8=27ms8位命令码和8位命令反码的总时间恒定为(1.125ms+2.25ms)×8=27ms

所有32位码的持续时间为27+27=54ms当加上引导码时,总的持续时间为54+9+4.5=67.5ms红外通信协议

--红外发射数据按键输出波形重复码单一按键波形红外通信协议

--红外发射数据连续按键波形红外通信协议

--红外接收数据红外接收模块将38K载波信号过滤,接收到的波形刚好与发射波形相反,波形与图11.20输出的波形一致前导码以低电平开始,持续9ms;然后维持4.5ms的高电平解码的关键是识别逻辑“0”(低电平)和逻辑“1”(高电平)在红外接收模块输出信号时,逻辑“0”和逻辑“1”均以0.56ms的低电平开始,不同的是两者高电平的脉冲宽度不同对于逻辑“0”(低电平)来说,只持续0.56ms的高电平对于逻辑“1”(高电平)来说,持续1.68ms的高电平设计实例二:红外遥控器解码的实现

--红外检测原理红外检测的目的就是从红外接收模块输出的逻辑“0”和逻辑“1”(低电平和高电平)信号中提取四个字节(32位)的数据,包括:一个字节(8位)的地址码一个字节(8位)的地址反码一个字节(8位)的命令码一个字节(8位)的命令反码红外检测原理

--I/O引脚的中断触发功能从前面给出的红外接收电路硬件可知,红外接收模块的输出端接到了STC32G12K128单片机的P3.5引脚在STC32G12K128单片机中,每个I/O引脚都具有中断触发功能,但是P3.5引脚的中断触发编号已经超过了KeilμVision允许的中断编号当在KeilμVision集成开发环境中使用C语言编写中断服务程序/中断句柄时,当中断号大于31时,编译程序就会报错红外检测原理

--I/O引脚的中断触发功能当使用C语言编写中断服务程序/中断句柄时,中断号13为保留的中断号,因此可以借用该中断号。主要步骤包括:在使用C语言编写中断服务程序/中断句柄时,用interrupt13指定该中断服务程序/中断句柄新建一个汇编语言文件(如isr.asm),并将该文件添加到当前的工程中。在该文件中添加汇编语言代码,如下面的代码所示红外检测原理

--I/O引脚的中断触发功能;定位到程序存储器地址为0x143的位置,这是端口P3的中断向量 CSEG AT0143H JMP P3INT_ISR;在0x143的位置保存一条跳转指令,跳转到P3INT_ISRP3INT_ISR:;跳转标号 JMP 006BH;在P3INT_ISR的位置保存着一条跳转指令,跳转到0x6B END;0x6B是保存中断号13的中断入口红外检测原理

--与P3端口中断有关的寄存器在STC32G系列单片机中,为端口P0到端口P7分别提供了端口中断使能寄存器、端口中断标志寄存器和端口中断模式配置寄存器,这些寄存器位于XSFR的区域本节仅介绍与P3端口中断有关的寄存器,关于其他端口与中断有关的寄存器请参考STC32G系列单片机技术参考手册第12.4一节内容与P3端口中断有关的寄存器

--P3端口中断使能寄存器(P3INTE)该寄存器位于XSFR地址为0x7EFD03的位置。当复位后,该寄存器的值为“00000000”当P3xINTE(x为位索引号)为“0”时,禁止P3.x引脚的中断功能;当P3xINTE(x为位索引号)为“1”时,使能P3.x引脚的中断功能位索引76543210名字P37INTEP36INTEP35INTEP34INTEP33INTEP32INTEP31INTEP30INTE与P3端口中断有关的寄存器

--P3端口中断标志寄存器(P3INTF)该寄存器位于XSFR地址为0x7EFD13的位置。当复位后,该寄存器的值为“00000000”当P3xINTF(x为位索引号)为“0”时,P3.x引脚上无中断请求;当P3xINTF(x为位索引号)为“1”时,P3.x引脚上有中断请求如果使能中断,则会进入中断服务程序/中断句柄。该位需要软件清零位索引76543210名字P37INTFP36INTFP35INTFP34INTFP33INTFP32INTFP31INTFP30INTF与P3端口中断有关的寄存器

--P3端口中断模式配置寄存器P3端口中断模式配置寄存器由一对寄存器P3IM0和P3IM1构成P3端口中断模式配置寄存器P3IM0该寄存器位于XSFR地址为0x7EFD23的位置。当复位后,该寄存器的值为“00000000”P3端口中断模式配置寄存器P3IM1寄存器该寄存器位于XSFR地址为0x7EFD33的位置。当复位后,该寄存器的值为“00000000”位索引76543210名字P37IM0P36IM0P35IM0P34IM0P33IM0P32IM0P31IM0P30IM0位索引76543210名字P37IM1P36IM1P35IM1P34IM1P33IM1P32IM1P31IM1P30IM1与P3端口中断有关的寄存器

--P3端口中断模式配置寄存器P3xM1和P3xM0(x为位索引号)组合的含义P3xM1P3xM0中断触发方式00下降沿中断01上升沿中断10低电平中断11高电平中断红外检测原理

--获取32位数据信息的方法该设计中,码型特征很明显对于单个按键来说,只要区分引导码,逻辑“0”(低电平)和逻辑“1”(高电平)它们的持续时间显著不同。因此,可以考虑使用定时器通过判断时间的边界来区分它们在该设计中,使用定时器/计数器0的模式1(自动16位重加载模式)红外传输信息的检测在P3.5引脚中断服务程序/中断句柄中实现红外检测原理

--获取32位数据信息的方法在该流程图中,给出了在P3.5

引脚中断服务程序/中断句柄中

处理红外传输信息的过程当通过STC-ISP软件将程序下载

到STC32G12K128单片机内的

程序存储器时,将IRC的频率设

置为6.000MHz。红外检测原理

--获取32位数据信息的方法在使用C语言编写代码的过程中,一个关键点就是设置判决条件/门槛在该设计中,使用的定时器/计数器0作为判决计数条件当引脚P3.5输入为逻辑“0”(低电平)时,重新使能定时器/计数器0开始计数,以得到低电平的持续时间当引脚P3.5输入为逻辑“1”(高电平)时,重新使能定时器/计数器0开始计数,以得到高电平的持续时间红外检测原理

--获取32位数据信息的方法在该设计中,设置定时器/计数器0的时钟源为SYSclk/12,在每个时钟沿定时器/计数器0加1。按下面公式计算高电平/低电平的持续时间,即:

时间长度=(12×SYSclk)/计数值[TH0*256+TL0]在设计中,考虑时钟的偏移和抖动,将时间长度设置在一个合理的范围内综上所述,最终门限是通过确定时间长度范围后,通过上面公式得到计数值的范围来作为实际的判断条件设计实例二:红外遥控器解码的实现

--修改type.h文件修改type.h文件中的代码#defineFOSC6000000L//定义单片机IRC频率6000000设计实例二:红外遥控器解码的实现

--添加ISR.asm文件CSEG AT0143H;定位到程序存储器的地址0x143 JMP P3INT_ISR;跳转到标号P3INT_ISR的位置P3INT_ISR:;标号P3INT_ISR JMP 006BH;跳转到0x6B的位置 END;结束设计实例二:红外遥控器解码的实现

--修改main.c文件#include"serial.h"//包含自定义的头文件register.h

/*****声明数组irdata,保存红外解码的4字节数据*********/unsignedcharirdata[4]={0,0,0,0}; bitflag=0; //声明flag变量为bitu16high_level_time()//声明检测红外发送数据的高电平持续时间函数{ TL0=0;//置定时器/计数器0初值低8位寄存器TL0为0 TH0=0;//置定时器/计数器0初值高8位寄存器TH0为0 TR0=1;//使能定时器/计数器0开始计数设计实例二:红外遥控器解码的实现

--修改main.c文件while(P35==1)//如果P3.5输入为“1”,一直继续,否则退出 { if(TH0>=0xEE)//如果计数时间太长,系统可能有问题,退出循环 break; } TR0=0;//如果P3.5输入为“0”,则停止定时器/计数器0计数 return(TH0*256+TL0);//返回定时器/计数器0的计数值}设计实例二:红外遥控器解码的实现

--修改main.c文件u16low_level_time()//声明检测红外发送数据的低电平持续时间函数{ TL0=0;//置定时器/计数器0初值低8位寄存器TL0为0 TH0=0;//置定时器/计数器0初值高8位寄存器TH0为0 TR0=1;//启动定时器/计数器0开始计数

while(P35==0)//如果P3.5输入为“0”,一直继续,否则退出 { if(TH0>=0xEE)//如果计数时间太长,系统可能有问题,退出循环 break; } TR0=0;//如果P3.5输入为“1”,则停止定时器/计数器0计数 return(TH0*256+TL0);//返回定时器/计数器0的计数值}设计实例二:红外遥控器解码的实现

--修改main.c文件/******定义端口P3的中断服务程序,利用保留中断号13*******/voidint13()interrupt13{u8i,j;//定义无符号字符变量i,ju16count=0;//定义无符号整型变量count u8dat=0;//定义无符号字符变量datif(P3INTF) { P3INTF=0X00; count=low_level_time();//读取前导码的低前半部分 if((count<=2000)||(count>5000))//如果不在范围内,退出中断 { return; }设计实例二:红外遥控器解码的实现

--修改main.c文件count=high_level_time();//读取前导码的高后半部分 if(count<2000||count>2500)//如果不在范围内,退出中断 {return; } /******下面开始处理32位数据*********/ for(i=0;i<4;i++)//四个字节的循环处理 {P35=1;//读取P3.5引脚前,需要置P3.5为高 dat=0;//dat赋值为0for(j=0;j<8;j++)//8个比特的循环处理 { count=low_level_time();//读取逻辑位低前半部分设计实例二:红外遥控器解码的实现

--修改main.c文件if(count<50||count>300)//如果不在范围内,则退出中断return; count=high_level_time();//读取逻辑位高后半部分 if(count>200&&count<400)//如果在逻辑“0”的范围内,填充0 dat>>=1; elseif(count>500&&count<1000)//如果在逻辑“1”的范围内 { dat>>=1;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论