找回密码
 立即注册
楼主: I兔儿

公司需要学增强型8051单片机,8H

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-3-29 18:33:58 | 显示全部楼层
第十二课     单片机C语言程序设计导入二

unsigned char data  保存在内部的ram中  定义的时候防止延时不对
调试模式下  在STC仿真软件中设置好芯片作为仿真软件    魔术棒选择串口号作为仿真口
实例1 实现跑马灯 仿真过程中的变量可以显示在  keil中
关键代码
code ledNum[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

P6 = ~ledNum[ledIndex];        //输出低驱动
ledIndex++;
实例2   单片机Flash作为EEPROM使用的基本操作。实现对0x0400单元的擦除和读写操作
ISP用户自定义E2PROM的大小
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-5 14:54:35 | 显示全部楼层
第十三课 中断原理及工作机制一
一、中断的相关概念
1.中断的概念
2.其他中断相关概念
中断源  中断响应  中断服务  中断服务
3.中断优先级
4.中断的优势
5.开中断和关中断
6.保护现场和回复现场
7.堆栈
8.中断的撤除
二、中断源
1.中断源
举例:
假如int0下降沿触发中断  IT0=1,  EX0=1,  EA=1
2.中断源及控制
3.中断标志位
(1)外部中断和定时器中断请求标记
外部中断0(INT0)和外部中断1(INT1)既可双边沿触发(即上升沿和下降沿都可以触发)也可以只有下降沿触发。这两个外部中断的请求标志位分别是寄存器TCON中的IEO/TCON.1和IE1/TCON.3。当外部中断服务程序被响应后,中断标志位I0和IE1会自动清0。外部中断0(INTO)和外部中断1(INT1)还可以用于将单片机从掉电模式唤醒。
TCON各个位含义:

①ITO:外部中断INT0触发方式控制位。可由软件置1或清0。
0:上升沿和下降沿均可触发外部中断。当INT0引脚出现上升沿或者下降沿时,置位IE0.
1:下降沿触发方式。INT0引脚上电平由高到低的负跳变时,置位IE0。
②)IE0:外部中断INTO请求标志。
③ IT1:外部中断INT1触发方式控制位,与IT0类似。
④IE1:外部中断INT1请求标志,其意义和IE0相同。


外部中断2~4(INT2~INT4)只能下降沿触发。当外部中断服务程序被响应后,相应的中标志位(INT2IF~INT4IF)硬件自动清零。外部中断2~4(INT2~INT4)也可以用于将单片机从掉电模式唤醒。
定时器2、定时器3和定时器4的中断请求标志位是T2IF、T3IF、T4IF。当相应的中断服务程序执行后,相应的中断标志位硬件自动清零。

(2)串口的中断请求标志
串口1、串口2、串口3和串口4的中断请求标志分别锁存在特殊功能寄存器SCON、S2CON、S3CON和S4CON中。这些中断请求标志都不能自动清0,需要用户在中断服务程序中使用软件清0。

中断源

中断源

中断源以及控制

中断源以及控制
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-5 17:18:32 | 显示全部楼层
第十四集 中断原理及工作机制二
(3)电源控制寄存器PCON中的标志位
LVDF是低电压检测标志位,同时也是低电压检测中断请求标志位。在正常工作和空闲工作状态时,如果内部工作电压VCC低于低电压检测门槛电压,低电压中断请求标志位(LVDF/PCON.5)自动置1,与低电压检测中断是否被允许无关。即在内部工作电压VCC低于低电压检测门槛电压时,不管有没有允许低电压检测中断,LVDF/PCON.5都自动为1该位要用软件洁0,洁0后,如内部工作电压VCC低于低电压检测门电压,该位又被自动设置为1。
(4)SPI状态寄存器SPSTAT中的标志位
SPIF是SPI传输完成标志。当一次传输完成时,SPIF被置位。此时,如果SPI中断被打开(ESPI=1,EA=1),将产生中断。
(5)ADC控制寄存器ADC_CONTR中的标志位
ADC FLAG是A/D转换结束标志位。AD转换完成后,ADCFLAG=1。此时,若允许A/D转换中断(EADC=1,EA=1),则由该位申请产生中断。也可以由软件查询该标志位判断A/D转换是否结束。不管是A/D转换完成后由该位申请产生中断,还是由软件查询该标志位A/D转换是否结束,当AD转换完成后,ADCFLAG=1,一定要软件清0.
4.中断的允许、禁止及优先级
(1)中断的开放和禁止
(2)中断优先级
5.单片机中断处理过程

