当前位置: 首页 > news >正文

江协科技51单片机学习- p17 定时器

🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大51单片机的视频为主以及自己的总结梳理📚 

 前言:

本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记,在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。

引用:

51单片机入门教程-2020版 程序全程纯手打 从零开始入门_哔哩哔哩_bilibili

​​​​​​c51语言变量语句意思,C51中循环语句-CSDN博客

定时器引用:

51单片机学习笔记_c51.h-CSDN博客

江科大51单片机入门学习笔记合集_51单片机江科大教程下载-CSDN博客

https://xiajun.blog.csdn.net/article/details/139968278

正文:

0. 🌿概述

在淘宝上购买了江协科技51单片机开发板套件(普中科技STC51单片机A2型号),就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程,通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。

1. 🚀C51单片机定时器

🐳定时器是51单片机的内部资源,其电路的连接和运转均在单片机内部完成。

🐳定时器的作用

  • 💘用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作。
  • 💘代替长时间的Delay,提高CPU的运行效率和处理速度。

  •  STC89C52系列单片机内部设置的两个16位定时器/计数器T0和T1,都具有计数和定时两种重做方式。
  • 对于每个定时器/计数器(T0/T1),在特殊功能计数器TMOD中都有一控制位- C/T 来选择T0或T1为定时器还是计数器。
  • 定时器/计数器0 有4中工作方式
    💘 模式0 (13位定时器/计数器)
    💘 模式1 (16位定时器/计数器)
    💘 模式2 (8位自动装载模式)
    💘 模式3 (两个8为定时器/计数器)
  • 定时器/计数器1除模式3外,其它工作模式与定时器0相同,T1在模式3无效,停止计数。

💖 定时器的个数是和单片机的型号联系在一起的,不同型号的单片机定时器的个数可能不同,但一般来说T0和T1的操作方式和所有51单片机所共有的和传统的51单片机兼容。

STC52RC单片机有3个定时器 T0, T1, T2,T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源。

2. 🚀C51单片机定时器中断

定时器就像一个小闹钟,一样根据时钟输出信号,每隔“几个脉冲”,计时器单元的值就增加1,当计数器单元数值增加到“设定的闹钟提醒时间”时,计数器就会向中断系统发出中断申请,产生“响铃提醒”,是程序跳转到中断服务函数中执行😊。

😛 中断也是一种单片机资源,查看STC89C52的数据手册。

  • 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的😘。
  • 当CPU正在处理某事件的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完成以后,在回到被中断的地方,继续原来的工作,这样的过程称为中断😘。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。
  • 微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断请求源的问题。通常是根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是优先响应最级别最高的中断请求。🤗

🔍️ 当CPU正在处理一个中断源的时候(执行相应的中断服务程序),发生了另外一个中断优先级比他还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完成后,在回到原低优先级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统📘,没有中断嵌套功能的中断系统称为单级中断系统📙。

