学习笔记|计数器|Keil软件中 0xFD问题|I/O口配置|STC32G单片机视频开发教程(冲哥)|第十二集:计数器的作用和意义

文章目录

  • 1.计数器的用途
  • 2.计数器的配置
    • 官方例程
    • 开始
    • Tips:编译时提示错误FILE DOES NOT EXIST:
  • 3.计数器的应用
  • 本例完整代码:
  • 总结
  • 课后练习:

1.计数器的用途

直流有刷的电机,后面两个一正一负的电接上,电机就可以转
在这里插入图片描述

到底是转子个几个圈呢?
我们就可以在背后加装这么一个码盘,我们假设这里是有60个这个光电的一个孔对吧
那我们转一圈是不是就可以一个轴上输出60个这样的脉冲,有遮挡就输出1,无遮挡输出0,
两路交替,如果说这圈有60个脉冲,60个高低电平(总共几个脉冲除60就是转的圈数)
本节利用开关,模拟计数器的功能。
编码器也可以实现脉冲输出,输出波形:方波
流过了多少液体,中间有个比例变化。一高一低算一个脉冲。
只要输出信号带这种高低电平变化的,想要计算个数的就可以用计数器的功能
在这里插入图片描述

2.计数器的配置

在这里插入图片描述

当GATE=O(TMOD.7)时,如TR1=1,则定时器计数。GATE=1时,允许由外部输入INT1控制定时器1,
这样可实现脉宽测量。TR1为TCON寄存器内的控制位,TCON寄存器各位的具体功能描述见上节TCON寄存器的介绍。
当c/T=0时,多路开关连接到系统时钟的分频输出,Tl对内部系统时钟计数,T1工作在定时方式
当C/T=1时,多路开关连接到外部脉冲输入P3.5/T1,即 T1工作在计数方式。
STC单片机的定时器1有两种计数速率:一种是12T模式,每12个时钟加1,与传统8051单片机相同;另外一种是1T模式,每个时钟加1,速度是传统8051单片机的12倍。T1的速率由特殊功能寄存器AUXR中的T1x12决定,如果T1x12=0,T1则工作在12T模式;如果T1x12=1,T1则工作在1T模式定时器1有两个隐藏的寄存器RL_TH1和RL_TL1。RL_TH1与TH1共有同一个地址,RL_TL1与TL1共有同一个地址。当TRI=0即定时器/计数器Ⅰ被禁止工作时,对TLl写入的内容会同时写入RL_TLl,对
TH1写入的内容也会同时写入RL_TH1。当TR1=1即定时器/计数器Ⅰ被允许工作时,对TLl写入内容,实际上不是写入当前寄存器TL1中,而是写入隐藏的寄存器RL_TL1中,对THl 写入内容,实际上也不是写入当前寄存器TH1中,而是写入隐藏的寄存器RL_THl,这样可以巧妙地实现16位重装载定时器。当读THl和TL1的内容时,所读的内容就是TH1和TL1的内容,而不是RL_TH1和RL_TLl的内容。
当定时器1工作在模式1(TMOD[5:4][M1.MO]=00B)时,[THl,TL1l]的溢出不仅置位TF1,而且会自动将[RL_TH1,RL_TL1]的内容重新装入[TH1,TL1]。
当T1CLKO/INT_CLKO.1=1时,P3.4/TO管脚配置为定时器1的时钟输出T1CLKO。输出时钟频率为T1溢出率/2。
如果C/T=0,定时器/计数器T1对内部系统时钟计数,则:
T1工作在1T模式(AUXR.6/T1x12=1)时的输出时钟频率=(SYsclk)(TM1PS+1)(65536-[RL_TH1,RL_TL1])/2T1工作在12T模式(AUXR.6/TIx12=0)时的输出时钟频率=(SYSclk)(TM1PS+1)/12/(65536-[RL_TH1,RL_TLI])/2如果C/T=1,定时器/计数器T1是对外部脉冲输入(P3.5/Tl)计数,则:输出时钟频率=(Tl_Pin_CLK)/(65536-[RL_TH1,RL_TL1])/2