(1)中断响应的条件及过程
当中断源向CPU发出中断请求时,如果中断的条件满足,CPU将进入中断响应周期。单片机响应中断的条件是:
1)中断源有请求。
2)中断允许寄存器IE相应位置1。
3)CPU中断开放(EA1)。
CPU响应中断时,将相应的优先级状态触发器置1,然后由硬件自动产生一个长调用指令LCALL此指令首先把断点地址压入堆栈保护,再将中断服务程序的入口地址送入到程序计数器PC,使程序转向相应的中断服务程序。



在程序的运行过程中,并不是任何时刻都可以响应中断请求。当出现下列情况时,CPU不会响应中断请求:
1)中断允许总控制位EA=0或发出中断请求的中断所对应的中断允许控制位为0。
2)CPU正在执行一个同级或高一级的中断服务程序。
3)当前执行的机器周期不是指令周期的最后一个机器周期。
4)正在执行的指令是中断返回指令RETI或者是访问专用寄存器IE或IP的指令时,CPU至少要再执行一条指令才能响应中断请求。

(2)中断服务
(3)中断请求的撤除






回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:233
  • 最近打卡:2025-04-30 16:08:37

61

主题

818

回帖

1490

积分

金牌会员

积分
1490
发表于 2025-4-5 20:33:09 | 显示全部楼层
jiayouba 51 不错的
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-7 19:04:00 | 显示全部楼层
第十五集 定时器原理及STC扩展
一  、STC8H8K64U单片机的定时/计数器结构
二  、STC8H8K64U的定时/计数器相关寄存器


定时/计数器的应用
在自动控制系统或者自动检测系统中,经常要用到定时器或者计数器,用于定时完成相关的任务,或者对外部事件进行计数,这可以通过单片机集成的定时/计数器实现。
1.定时/计数器的作用
STC8H8K64U单片机内部集成了五个16位的定时1计数器(T0、T1、T2
T3和T4),作用如下:
(1)方便地用于定时控制;
(2)用作分频器和用于事件记录;
(3)可编程时钟输出功能,用于给外部器件提供时钟
(4)可用作串口的波特率发生器
2.定时/计数器的一般结构


单片机CPU和定时器相关寄存器
定时/计数器的工作模式
(1)T0和T1的工作模式
STC8H8K64U的定时器/计数器T0有4种工作模式:模式0(16位自动重装载模式)模式1(16位不可重装载模式)
模式2(8位自动重装模式)
模式3(不可屏蔽中断的16位自动重装载模式)

T1模式3时无效

当GATE=0时,如TRn=1,则定时器计数。GATE=1时,允许由外部输入INTn控制定时器
这样可实现脉宽测量。
当C/T-0时,多路开关连接到系统时钟的分频输出,Tn对内部系统时钟计数,Tn工作在定时方式。当C/T=1时,多路开关连接到外部脉冲输入,Tn对外部脉冲计数,即Tn工作在计数
方式。STC8H8K64U单片机的定时器有两种计数速率:一种是12T模式,每12个时钟加1(称为“12分频”),速度与传统8051单片机相同;另一种是1T模式,每1个时钟加1(称为“不分频”),速度是传统8051单片机的12倍。T0和T1的速率分别由辅助寄存器AUXR中的TOx12和T1x12两个控制位决定,如果T0x12=0,T0则工作在12T模式:如果TOx12=1,TO则工作在1T模式。如果T1x12=0,T1则工作在12T模式;如果T1x12=1,T1则工作在1T模式。当定时器工作在模式0时,「Ln,THn]的溢出不仅置位TFn,而且会自动将时间常数重新装入ITLn,THn.
当T0CLKO=1时,T1/P3.5引脚配置为定时器0的时钟输出TOCLKO
当T1CLKO=1时,TO/P3.4引脚配置为定时器1的时钟输出T1CLKO