STC89C52系列单片机提供了 8个中断请求源 , 它们分别是:

  1. 🔖外部中断0 (INT0
  2. 🔖定时器0中断
  3. 🔖外部中断1 (INT1
  4. 🔖定时器1中断
  5. 🔖串口中断(UART)
  6. 🔖定时器2中断
  7. 🔖外部中断2(INT2
  8. 🔖外部中断3(INT3

🔍️所有的中断都具有 4个优先级

  • 🔍️用户可以用关中断允许位(EA/IE.7)或相应中断的允许位来屏蔽所有的中断请求,也可以打开相应的中断允许为来使PCU响应相应的中断申请;
  • 🔍️每一个中断源可以用软件独立的控制为开中断或者关中断状态;
  • 🔍️每一个中断的优先级别均可以用软件设置。
  • 🔍️高优先级的中断可以打断低优先级的中断,反之,低优先级的中断请求不可以打断高优先级的中断。
  • 🔍️当两个相同优先级的中断同时产生时,将由查询次序来决定先响应哪个中断。

STC89C52系列单片机的各个中断查询次序如下表所示:

51单片机的计时器T0/T1 模式1 (16为定时器/计数器)功能框图如下,主要分为3部分,时钟部分,计数器部分,中断部分。

定时器计数部分:

  • 🦜TL0 16为位计数器的低8位,TLH0 16位计数器的高8位,最大可以存数值为65535。
  • 🦜C/T 选择T0/T1计数器/定时器是工作在定时器模式,还是工作在计数器模式。T 字符上面的横线表示‘低电平’有效选择定时器,C 表示‘高电平’有效选择计数器。

 定时器时钟部分:

  • 🦜定时器时钟部分来自于系统时钟 SYSclk  或者 T0Pin (选择T0Pin时外部每输入一个脉冲,计数器加1)。
  • 🦜本实验我使用的普中科技C51单片机开发板的晶振是 11.0952Mhz,即系统时钟 SYSclk 是 11.0952MHz

定时器的系统使用 SYSclk 通过 12或者6 分频,进入定时器,我使用的普中单片机开发板上面的晶振是 11.0952Mhz/12=921,600Hz,也就是说计时器每加1 时间经过了 1/921,600 s 

定时器和中断的整体关系,定时器的时钟部分产生脉冲,

3. 🚀定时器相关寄存器

  • 寄存器是连接软硬件的媒介。
  • 在单片机中寄存器就是一段特殊的RAM存储器,一方面寄存器可以存储和读取数据,另一方面,寄存器背后都连着一根导线,控制着电路的链接方式。
  • 寄存器相当于一个复杂机器的“操作按钮”。

定时器 TCON 寄存器

定时器 TMODE 寄存器

 4. 🚀C51单片机中断相关寄存器

51单片机中断相关寄存器如下

5. 单片机寄存器可位寻址不可位寻址

😎单片机寄存器分为可位寻址不可位寻址,可位寻址的寄存器可以单独对寄存器的某一位赋值,不可位寻址的寄存器只能对寄存器整体赋值。

6. 单片机C 中断处理函数

单片机C 中断处理函数需要增加关键字 "interupt x",x就是中断号(中断查询次序号)。

7. 定时器中断源码编写

7.1 定时器中断源码编写。

STC-ISP中硬件定时器计算工具

  • 根据开发板实际的晶振频率选择主频为11.0592MHz
  • 定时器模式,因为STC89C52RC的定时器/计数器模式为0/1/2/3 这四种模式,此时实验我们选用的是定时器/计数器T0的16位模式。(STC89C52不支持16为自动装载模式)
  • 定时器时钟的分频值选择,本次实验选择12分频。

#include <REGX52.H>
#include <INTRINS.H>/*** @brief  定时器0初始化函数* @param  无* @retval 无*/
void Timer0_Init()
{//TMOD = 0x01;		//TMODE寄存器,定时器T0配置为模式1,16为定时器/计数器TMOD &= 0xF0;TMOD |= 0x01;TF0 = 0; 			//TCON寄存器,TR0 = 1;			//T0定时器开始计时//每隔1ms产生一次中断,然后重新开始计数,重新计数1000次就是1秒//从 64535 开始计数,计数到 TH0 = (65535 - 1000) / 256;					//12MHz晶振,12分频TL0 = (65535 - 1000) % 256 + 1; 			////中断部分寄存器ET0 = 1;			//允许定时器T0中断EA = 1;				//允许中断PT0 = 0;			//定时器T0中断优先级
}//void Timer0Init(void)		//1毫秒@11.0592MHz
//{
//	AUXR &= 0x7F;		//定时器时钟12T模式
//	TMOD &= 0xF0;		//设置定时器模式
//	TL0 = 0x66;			//设置定时初值
//	TH0 = 0xFC;			//设置定时初值
//	TF0 = 0;			//清除TF0标志
//	TR0 = 1;			//定时器0开始计时
//}void main()
{Timer0_Init();		//定时器T0初始化P2_0 = 0;while(1){}
}/*** @brief  定时器0中断处理函数* @param  无* @retval 无*/
void Timer_Routine(void) interrupt 1
{static unsigned int count = 0;count++;//P2_0 = 0;if(count >= 500)		//定时器T0每1ms中断一次,进入1000次经过了1s{P2_0 = ~P2_0;count = 0;}//定时器溢出之后需要重新装载TH0 = (65535 - 1000) / 256;					//12MHz晶振,12分频TL0 = (65535 - 1000) % 256 + 1; 			//
}

7.2 定时器和按键实现LED流水灯左移和右移

定时器和按键实现LED流水灯左移和右移,程序设计思路:

  • 在main.c 主循环里循环检测独立按键 KEY_1/2/3/4 是否被按下。
  • 在单片机定时器中断里每隔 1 秒控制LED流水灯左移或者右移,每次按下独立按键KEY_1翻转LED流水灯的移动方向。
  • 本实验使用 Keil5 里自带的 _cror_() 循环右移和_crol_()循环左移函数。

 

💘 循环左移,循环右移和普通移位运算的区别是,循环左移每次移位的时候最高位会被移到最低位,而普通的向左移位运算最高位会被丢弃,而最低位补零。使用循环移位运算来控制LED流水灯的亮灭非常的简单。

在单片机定时器中断里使用循环移位运算来控制LED流水灯的向左移位和向右移位的源码如下,每此按下独立按键KEY_1的时候LED流水灯的方向Toggle翻转一次。

#include <REGX52.H>
#include <REGX52.H>
#include <INTRINS.H>
#include "timer0.h"
#include "key.h"unsigned char LEDMode = 0;void main()
{unsigned char keyNum;Timer0_Init();		//定时器T0初始化P2 = 0xFE;while(1){keyNum = Key();if(keyNum){if(keyNum == 1){LEDMode++;if(LEDMode >= 2)LEDMode = 0;}if(keyNum == 2) P2_2 = ~P2_2;if(keyNum == 3) P2_3 = ~P2_3;if(keyNum == 4) P2_4 = ~P2_4;}}
}/*** @brief  定时器0中断处理函数模版* @param  无* @retval 无*/
void Timer_Routine(void) interrupt 1
{static unsigned int count = 0;count++;//P2_0 = 0;if(count >= 500)		//定时器T0每1ms中断一次,进入1000次经过了1s{if(LEDMode == 0){P2 = _cror_(P2, 1);		//循环右移}else{P2 = _crol_(P2, 1);		//循环左移}count = 0;}//定时器溢出之后需要重新装载TH0 = (65535 - 1000) / 256;					//12MHz晶振,12分频TL0 = (65535 - 1000) % 256 + 1; 			//
}

7.3 单片机定时器中断实现LCD1602时钟

单片机定时器中断实现LCD1602时钟,设计如下:

#include <REGX52.H>
#include <INTRINS.H>
#include "timer0.h"
#include "lcd1602.h"static char hour = 23;
static char minute = 59;
static char second = 23;void main()
{Timer0_Init();LCD_Init();LCD_ShowString(1,1,"Clock:");while(1){LCD_ShowNum(1, 7, hour, 2);LCD_ShowChar(1, 9, ':');LCD_ShowNum(1, 10, minute, 2);LCD_ShowChar(1, 12, ':');LCD_ShowNum(1, 13, second, 2);}
}/*** @brief  定时器0中断处理函数模版* @param  无* @retval 无*/
void Timer_Routine(void) interrupt 1
{static unsigned int count = 0;count++;//P2_0 = 0;if(count >= 1000)		//定时器T0每1ms中断一次,进入1000次经过了1s{second++;if(second >= 60){ minute++; second = 0;}if(minute >= 60){hour++; minute = 0;}if(hour >= 24){hour = 0;}count = 0;}//定时器溢出之后需要重新装载TH0 = (65535 - 1000) / 256;					//12MHz晶振,12分频TL0 = (65535 - 1000) % 256 + 1; 			//
}

烧录到单片机开发板之后实际效果:

8. 总结

8.1 定时器每次溢出后需要重新装载计数器的计数值

😎😎😎定时器每次溢出后需要重新装载计数器的值。😎😎😎

因为每次定时器计数值都溢出为了0,如果不重新装载定时器计数器的值下一次计数值计数的时候就从0开始计数直到 65535 溢出,下一次中断时经过的时间就不是我们期望的时间了🤓。

相关文章:

江协科技51单片机学习- p17 定时器

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…...

【D3.js in Action 3 精译】前言

早在 2017 年&#xff0c;我还是一名渴望迈出职业生涯关键一步的前端开发者。虽然我很热衷于网站开发&#xff0c;但总感觉缺了点什么。我一直希望自己的工程专业背景和对教学的热爱能与新的编程技能相结合。就在这时&#xff0c;搭档建议我学学数据可视化。出于某种原因&#…...

Java SE入门及基础(58) 并发 进程与线程概念

目录 并发 进程和线程 1. 进程和线程 2. 进程 3.线程 总结 并发 并发(Concurrency) Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other app…...

放松一下,简简单单了

哈哈哈哈哈...

【智能制造-5】数采和电机

既然可以采集PLC的数据&#xff0c;为什么要采集电机的数据&#xff1f; 采集PLC&#xff08;可编程逻辑控制器&#xff09;的数据和采集电机的数据是两个不同的概念和目的。 PLC是用于控制和监控工业自动化过程的设备&#xff0c;它可以接收传感器的输入信号并根据预设的逻辑…...

【软考论文】论信息系统的安全性与保密性设计

目录 一、题目二、论文2.1 摘要2.2 正文三、扩展3.1 信息安全包括5个基本要素3.2 国产秘钥算法3.3 等保(信息安全等级保护)3.4 其他一、题目 在企业信息化推进的过程中,需要建设许多信息系统,这些系统能够实现高效率、低成本的运行,为企业提升竞争力。但在设计和实现这些…...

【图文教程】电脑查看显卡GPU温度方法:小白也能秒懂!

在电脑操作中&#xff0c;显卡是电脑的重要组件之一&#xff0c;其温度控制对于保持系统稳定运行是特别重要的。但是&#xff0c;许多新手用户不知道要怎么操作才能查看电脑显卡CPU的温度&#xff1f;接下来小编给大家介绍三种简单有效的查看显卡温度方法&#xff0c;操作简单&…...

Qt的智能终端项目文档完整版

由于上一篇文章已经把用户端的页面都显示了&#xff0c;这里就不在赘述&#xff0c;就将那个运行在虚拟机上的截图展示下来了&#xff0c;其实这个也就是最后的效果了。目前就是这个&#xff0c;感觉当练手的也还行...

SQL面试题练习 —— 查询最近一笔有效订单

目录 1 题目2 建表语句3 题解 题目来源&#xff1a;字节跳动。 1 题目 现有订单表t_order&#xff0c;包含订单ID&#xff0c;订单时间,下单用户&#xff0c;当前订单是否有效&#xff0c;请查询出每个用户每笔订单的上一笔有效订单 ----------------------------------------…...

分享HTML显示2D/3D粒子时钟

效果截图 实现代码 线上体验&#xff1a;three.jscannon.js Web 3D <!DOCTYPE html> <head> <title>three.jscannon.js Web 3D</title><meta charset"utf-8"><meta name"viewport" content"widthdevice-width,ini…...

Java——IDEA使用

一、IDEA介绍 IntelliJ IDEA 是 JetBrains 公司开发的一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于 Java 编程语言&#xff0c;但也支持多种其他语言和框架。由于其强大的功能和灵活性&#xff0c;IntelliJ IDEA 被广泛应用于软件开发领域&…...

高性能STL库 EASTL 、高性能JSON库

GitHub - electronicarts/EASTL: EASTL stands for Electronic Arts Standard Template Library. It is an extensive and robust implementation that has an emphasis on high performance. 兄弟们&#xff0c;对STL要求性能高的可以试试这个EASTL库&#xff01;&#xff01…...

多通道采集器采样接口设计[进行中...]

1.技术问题 这是一个非常小的设计&#xff0c;完全不值得把它展示出来。但是因为这个接口设计关系到一些细微的配置和技术限制&#xff0c;仍然有一些细节需要处理&#xff0c;并且很容易出错&#xff0c;我们先把技术问题罗列一下&#xff1a; 多个传感器对应的多个逻辑通道…...

rapidjson使用中crash问题分析

问题 在使用rapidjson时&#xff0c;使用Document的Parse方法解析json字符串&#xff0c;程序crash。 分析 可以参考https://github.com/Tencent/rapidjson/issues/1269&#xff0c;由于rapidjson的内存分配器默认认为内存分配成功&#xff0c;没有对分配后做判空判断&#…...

TCP协议中的三次握手和四次挥手机制

TCP协议中的三次握手和四次挥手机制 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的通信协议&#xff0c;它的三次握手和四次挥手机制是建立和断开连接的关键步骤。 三次握手&#xff1a; 第一次…...

Linux双网卡默认路由的metric设置不正确,导致SSH连接失败问题定位

测试环境 VMware虚拟机 RockyLinux 9 x86_64 双网卡&#xff1a;eth0(访问外网): 10.206.216.92/24; eth1(访问内网) 192.168.1.4/24 问题描述 虚拟机重启后&#xff0c;SSH连接失败&#xff0c;提示"Connection time out"&#xff0c;重启之前SSH连接还是正常的…...

Batch入门学习:从零开始掌握批处理脚本

目录 1. Batch脚本简介 1.1 什么是Batch脚本&#xff1f; 1.2 Batch脚本的历史 1.3 Batch脚本的应用场景 2. Batch脚本基本语法 2.1 注释 2.2 变量 2.3 常用命令 2.3.1 ECHO 2.3.2 PAUSE 2.3.3 CLS 2.3.4 GOTO 2.3.5 IF 2.3.6 FOR 2.4 参数传递 2.5 输入输出重…...

diffusion model(十八):diffusion model中negative prompt的工作机制

info个人博客主页http://myhz0606.com/article/ncsn 前置阅读&#xff1a; DDPM&#xff1a; http://myhz0606.com/article/ddpm classifier-guided&#xff1a;http://myhz0606.com/article/guided classifier-free guided&#xff1a;http://myhz0606.com/article/classi…...

Python | Leetcode Python题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; class Solution:def dfs(self, grid, r, c):grid[r][c] 0nr, nc len(grid), len(grid[0])for x, y in [(r - 1, c), (r 1, c), (r, c - 1), (r, c 1)]:if 0 < x < nr and 0 < y < nc and grid[x][y] "1":self.d…...

利用圆上两点和圆半径求解圆心坐标

已知圆上两点P1&#xff0c;P2&#xff0c;坐标依次为 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1​,y1​),(x2​,y2​)&#xff0c;圆的半径为 r r r&#xff0c;求圆心的坐标。 假定P1&#xff0c;P2为任意两点&#xff0c;则两点连成线段的中点坐标是 x m i …...

岗亭厂家直销:揭秘源头工厂如何帮你省下30%采购成本

在2026年1月的今天&#xff0c;户外岗亭作为城市管理、社区安防及商业服务的关键节点&#xff0c;其市场需求持续增长。然而&#xff0c;行业在快速发展的同时&#xff0c;也暴露出一些亟待解决的技术与成本挑战。从技术层面看&#xff0c;传统岗亭产品普遍面临结构稳定性不足、…...

多层PCB结构与设计核心技术解析

多层PCB内部结构解析与设计指南1. 多层PCB技术概述1.1 多层PCB的基本概念现代电子设备对电路板的要求越来越高&#xff0c;多层PCB已成为复杂电子系统的标准配置。与单层或双层PCB相比&#xff0c;多层PCB通过在绝缘基材上叠加多个导电层&#xff0c;实现了更高的布线密度和更优…...

图像转3D模型:零基础制作个性化浮雕的完整指南

图像转3D模型&#xff1a;零基础制作个性化浮雕的完整指南 【免费下载链接】ImageToSTL This tool allows you to easily convert any image into a 3D print-ready STL model. The surface of the model will display the image when illuminated from the left side. 项目地…...

Mplus实战:如何用随机截距交叉滞后模型(RI-CLPM)分析心理学纵向数据?

Mplus实战&#xff1a;随机截距交叉滞后模型&#xff08;RI-CLPM&#xff09;在心理学纵向研究中的深度应用 心理学研究中&#xff0c;我们常常需要探索变量间的动态相互作用——比如焦虑和睡眠问题如何相互影响&#xff1f;传统交叉滞后模型&#xff08;CLPM&#xff09;虽然广…...

遇到‘Got minus one from a read call‘别慌!Oracle 12c连接数优化全攻略

深度解析Oracle 12c连接数优化&#xff1a;从"Got minus one from a read call"到高可用架构 当Java应用突然抛出java.sql.SQLRecoverableException: IO Error: Got minus one from a read call异常时&#xff0c;这往往是数据库连接资源耗尽的信号。本文将带您深入O…...

Qwen3.5-4B-Claude-Opus保姆级教程:Web界面响应延迟归因与优化路径

Qwen3.5-4B-Claude-Opus保姆级教程&#xff1a;Web界面响应延迟归因与优化路径 1. 模型与部署环境概览 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B的推理蒸馏模型&#xff0c;特别强化了结构化分析、分步骤回答以及代码与逻辑类问题的处理能力。该…...

OpCore Simplify:零基础黑苹果配置的智能助手

OpCore Simplify&#xff1a;零基础黑苹果配置的智能助手 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 对于许多电脑爱好者来说&#xff0c;安装黑苹…...

答辩 PPT 不用熬!PaperXie AI PPT 让毕业论文答辩赢在 “门面”

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 又到毕业冲刺季&#xff0c;当论文终于敲下最后一个句号&#xff0c;毕业论文答辩 PPT却成了新的 “熬夜重灾区”&#xff1a…...

农业IoT部署卡在MQTT连接失败?Python异步通信优化全链路解析(含田间实测吞吐量对比数据)

第一章&#xff1a;农业IoT部署卡在MQTT连接失败&#xff1f;Python异步通信优化全链路解析&#xff08;含田间实测吞吐量对比数据&#xff09;在华北平原某智慧农场的边缘网关部署中&#xff0c;23台土壤温湿度传感器频繁出现MQTT连接超时与会话重置现象&#xff0c;平均重连耗…...

SEO_为什么你的网站需要SEO?关键原因解析

<h3 id"seoseo">SEO:为什么你的网站需要SEO&#xff1f;关键原因解析</h3> <p>在当今数字化时代&#xff0c;拥有一个网站是企业或个人展示品牌、产品和服务的重要途径。仅仅拥有一个网站并不足以吸引足够的访问量和客户。这时&#xff0c;SEO&…...