Tl_C/T:Tl_C/T位写1,控制定时器1用作定时器或计数器,清0则用作定时器(对内部系统时钟进行计数),置1用作计数器(对引脚T1/P3.5外部脉冲进行计数)。
Tl_GATE:控制定时器1,置1时只有在INT1脚为高及TRI控制位置1时才可打开定时器/计数器1。此处仅需要TR1计数,故可以将Tl_GATE置0.

官方例程

在这里插入图片描述
在这里插入图片描述
设置TMOD = 0X40 =0100 0000 ,即Tl_C/T置1,用作计数。16位自动重载。
TL1 = 0xff; //1111 1111,65535,相当于再来1个脉冲,就可以进一下中断,给引脚取反。每来一个脉冲,取反一次。
TH1 = 0xff;

开始

用按钮模拟,松开是高电平,然后不断的按下松开按下松开。
选用例程作为参考:
在这里插入图片描述

需要打开内部4K的上拉电阻打开,用到端口上拉电阻控制寄存器(PxPU):在这里插入图片描述

在这里插入图片描述

STC-ISP软件中有这个IO口的一个配置工具:
在这里插入图片描述

利用上一节的例程,改名为8.计数器,可以用T1来实现。
将void Timer0_Isr(void) interrupt 1屏蔽,调用T0中断屏蔽,本节不需要。
按手册上的例程顺序编写。

Tips:编译时提示错误FILE DOES NOT EXIST:

在这里插入图片描述

C251 FATAL-ERROR -ACTION:  OPENING INPUT-FILEFILE:    \STC32\8.计势鱘COMM\stc32g.hERROR:   FILE DOES NOT EXIST
C251 TERMINATED.

这里涉及“附录I关于Keil软件中 0xFD问题的说明”。

Keil项目路径名的字符中也不能含有带OxFD编码的汉字,否则Keil软件会无法正确编译此项目。故需要修改本工程的目录名:
改为英文名:8.Count_T1,编译正常通过,按键led循环亮灭。
课后可以试验一下通过改变H1跟TL1的值,实现2下亮灭。
这个值的确定可以使用STC-ISP中的I/O口配置工具,高级配置,设置条件:
在这里插入图片描述

得到设置代码: P3PU = 0x20;

3.计数器的应用

见2017年全国大学生电子设计竞赛试题 ——直流电动机测速装置(O题),题目如下
在这里插入图片描述

解题思路如下:
在这里插入图片描述

M法测速:又叫做频率测量法。这种方法是在一个固定的定时时间内(以秒为单位),统计这段时间的编码器脉冲数,计算速度值。设编码器单圈总脉冲数为C, 时间T0内,统计到的编码器脉冲数为M0,则转速n的计算公式为:
在这里插入图片描述

首先我们定义一个变量叫u16 Count_T1 = 0;初值设置为0。
改写中断处理函数:void Timer0_Isr(void) interrupt 1:

void Timer0_Isr(void) interrupt 1 //1ms进来执行一次,无需其他延时,重复赋值
{TimCount++; //计算2000次=2s,可以一直运行if(TimCount>= 2000){TimCount = 0;Count_T1 = (TH1 * 256) + TL1; //单位:转/s,TH1 = 0;TL1 = 0;Show_Tab[4] = TimCount/1000%10;Show_Tab[5] = TimCount/100%10+10;Show_Tab[6] = TimCount/10%10;Show_Tab[7] = TimCount/1%10;		//取10位}SEG_Fre();		//计算得到结果后,数码管刷新}

本例完整代码:

#include "COMM/stc.h"		//调用头文件
#include "COMM/usb.h"#define KEY1 P32		//定义一个按键 引脚选择P32
#define KEY2 P33		//定义一个按键 引脚选择P33#define BEEP P54		//定义一个按键 引脚选择P54#define SEG_Delay  1	//延时多少ms#define MAIN_Fosc 24000000UL	//定义主时钟char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";u8 SEG_Tab[21] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};	//0-9段码,0-9带小数点
u8 COM_Tab[8] = { 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe };	//0-7的位码数组
u8 Show_Tab[8] = {20,20,20,20,0,0,0,0};u32 TimCount = 0;		//计数单位1ms
bit RUN_State = 0;		//开始运行/结束运行
u8 num = 0;u16 Count_T1 = 0;void sys_init();	//函数声明
void delay_ms(u16 ms);	//unsigned int void SEG_Fre( void ) 
{//位码选择第一位,段码选择0  P7 = COM_Tab[num];			//位码的选择P6 = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码 赋给 P6   NUM =0 -> Show_Tab[num]] = 1 -> p6 = oxF9 //delay_ms(SEG_Delay);num++;if( num >7 )num = 0;	
}//========================================================================
// 函数名称: Timer0_Init
// 函数功能: 定时器0初始化
// 入口参数: 无
// 函数返回: 无
// 当前版本: VER1.0
// 修改日期: 2023
// 当前作者: 
// 其他备注: 
//========================================================================
void Timer0_Init(void)		//1毫秒@24.000MHz
{AUXR &= 0x7F;			//定时器时钟12T模式TMOD &= 0xF0;			//设置定时器模式TL0 = 0x30;				//设置定时初始值TH0 = 0xF8;				//设置定时初始值TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时ET0 = 1;				//使能定时器0中断
}void main()					//程序开始运行的入口
{sys_init();				//USB功能+IO口初始化usb_init();				//usb库初始化TMOD = 0x50;			//设置计数器模式   TL1 = 0x00;				//设置计数初始值TH1 = 0x00;				//设置计数初始值TF1 = 0;				//清除TF1标志TR1 = 1;				//定时器1开始计时ET1 = 1;				//使能定时器1中断P3PU = 0x20; 			//打开内部上拉4.1KTimer0_Init();EA = 1;					//CPU开放中断,打开总中断。while(1)		//死循环{if( DeviceState != DEVSTATE_CONFIGURED ) 	//continue;if( bUsbOutReady )								{usb_OUT_done();}}
}void Timer0_Isr(void) interrupt 1
{TimCount++;			//每隔1ms+1		//	计数到2000 = 2sif( TimCount>=2000 )		//2秒定时时间到了{TimCount = 0;Count_T1 = (TH1 *256 )+ TL1;		// 转/2s  转/minTH1 = 0;TL1 = 0;Show_Tab[4] = Count_T1/1000%10;Show_Tab[5] = Count_T1/100%10;	Show_Tab[6] = Count_T1/10%10;		Show_Tab[7] = Count_T1/1%10;		//取10位 }SEG_Fre();		//数码管刷新的
}void Timer1_Isr(void) interrupt 3
{}/*11111110 0XFE11111101 0XFD11111011 0XFB11110111 0XF711101111 0XEF11011111 0XDF10111111 0XBF01111111 0X7F
*/void sys_init()		//函数定义
{WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快EAXFR = 1; //扩展寄存器(XFR)访问使能CKCON = 0; //提高访问XRAM速度P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口P3M0 = 0x00;P3M1 = 0x00;P3M0 &= ~0x03;P3M1 |= 0x03;//设置USB使用的时钟源IRC48MCR = 0x80;    //使能内部48M高速IRCwhile (!(IRC48MCR & 0x01));  //等待时钟稳定USBCLK = 0x00;	//使用CDC功能需要使用这两行,HID功能禁用这两行。USBCON = 0x90;
}void delay_ms(u16 ms)	//unsigned int 
{u16 i;do{i = MAIN_Fosc/6000;while(--i);}while(--ms);
}

总结

了解计数器的使用方法和应用场景

课后练习:

尝试实现T法测速:又叫做周期测量法。这种方法是建立一个已知频率的高频脉冲并对其计数,计数时间由捕获到的编码器相邻两个脉冲的间隔时间TE决定, 计数值为M1。设编码器单圈总脉冲数为C,高频脉冲的频率为F0,则转速n的计算公式为:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UNIX网络编程卷一 学习笔记 第三十一章 流

在大多数源自SVR 4的内核中,X/Open传输接口(X/Open Transport Interface,XTI,是独立于套接字API的另一个网络编程API)和网络协议通常就像终端IO系统那样也使用流系统(STREAMS system)实现。 我…

Nginx__基础入门篇

目录: Nginx的优势 HTTP协议详解 Nginx部署-Yum Nginx配置文件 Nginx编译参数 Nginx基本配置 Nginx日志Log Nginx WEB模块 Nginx 访问限制 Nginx 访问控制 Nginx的优势 Nginx (engine x) 是一个高性能的HTTP(解决C10k的问题)和反向代理服务器,也是一个IM…

leetcode 205. 同构字符串

2023.9.6 本题维护两个映射表map&#xff0c;若发现无法对应则返回false。 代码如下&#xff1a; class Solution { public:bool isIsomorphic(string s, string t) {unordered_map<char,char> m1;unordered_map<char,char> m2;for(int i0; i<s.size(); i){//相…

ctfshow vip题目限免

源码泄露 右键查看源代码即可得到flag 前台JS绕过 解法一 URL前面加上view-source: 解法二 题目描述说禁用js&#xff0c;那就禁用就行 然后和前面一样右键查看就行 协议头信息泄露 提示抓包&#xff0c;那就抓包吧 抓包直接就在返回包获得flag了 robots后台泄露 robot…

java获取jenkins发布版本信息

一.需求&#xff1a; 系统cicd发布时首页需要展示jenkins发布的版本和优化内容 二.思路: 1.jenkins创建用户和秘钥 2.找到对应构建任务信息的api 3.RestTemplate发起http请求 三.实现&#xff1a; 1.创建用户和token 2.查找jenkins API 创建 Job POST http://localhost…

Linux查端口占用的几种方式

在Linux中&#xff0c;你可以使用以下几种方式来查看端口的占用情况。 一、使用netstat命令 #安装netstat yum -y install net-tools #检测端口占用 netstat -npl | grep 端口# 几种常规用法 netstat -ntlp //查看当前所有tcp端口 netstat -ntulp | grep 80 //查看所有80端…

layui引入百度地图

<script type"text/javascript" src"//api.map.baidu.com/api?typewebgl&v1.0&ak你的ak"></script> <script src"https://code.bdstatic.com/npm/jquery1.12.4/dist/jquery.min.js"></script> <script src&…

看涨期权计算例题(期权案例计算)

看涨期权又称认购期权&#xff0c;买进期权&#xff0c;买方期权&#xff0c;买权&#xff0c;延买期权&#xff0c;或“敲进”&#xff0c;是指期权的购买者拥有在期权合约有效期内按执行价格买进一定数量标的物的权利&#xff0c;下文为大家科普看涨期权计算例题&#xff08;…

LLVM 与代码混淆技术

项目源码 什么是 LLVM LLVM 计划启动于2000年&#xff0c;开始由美国 UIUC 大学的 Chris Lattner 博士主持开展&#xff0c;后来 Apple 也加入其中。最初的目的是开发一套提供中间代码和编译基础设施的虚拟系统。 LLVM 命名最早源自于底层虚拟机&#xff08;Low Level Virtu…

ComfyUI 安装

背景&#xff1a; stable diffussion XL最先适配&#xff0c;专业性强的SD操作界面 安装步骤&#xff1a; git clone GitHub - comfyanonymous/ComfyUI: A powerful and modular stable diffusion GUI with a graph/nodes interface. 1、pip install torch torchvision torc…

window11,C盘瘦身减肥技巧

前言 本文主要说明windows11的C盘空间优化技巧&#xff0c;也叫减肥瘦身&#xff0c;目标&#xff1a;20G以内。绝大部分内容&#xff0c;也适用于window10和windows7&#xff0c;只是操作系统不同&#xff0c;操作方式略有不同。不关注C盘空间的读者&#xff0c;可以忽略此文…

2023年数维杯数学建模A题河流-地下水系统水体污染研求解全过程文档及程序

2023年数维杯数学建模 A题 河流-地下水系统水体污染研 原题再现&#xff1a; 河流对地下水有着直接地影响&#xff0c;当河流补给地下水时&#xff0c;河流一旦被污染&#xff0c;容易导致地下水以及紧依河流分布的傍河水源地将受到不同程度的污染&#xff0c;这将严重影响工…

sentinel加密狗使用及规则配置

Sentinel加密狗是一种硬件加密设备&#xff0c;用于保护软件应用程序免受未经授权的访问和复制。它可以提供软件许可管理、访问控制和数据保护等功能。下面是Sentinel加密狗的使用及规则配置的相关介绍。 Sentinel加密狗的使用 插入加密狗&#xff1a;将Sentinel加密狗插入计算…

基于语雀编辑器的在线文档编辑与查看

概述 语雀是一个非常优秀的文档和知识库工具&#xff0c;其编辑器更是非常好用&#xff0c;虽无开源版本&#xff0c;但有编译好的可以使用。本文基于语雀编辑器实现在线文档的编辑与文章的预览。 实现效果 实现 参考语雀编辑器官方文档&#xff0c;其实现需要引入以下文件&…

Google Earth Engine 的缺点和限制

随着 Google Earth Engine 在地球科学和数据计算领域越来越流行&#xff0c;网上有很多介绍Google Earth Engine 的文章及 Google Earth Engine的追随者。Google Earth Engine确实是一款伟大的产品&#xff0c;我们应该为其点赞。但由于已经有太多人在热捧了&#xff0c;我这里…

数据库设计:防止MySQL字段名与关键字相撞,保护数据完整性!

MySQL是一款广泛应用的关系型数据库管理系统&#xff0c;对于数据库设计而言&#xff0c;字段名的选择是至关重要的一环。不小心选择了和MySQL关键字相同的字段名可能导致严重的数据完整性问题。下面将深入探讨如何防止MySQL字段名与关键字相撞&#xff0c;以保护数据的完整性。…

报错: “Data is Null. This method or property cannot be called,解决方法

在进行导入的时候报错 System.Data.SqlTypes.SqlNullValueException: "Data is Null. This method or property cannot be called on Null values."是一个在使用DataReader.GetString(i)方法时出现的异常情况。当对应字段的值为Null时&#xff0c;这个方法会抛出异常…

用户案例 | 蜀海供应链基于 Apache DolphinScheduler 的数据表血缘探索与跨大版本升级经验

导读 蜀海供应链是集销售、研发、采购、生产、品保、仓储、运输、信息、金融为一体的餐饮供应链服务企业。2021年初&#xff0c;蜀海信息技术中心大数据技术研发团队开始测试用DolphinScheduler作为数据中台和各业务产品项目的任务调度系统工具。本文主要分享了蜀海供应链在海…

【Node.js】—基本知识点总结

【Node.js】—基本知识总结 一、命令行常用操作 二、Node.js注意点 Node.js中不能使用BOM和DOM操作 总结 三、Buffer buffer是一个类似于数组的对象&#xff0c;用于表示固定长度的字节序列buffer的本质是一段内存空间&#xff0c;专门用来处理二进制数据 特点&#xff1a;…

postgresql-子查询

postgresql-子查询 子查询简介派生表IN 操作符ALL 操作符ANY 操作符关联子查询横向子查询EXISTS 操作符 子查询简介 子查询&#xff08;Subquery&#xff09;是指嵌套在其他 SELECT、INSERT、UPDATE 以及 DELETE 语句中的 查询语句 子查询的作用与多表连接查询有点类似&#x…