定时器T2的工作模式固定为16位自动重装载模式。
T2、T3和T4的工作方式与T0的工作方式0类似。
-----------------------------------------------------------------------------------------------------------------------------------------------------
STC8H8K64U的定时/计数器相关寄存器
与定时/计数器相关的特殊功能寄存器有TMOD、TCON、AUXR、INTCLKO、T4T3M。其中,TMOD用于控制定时/计数器的工作方式;TCON用于控制T0、T1的启动和停止,并包含了定时器的状态;AUXR用于设置定时器T0、T1、T2的速度和T2的功能选择和启动/停止控制:T4T3M用于设置T4和T3的功能、速度和启动/停止控制。





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-8 00:22:35 | 显示全部楼层
第十六集 定时器应用及STC扩展
1.定时/计数器量程的扩展(软件扩展 硬件扩展)


定时/计数器的应用编程主要有两点:一是能正确初始化,包括写入控制字,进行时间常数的计算并装入;二是中断服务程序的编写,即在中断服务程序中编写实现需要定时完成的任务代码。一般情况下,定时/计数器初始化部分的步骤大致如下:
1)设置工作方式,将控制字写入方式寄存器
2)把定时/计数初值装入TLn、THn寄存器。
3)置位TRn以启动定时/计数。
置位ET允许定时/计数器中断(如果需要)4)
5)置位EA使CPU开放中断。



我测试出来时0.5S有人知道原因吗 代码如下

//【例2】设系统时钟频率为11.0592MHz,利用定时器T2定时,每隔4s将P6.0的状态取反
#include "stc8h.h"
unsigned char i;
void Timer2_Init(void);
void main (void)
{   
P4M1=0xff;
P4M0=0xff;
P6M1=0x0;
P6M0=0x0;
P40=0;
Timer2_Init();
i=4;
EA =1;
while(1);
}



void Timer2_Isr(void) interrupt TMR2_VECTOR
{
    i--;
//计数变量减1
//若减到0,则将取反
if(i==0)
  {  P60 = ~P60;
    i= 4;//重新给计数变量赋值
   }
}


void Timer2_Init(void)                //1秒@11.0592MHz
{
        TM2PS = 0x0E;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0xFB;                        //定时器时钟12T模式
        T2L = 0x00;                                //设置定时初始值
        T2H = 0x10;                                //设置定时初始值
        AUXR |= 0x10;                        //定时器2开始计时
        IE2 |= 0x04;                        //使能定时器2中断
}






回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:82
  • 最近打卡:2025-04-30 08:21:19
已绑定手机

6

主题

31

回帖

358

积分

中级会员

积分
358
发表于 2025-4-8 13:26:17 | 显示全部楼层
zha*** 发表于 2025-3-21 06:56
学单片机必须从stc开始

赞同
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-10 16:35:33 | 显示全部楼层
十七集 串行口原理一
一、串行通信的相关概念
二、串行通信的分类
三、通用异步接收器/发送器UART



一.串行通信的相关概念
基本的数据通信方式有两种:
并行通信--数据的各位同时传送
串行通信--数据一位一位地顺序传送

串行通信的分类-1.
1、按照通信格式的同步方式分类按照该分类方法,串行通信可分为异步通信和同步通信。

串行通信的分类-2
异步通信的数据帧格式(7个数据位)

串行通信的分类-3
异步通信的数据帧格式(8个数据位)

串行通信的分类-4
在异步数据传送中,CPU与外设之间事先必须约定好以下内容:
1)字符格式
双方要设定好字符的编码形式、奇偶校验形式、起始位和停止位的规定。
2)通信速率
通信速率通常使用波特率来表示。
典型的表示方法:如,9600,n

串行通信的分类-5
(2)同步通信
同步通信效率高,但线路复杂,适合于近距离通信。
同步传送时需要注意的是:同步通信的收/发双方必须使用相同的同步字符在同步传送中要求用同步时钟来实现发送端和接收端之间的严格同步,而且对同步时钟脉冲信号的相位一致性要求非常严格。

串行通信的分类-6
2、按照数据的传送方向分类
(1)单工方式:只允许数据按一个固定的方向传送。

串行通信的分类-7
2、按照数据的传送方向分类
(2)半双工方式:数据可以从A发送到B,也可以从B发送到A。但同一时刻只能向一个方向传送。

.串行通信的分类-8
2、按照数据的传送方向分类
(3)全双工方式:数据可同时在两个方向
上传送。

1.串行接口
在串行传送中,数据是一位一位按顺序进行传送的,而计算机内部的数据是并行传送的。因此当计算机向外发送数据时,必须将并行的数据转换为串行的数据再行传送。反之,又必须将串行数据转换为并行数据输入计算机中。上述并一串或串一并的转换既可以用软件实现,也可用硬件实现。但由于用软件实现会使CPU的负担增加,降低了其利用率,故目前往往用硬件完成这种转换。通用的异步接收器1发送器(UART,UniversalAsynchronous Receiver/Transmitter)就可实现上述“串行-并行转换是串行接口的核心部件。
2.通用的异步接收器/发送器UART的结构
3.通用的异步接收器/发送器UART的出错标志
4.通用的异步接收器/发送器UART的同步过程






回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-10 18:26:08 | 显示全部楼层
第十八课   串行口原理二

STC8H8K64U单片机的串口简介
STC8H8K64U的UART接口的寄存器
STC8H8K64U单片机的串口工作模式

STC8H8K64U单片机具有4个采用UART工作方式的全双工串行通信接口(串口1、串口2、串口3、串口4)。
串口2、串口3、串口4没有同步移位功能。

串口相关寄存器
与串口1相关的寄存器有SCON、PCON、AUXR、SBUF、TMOD、TH1、TL1、TCON、IE、IP、SADEN和SADDR.
与串口2相关的寄存器有:S2CON、S2BUF、TH2、TL2、AUXR、IE2IP2和AUXR1.
与串口3相关的寄存器有:S3CON、S3BUF.
与串口4相关的寄存器有:S4CON、S4BUF。其中,寄存器TMOD、TH1TL1、TH2、TL2和TCON与定时器有关,详细介绍请参见第7章;寄存器IEIE2、IP和IP2与中断有关,详细介绍请参见第6章。

1、串口控制寄存器SCON


2.SM2:多机通信控制位。多机通信主要指单片机通信时工作于方式2和方式3。SM2位主要用于方式2和方式3,是进行主一从多机通信的控制位。这种多机通信方式一般为“一台主机,多台从机”系统,主机发送的信息可被各从机接收,而从机只能与主机进行通信,从机问互相不能直接通信。

实现多机通信的过程:
(1)主、从机均初始化为模式2或模式3,置SM2=1,允许中断。
(2)主机置TB8=1,发送要寻址的从机地址。
(3)所有从机均接收主机发送的地址,并进行地址比较。
(4)被寻址的从机确认地址后,置本机SM2=0,此时可向主机返回地址,供主机核对。
(5)核对无误后,主机向被寻址的从机发送命令,通知从机接收或发送数据。
(6)通信只能在主、从机之间进行,两个从机之间的通信需通过主机作中介。
(7)本次通信结束后,主、从机重置SM2=1,主机可再对其他从机寻址。
在实际工程应用中,这种多机通信中的接口协议常用RS-485标准。RS-485是一种多发送器的电路标准,它允许双导线上一个发送器驱动最多256个负载设备(不同的芯片数量不同)。RS-485为半双工,在某一时刻,一个发送另一个接收。在电路设计上,平衡连接电缆两端要有终端电阻。常用的RS-485芯片是MAX1487(目前也出现了很多与其兼容的芯片),其包含一个驱动器和一个接收器,适合于RS-485通信标准的低功率收发器。详细信息及使用方法,请参见相关手册。


2--------串口2控制寄存器S2CON

串口2控制寄存器

串口2控制寄存器

3.串口3控制寄存器S3CON

4.串口4控制寄存器S4CON

4

4


5.掉电控制寄存器PCON  
截图202504110929207723.jpg

6.辅助寄存器AUXR
截图202504110931041722.jpg

7.从机地址控制寄存器
为了方便多机通信,STC8H8K64U单片机设置了从机地址控制寄存器SADEN和SADDR。其中,SADEN是从机地址掩模寄存器(地址为B9H,复位值为00H),SADDR是从机地址寄存器(地址为A9H,复位值为00H)
主机可以用从机地址来选择性地访问从机,可以用广播的方式来寻址所有的从机。从机的地址由SADDR和SADEN寄存器定义,从机地址是由SADDR设定的8位数据,如果SADEN中相应的位置0,则SADDR中对应的位无效。只有当SADEN中的相应位为I,SADDR中的数据才有效。也就是说,SADEN寄存器使能串口的自动地址识别功能,当SADEN中的某位被置为1,那么SADDR寄存器中的相应位会与接收到的数据进行比较。如果SADEN.n被设为0,那么系统会忽略对该位的比较。如果SADEN为全0,那么对于所有的地址系统都会产生中断。


截图202504110936103652.jpg

8数据缓冲器
数据缓冲器用于保存要发送的数据或者从串口接收到的数据。串口1的数据缓冲器是SBUF(地址是99H),串口2的数据缓冲器是S2BUF(地址是9BH),串口3的数据缓冲器是S3BUF(地址是ADH),串口4的数据缓冲器是S4BUF(地址是85H)。
对于串口1,SBUF是用来存放发送和接收数据的两个独立的缓冲寄存器,CPU执行给SBUF赋值的语句时,触发串口1的发送,串口1便一位一位地发送数据,发送完成后标志TI=1;在CPU允许接收串行数据时,外部串行数据经RXD送入SBUF,电路便自动启动接收,第9位则装入SCON寄存器的RB8位,直至完成一数据后将RI置1,当串口接收缓冲器接收到一帧数据时,可以执行读取SBUF内容的语句读取串口数据,如rxbuffer=SBUF。


STC8H8K64U的串口工作模式


1)串口1工作模式0
当软件设置SCON的SMO、SM1为“00”时,串口1工作于模式0,串行通信接口工作在同步移位寄存器模式,RxD为串行通讯的数据口,TxD为同步移位脉冲输出脚,发送、接收的是8位数据,低位在先。该模式下
,必须清0多机通信控制位SM2,使之不影响TB8位和RB8位。模式0的发送过程:当主机执行将数据写入发送缓冲器SBUF指令时启动发送,串行口即将8位数据从RxD引脚输出(从低位到高位),发送完中断标志T置1,TxD引脚输出同步移位脉冲信号。



模式0的接收过程:首先将接收中断请求标志RI清零并置位允许接收控制位REN时启动模式0接收过程。启动接收过程后,RxD为串行数据输入端,TxD为同步脉冲输出端。当接收完成一数据(8位)后,控制信号复位,中断标志RI被置1,呈中断申请状态。当再次接收时,必须通过软件将RI清0。



2)串口1工作模式1当软件设置SCON寄存器的SM0、SM1为“01”时,串行口1工作于模式1。此方式为8位UART格式,一帧信息为10位,包括1位起始位,8位数据位(低位在先)和1位停止位。起始位和停止位是在发送时自动插入的。接收时,停止位进入SCON的RB8位。波特率可变,即可根据需要设置波特率。TxD为数据发送引脚,RXD为数据接收引脚,方式1提供异步全双工通信,适合于点到点的通信。

串口1工作方式1

串口1工作方式1

3)工作模式2很少使用
4)工作模式3


(2)串口2的工作模式
串口2只有两种工作模式,它们都是UART方式(即异步串行通信模式)
1)模式0   
10位数据通过RxD2/P1.0(RxD2_2/P4.0)接收,通过TxD2/P1.1(TxD2_2/P4.2)发送。一帧数据包含个起始位(0),8个数据位和一个停止位(1)。接收时,停止位进入特殊功能寄存器S2CON的S2RB8位。波特率由定时器T2的溢出率决定。
当T2工作在1T模式(T2x12=1)时,串行口2的波特率=SYScIk/(65536-[RL_TH2,RL_TL2])14;当T2工作在12T模式(T2x12=0)时,串行口2的波特率=SYSclk/12/(65536-[RL TH2,RL TL2])14。其中,RL TH2是T2H的重装载寄存器,RL_TL2是TL2的重装载寄存器。使用时,直接给TH2和TL2进行赋值即可。
2)模式1
11位数据通过TxD2/P1.1(TxD2_2/P4.2)发送,通过RxD2/P1.0(RxD2_2/P4.0)接收。一帧数据包含一个起始位(0)、8个数据位、一个可编程的第9位和一个停止位(1)。发送时,第9位数据位来自特殊功能寄存器S2CON的S2TB8位。接收时,第9位进入特殊功能寄存器S2CON的S2RB8位。波特率的计算方法与方式0相同,在此不再复述。串口3和串口4的工作模式与串口2类似.


与寄存器相关的寄存器

与寄存器相关的寄存器

SCON

SCON

串口工作方式

串口工作方式

3

3
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-04-25 19:41:38
已绑定手机

3

主题

33

回帖

187

积分

注册会员

积分
187
发表于 2025-4-11 14:39:15 | 显示全部楼层
第十九课   串口通信多机通信
1.串口1波特率的设定
(1)模式0的波特率
当UART_MOx6-0时,波特率为SYSclk/12;当UART_MOx6-1时,波特率为SYSc1k/2。


(2)模式2的波特率
串行口1工作于模式2时,波特率有两种波特率可选,取决于电源控制寄存器PCON中SMOD位的值,当SMOD-0时,为SYSclk/64:当SM0D-1时,为SYSclk/32.

(3)模式1和3的波特率
串行口1工作于模式1和3时,波特率是可变的,可以通过编程改变定时器1的溢出率或者定时器2的溢出率来确定波特率。
编程时应注意,当定时器作为波特率发生器使用时,应禁止定时器产生中断(ET1=0或ET2-0)。典型用法是将定时器设置工作在自动重装入时间常数的定时方式。设置完成后,启动定时器(TR1=1或TR2-1)。

假设SYSclk为系统时钟频率。串口1用T1作为波特率发生器,且T1工作于模式0(16位自动重
装模式)时的公式如下:
波特率=(T1的溢出率)/4=SYSclk/12-2 65536-[RL THL,RL TL1])/4
其中,12T模式时,TIx12=0:1T模式时,TIx12=1。
RL, TH1是TH1的自动重装载寄存器,RL,TL1是TL1的自动重装载寄存器。注意:此时波特率与
SMOD无关。
T2只有一种工作方式,即16位自动重装方式,因此使用T2作为波特率发生器时的公式如下:串口1的波特率=SYSclk/121-12x12/(65536-[RL, TH2,RL TL2])/4其中,RL TH2是TH2的自动重装寄存器;RLTL2是TL2的自动重装寄存器。在实际应用中,一般选用模式1或模式3。此时,波特率的设置关键在于T1和T2的溢出率的计算。





2.串口2~4的波特率设定
对于串口2、串口3和串口4,具体使用T2、T3或T4中的哪一个定时器作为波特率发生器前面已有详细叙述。在此,以T2作为波特率发生器为例,波特率计算方法如下公式所示:
波特率=SYSclk/12n/(65536-[RL TH2,RL TL2])/4串口3和串口4波特率的设定方式与串口2类似。



串口接口应用举例
(1)串口1的编程要点
① 设置串行口的工作模式
设置SCON寄存器的SMO和SM1的内容。若需要串行口具有接收功能,则置REN=1。
②设置正确的波特率
(a)使用T1作为波特率发生器时,需要设置T1的工作模式和时间常数(设定TMOD和TH1、TL1寄存器的内容);启动T1(置TR1=1)。
(b)使用T2作为波特率发生器时,需要设置T2寄存器和相应的位,包括:T2自动重装寄存器TH2和TL2,T2_C/T位,T2x12位,SMOD位。启动T2(置TR2=1)。
③ 设置串行口的中断优先级(设置PS寄存器的内容,也可以不设置,取默认值),设置相应的中断控制位(ES和EA)
4)如要串口1发送,将数据送入SBUF。
编制串行中断服务程序,在中断服务程序中要有清除中断标志指令(将TI和RI清0)。



(2)串口2的编程要点
首先 串口相关的IO设置
① 设置串口2的工作模式
设置S2CON寄存器中的S2SMO位。如需要串行口2具有接收功能,则置S2REN=1。2设置串口2的波特率
串口2只能使用T2作为波特率发生器,设置内容包括:TH2和TL2,T2C/位,T2x12位。
启动T2(置TR2=1)。
③ 设置串口2的中断优先级(设置PS2,也可以不设置,取默认值),设置打开相应的中断控制位(ES2和EA)
④如要串口2发送,将数据送入S2BUF。
⑤ 编制串行中断服务程序,在中断服务程序中要设置清除中断标志指令(分别是接收完成标志S2RI和发送完成标志S2TI)。



例: 设有甲、乙两台单片机,编写程序使两台单片机问实现如下串行通信功能。(假设系统时钟为11.0592MHz)
甲机发送:将首址为ADDRT的128字节的外部RAM数据块顺序向乙机发送:
乙机接收:将接收的128字节的数据,顺序存放在以首址为ADDRR的外部RAM中






//包含单片机的寄存器定义头文件//在外部RAM区定义128个单元
#include  "stc8h.h"
unsigned char xdata ADDRT[128];

unsigned char num=0;
//声明计数变量
unsigned char *
myp;//指向发送数据区的指针
void main(void)//主程序,在C语言的主程序中可以不设置堆栈指针
{

SCON=0x40;      //8位数据,可变波特率
AUXR &= 0xFE;   //串口1选择定时器1为波特
TMOD &= 0x0F:   //设定定时器1为16位自动
TL1 = 0xE8;     //设定定时初值
TH1 = 0xFF;     //设定定时初值
TR1 = 1;        //启动定时器1
ES=1;           //串行口开中断
EA=1;           //开中断
psend=ADDRT;    //设置发送数据缓冲区指针
SBUF=*psend;    //发送第一个数据
while(1);       //等待中断

}






void UART1_ISR(void)interrupt UART1_VECTOR //串口1中断服务函数
{
       TI=0;             //清发送中断标志
       num++;            //修改计数变量值
      if(num==0x7F)ES=0; //判断是否发送完,若已完,则关中断
      else               //否则,修改指针,发送下一个数据
        {
            myp++:
            SBUF=*myp;
        }        
}





发送代码

#include "stc8h.h"
unsigned char xdata ADDRT[128];
unsigned char num = 0;        // 计数变量
unsigned char *psend;         // 发送数据指针

void main() {
    SCON = 0x40;       // 串口模式1(8位UART,无校验)
    AUXR &= 0xFE;      // 串口1使用定时器1为波特率发生器
    TMOD |= 0x20;      // 定时器1设为8位自动重装模式
    TH1 = 0xFD;        // 波特率9600(11.0592MHz)
    TL1 = 0xFD;        // 初始值
    TR1 = 1;           // 启动定时器1
    ES = 1;            // 允许串口中断
    EA = 1;            // 开总中断

    psend = ADDRT;     // 指针指向数据首地址
    SBUF = *psend;     // 发送第一个字节
    while(1);          // 等待中断
}

void UART1_ISR() interrupt 4 {
    if (TI) {          // 发送中断
        TI = 0;        // 清除标志
        num++;         // 计数+1
        if (num == 127) {
            ES = 0;    // 发送完成,关闭中断
        } else {
            psend++;   // 指针递增
            SBUF = *psend; // 发送下一字节
        }
    }
}




接收代码


#include "stc8h.h"
unsigned char xdata ADDRR[128];
unsigned char num = 0;        // 计数变量
unsigned char *precv;         // 接收数据指针


void main() {
    SCON = 0x50;       // 串口模式1,允许接收
    AUXR &= 0xFE;      // 定时器1作波特率发生器
    TMOD |= 0x20;      // 定时器1设为8位自动重装
    TH1 = 0xFD;        // 波特率9600(11.0592MHz)
    TL1 = 0xFD;
    TR1 = 1;           // 启动定时器1
    ES = 1;            // 允许串口中断
    EA = 1;            // 开总中断


    precv = ADDRR;     // 指针指向接收缓冲区
    while(1);          // 等待中断
}


void UART1_ISR() interrupt 4 {
    if (RI) {          // 接收中断
        RI = 0;        // 清除标志
        *precv = SBUF; // 存储数据
        precv++;       // 指针递增
        if (++num == 128) ES = 0; // 接收完成,关中断
    }
}



例:
多机通信编程举例
现用简单实例说明多机串行通信中从机的基本工作过程。而实际应用中还需要考虑通信的规范协议。有些协议很复杂,在此不加以考虑。假设系统晶振频率为11.0592MHz。
主机:先向从机发送一帧地址信息,然后再向从机发送10个数据信息,
从机:接收主机发来的地址帧信息,并与本机的地址号相比较,若不符合,仍保持SM2=1不变;若相等,则使SM2清零,准备接收后续的数据信息,直至接收完10个数据信息。




从机代码
#include "stc8h.h"

unsigned char xdata ADDRR[10];
unsigned char SLAVE = 5;      // 从机地址设为5
unsigned char num = 10;       // 待接收数据计数
unsigned char *mypdata = ADDRR;

void UART_Init() {
    SCON = 0xF0;              // 模式3(9位UART),SM2=1,允许接收
    AUXR |= 0x01;             // 使用定时器2作为波特率发生器
    T2L = 0xE8;               // 定时器2初值(11.0592MHz, 9600bps)
    T2H = 0xFF;
    AUXR |= 0x10;             // 启动定时器2
    ES = 1;                   // 允许串口中断
    EA = 1;                   // 开总中断
}

void main() {
    UART_Init();
    mypdata = ADDRR;          // 指向接收缓冲区
    while(1);
}

void UART1_ISR() interrupt 4 {
    if (RI) {
        RI = 0;               // 清除接收中断标志
        unsigned char rdata = SBUF;

        if (RB8 == 1) {       // 地址帧
            if (rdata == SLAVE) {
                SM2 = 0;      // 地址匹配,准备接收数据
            }
        } else {              // 数据帧
            if (SM2 == 0) {   // 仅当SM2=0时接收数据
                *mypdata++ = rdata;
                num--;
                if (num == 0) {
                    SM2 = 1;  // 接收完成,恢复SM2=1
                    num = 10; // 重置计数
                    mypdata = ADDRR; // 重置指针
                }
            }
        }
    }
    if (TI) TI = 0;           // 清除发送中断标志(若启用发送)
}


主机代码
#include "stc8h.h"

void UART_Init() {
    SCON = 0x80;              // 模式2(9位UART),SM2=0
    AUXR |= 0x01;             // 使用定时器2
    T2L = 0xE8;               // 波特率9600
    T2H = 0xFF;
    AUXR |= 0x10;             // 启动定时器2
}

void SendAddress(unsigned char addr) {
    TB8 = 1;                  // 地址帧标志
    SBUF = addr;
    while(!TI);               // 等待发送完成
    TI = 0;
}

void SendData(unsigned char *data, unsigned char len) {
    TB8 = 0;                  // 数据帧标志
    for (unsigned char i=0; i<len; i++) {
        SBUF = data;
        while(!TI);
        TI = 0;
    }
}

void main() {
    UART_Init();
    unsigned char xdata data[10] = {0x01, 0x02, ..., 0x0A};

    SendAddress(5);           // 发送从机地址5
    SendData(data, 10);       // 发送10字节数据
    while(1);
}


流程图

流程图
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 22:10 , Processed in 0.177229 second(s), 107 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表