STC89C52RC/LE52RC
STC89C52RC
- 芯片手册
- 原理图
- 扩展版原理图
- 功能示例
- LED灯
- ==LED灯的常亮效果==
- ==LED灯的闪烁==
- ==LED灯的跑马灯效果:从左到右,从右到左==
- 数码管
- 静态数码管
- 数码管计数
- App.c
- App.h
- Com.c
- Com.h
- Dir.c
- Dir.h
- Int.c
- Int.h
- Mid.c
- Mid.h
- 模板
- mian.c
- App.c
- App.h
- Com.c
- Com.h
- Dir.c
- Dir.h
- Int.c
- Int.h
- Mid.c
- Mid.h
芯片手册
STC89C52
原理图
扩展版原理图
扩展版原理图
功能示例
LED灯
LED灯的常亮效果
# include <STC89C5xRC.H>
void main(){//将LED连接的P00端口设置为0P00 =0;while(1);
}
LED灯的闪烁
/*----------------------------------------------------------* 文件名:LED_FlowLight.c* 功能:STC89C52RC单片机控制的LED流水灯程序(单向左移循环)* 硬件连接:P0口接8个共阳LED,P4.6控制蜂鸣器* 作者:[您的名字]* 日期:[创建日期]*---------------------------------------------------------*/#include <STC89C5xRC.H> // 包含STC89C52RC系列单片机寄存器定义头文件
#include <INTRINS.H> // 包含内部函数库(提供_nop_()空指令)/* 类型重定义(增强可读性)*/
typedef unsigned char u8; // 定义无符号8位数据类型(范围0~255)
typedef unsigned int u16; // 定义无符号16位数据类型(范围0~65535)/* 函数声明 */
void Delayms(u16 count); // 毫秒级延时函数声明/*----------------------------------------------------------* 主函数*---------------------------------------------------------*/
void main()
{// 变量初始化u8 temp = 0x01; // 初始化LED位置(二进制00000001,对应最右侧LED)// 注:实际是P0.0对应第一个LED,P0.7对应第八个LEDP46 = 0; // 关闭蜂鸣器(硬件设计缺陷,P4.6低电平关闭蜂鸣器)// 如果不设置,上电时可能产生噪音while (1) // 主循环(单片机程序必须包含无限循环){/* LED显示控制 */P0 = ~temp; // 输出到P0口控制LED:// - 取反操作是因为采用共阳接法(端口输出0时LED亮)// - 例如temp=0x01(00000001),取反后=0xFE(11111110),// 即P0.0输出0,对应LED点亮/* 更新LED位置 */temp <<= 1; // 左移一位,实现LED流水效果// 例如:0x01→0x02→0x04→...→0x80/* 循环检测 */if (temp == 0) // 当左移超出8位时(0x80<<1会变成0x00){temp = 0x01; // 重新从最右侧开始}/* 延时控制流水速度 */Delayms(100); // 延时100ms(控制LED移动速度)}
}/*----------------------------------------------------------* 函数名称:Delayms* 功能:实现毫秒级延时* 参数:count - 需要延时的毫秒数* 说明:针对12MHz晶振校准,其他频率需调整参数*---------------------------------------------------------*/
void Delayms(u16 count)
{/* 变量定义(使用data关键字将变量存储在内部RAM,提高访问速度)*/u8 data i, j; while (count--) // 外层循环(控制总延时毫秒数){_nop_(); // 空指令(消耗1个机器周期,12MHz下=1us)// 用于微调延时精度/* 双重循环实现精确延时 */i = 2;j = 199;do{while (--j); // 内层循环1(约199×3个机器周期)} while (--i); // 内层循环2(外层循环2次)/* * 延时计算(12MHz时钟):* - 1机器周期=1us* - 内层循环:199×3 = 597us* - 外层循环:2×597 = 1194us ≈ 1ms* - 总延时:count × 1ms*/}
}
LED灯的跑马灯效果:从左到右,从右到左
#include <STC89C5xRC.H> // 包含STC89C52RC系列单片机头文件
#include <INTRINS.H> // 包含 intrinsics 函数(如_nop_)typedef unsigned char u8; // 定义无符号8位数据类型(0~255)
typedef unsigned int u16; // 定义无符号16位数据类型(0~65535)// 函数声明
void Delayms(u16 count); // 毫秒级延时函数声明void main()
{// 变量初始化u8 temp = 0x01; // 初始灯位(00000001,最右侧LED亮)bit is_left = 1; // 方向标志(1=左移,0=右移)while (1) // 主循环{P0 = ~temp; // 输出到P0口(取反因为LED共阳接法)// 根据移动方向更新灯位if (is_left) {temp <<= 1; // 左移一位(LED向左移动)} else {temp >>= 1; // 右移一位(LED向右移动)}// 检测边界条件并改变方向if (temp == 0x80) { // 当移动到最左端(10000000)is_left = 0; // 改为右移方向}if (temp == 0x01) { // 当移动到最右端(00000001)is_left = 1; // 改为左移方向}Delayms(100); // 延时100ms控制移动速度}
}/*** @brief 毫秒级延时函数* @param count 延时毫秒数* @note 针对12MHz晶振校准,其他频率需要调整参数*/
void Delayms(u16 count)
{u8 data i, j; // 使用data关键字将变量存储在内部RAMwhile (count--) // 外层循环(毫秒级){_nop_(); // 空指令(4个时钟周期)i = 2;j = 199;do // 内层循环(微秒级){while (--j); // 约100us} while (--i); // 组合成约1ms延时}
}
数码管
静态数码管
#include <STC89C5xRC.H> // 包含STC89C52RC系列单片机头文件
#include <INTRINS.H> // 包含 intrinsics 函数(如_nop_)typedef unsigned char u8; // 定义无符号8位数据类型
typedef unsigned int u16; // 定义无符号16位数据类型
typedef unsigned long u32; // 定义无符号32位数据类型// 函数声明
void DigitalTube_setBuffer(u32 number); // 设置数码管显示缓冲区
void DigitalTube_Single(u8 pos, u8 number); // 控制单个数码管显示
void DigitalTube_Refresh(); // 刷新整个数码管显示
static void Delayms(u16 count); // 毫秒级延时函数(static限制作用域)// 数码管段选码(共阴数码管0-9,对应a~dp段)
// 编码格式:gfedcba(P0.0~P0.6),最高位P0.7为小数点
const u8 number_codes[10] = {0x3F, // 0 - 001111110x06, // 1 - 000001100x5B, // 2 - 010110110x4F, // 3 - 010011110x66, // 4 - 011001100x6D, // 5 - 011011010x7D, // 6 - 011111010x07, // 7 - 000001110x7F, // 8 - 011111110x6F // 9 - 01101111
};u8 digital_buffer[8]; // 数码管显示缓冲区(存储8位数码管的段选值)void main()
{// 初始化IO口// P0 = 0x00; // 段选初始化为全灭(注释掉,实际在刷新函数中处理)// P1 = 0xC7; // 位选初始化为全灭(P1.3-P1.5控制位选,11000111)P46 = 0; // 可能的总使能信号(低电平有效)P36 = 0; // 数码管使能信号(低电平有效)P34 = 1; // 关闭流水灯(高电平关闭)DigitalTube_setBuffer(99998888); // 设置初始显示值为250while (1){DigitalTube_Refresh(); // 持续刷新数码管显示}
}/*** @brief 设置数码管显示缓冲区内容* @param number 要显示的数字(最大支持8位数)* @note 数字将右对齐显示,不显示前导零*/
void DigitalTube_setBuffer(u32 number)
{u8 i;// 1. 清空缓冲区(全部显示空白)for (i = 0; i < 8; i++) {digital_buffer[i] = 0; // 0表示不显示任何段}// 2. 从最右侧开始填充数字(右对齐)for (i = 7; i >= 0; i--) {digital_buffer[i] = number_codes[number % 10]; // 获取当前位的段码number /= 10; // 移除已处理的最低位if (number == 0) break; // 数字已处理完毕则退出}
}/*** @brief 控制单个数码管显示* @param pos 数码管位置(0-7对应位选)* @param number 要显示的段码值* @note 使用P1.3-P1.5控制3-8译码器选择位选*/
void DigitalTube_Single(u8 pos, u8 number)
{// 1. 位选控制(通过P1.3-P1.5)pos <<= 3; // 左移3位,将0-7映射到P1.3-P1.5P1 &= 0xC7; // 11000111 - 清除位选位(P1.3-P1.5)P1 |= pos; // 设置新的位选// 2. 段选输出P0 = number; // 输出段码值到P0口
}/*** @brief 刷新整个数码管显示(动态扫描)* @note 采用循环扫描方式,每位显示1ms*/
void DigitalTube_Refresh()
{u8 i = 0;while (i <= 7) // 扫描0-7共8位数码管{DigitalTube_Single(i, digital_buffer[i]); // 显示当前位Delayms(1); // 保持显示1msi++;}
}/*** @brief 毫秒级延时函数* @param count 延时毫秒数* @note 使用static限制只在本文件使用,防止命名冲突*/
static void Delayms(u16 count)
{u8 data i, j;while (count--){_nop_(); // 空指令,用于精确延时i = 2;j = 199;do{while (--j); // 内层循环延时} while (--i); // 外层循环延时}
}
数码管计数
mian.c
#include ".\Com\Com_Util.h"
#include ".\Int\Int_DigitalTube.h"// 主函数
void main()
{u8 num = 100;u8 count = 0;u8 i=0;P46 = 0; // 关闭蜂鸣器// 初始化数码管Int_DigitalTube_Init();//设置要显示的数字Int_DigitalTube_setBuffer(num);//死循环while (1){Int_DigitalTube_setBuffer(num);while (count <= 100){Int_DigitalTube_Refresh();count++;}if (num > 0){num--;count=0;}else if (num == 0){while (1){Int_DigitalTube_setBuffer(0);}}}
}
App.c
App.h
Com.c
#include "Com_Util.h"// 延时函数,指定延时多少毫秒
void Delayms(u16 count)
{u8 data i, j;while (count){_nop_();i = 2;j = 199;do{while (--j);} while (--i);count--;}
}
Com.h
#ifndef __COM_UTIL_H__
#define __COM_UTIL_H__#include <STC89C5xRC.H>
#include <INTRINS.H>// 类型别名
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;/*** @brief 延时函数,指定延时多少毫秒** @param count 指定多少毫秒*/
void Delayms(u16 count);#endif
Dir.c
Dir.h
Int.c
#include "Int_DigitalTube.h"// 定义数组,保存每个数字的段选信息
static u8 s_number_codes[10] = {0x3F, // 00x06, // 10x5B, // 20x4F, // 30x66, // 40x6D, // 50x7D, // 60x07, // 70x7F, // 80x6F // 9
};// 定义数组,8个元素,对应数码管8个位置; 每个元素存储数字的段选信息
static u8 s_digital_buffer[8];/*** @brief 数码管初始化*/
void Int_DigitalTube_Init()
{// 打开数码管开关P36 = 0;// 关闭流水灯P34 = 0;
}/*** @brief 将指定的整数设置到数码管显示缓存中(s_digital_buffer数组)** @param number*/
void Int_DigitalTube_setBuffer(u32 number)
{u8 i;// 1. 清空之前的显示内容for (i = 0; i < 8; i++){s_digital_buffer[i] = 0x00;}// 2. 依次取出number中每位上的数,将其段选信息存储数组;最低位存入最后一个元素for (i = 7;; i--){// 取出当前位上的数,将其段选信息存入数组指定位置s_digital_buffer[i] = s_number_codes[number % 10];// 处理number,去掉最低位number /= 10;// 如果number变为0,说明数字已经取完,停止循环if (number == 0 || i == 0){break;}}
}/*** @brief 数码管指定位置指定数字** @param pos 位置,使用数字0~7分别表示从左边数第1到到第8个* @param code 数字的段选信息*/
void Int_DigitalTube_Single(u8 pos, u8 number_code)
{// 1. 位选 -------------------------------// 1.1 pos 左移3位, 与P15、P14、P13 对齐pos <<= 3;// 1.2 将P1的P15、P14、P13三位置0,其他位保持不变, P1 & 0b11000111P1 &= 0xC7;// 1.3 将pos上的三位有效数, 赋值到 P15、P14、P13 位置上P1 |= pos;// 2. 段选 --------------------------------P0 = number_code;
}/*** @brief 刷新数码管**/
void Int_DigitalTube_Refresh()
{// 循环0到7u8 i;for (i = 0; i <= 7; i++){Int_DigitalTube_Single(i, s_digital_buffer[i]);Delayms(1);}
}
Int.h
#ifndef __INT_DIGITALTUBE_H__
#define __INT_DIGITALTUBE_H__#include "..\Com\Com_Util.h"/*** @brief 数码管初始化*/
void Int_DigitalTube_Init();/*** @brief 将指定的整数设置到数码管显示缓存中(digital_buffer数组)* * @param number */
void Int_DigitalTube_setBuffer(u32 number);/*** @brief 数码管指定位置指定数字** @param pos 位置,使用数字0~7分别表示从左边数第1到到第8个* @param code 数字的段选信息*/
void Int_DigitalTube_Single(u8 pos, u8 number_code);/*** @brief 刷新数码管**/
void Int_DigitalTube_Refresh();#endif
Mid.c
Mid.h
模板
mian.c
App.c
App.h
Com.c
Com.h
Dir.c
Dir.h
Int.c
Int.h
Mid.c
Mid.h
相关文章:
STC89C52RC/LE52RC
STC89C52RC 芯片手册原理图扩展版原理图 功能示例LED灯LED灯的常亮效果LED灯的闪烁LED灯的跑马灯效果:从左到右,从右到左 数码管静态数码管数码管计数App.cApp.hCom.cCom.hDir.cDir.hInt.cInt.hMid.cMid.h 模板mian.cApp.cApp.hCom.cCom.hDir.cDir.hInt.…...

✨ PLSQL卡顿优化
✨ PLSQL卡顿优化 1.📂 打开首选项2.🔧 Oracle连接配置3.⛔ 关闭更新和新闻 1.📂 打开首选项 2.🔧 Oracle连接配置 3.⛔ 关闭更新和新闻...
yum命令常用选项
刷新仓库列表 sudo yum repolist清理 Yum 缓存并生成新的缓存 sudo yum clean all sudo yum makecache验证 EPEL 源是否已正确启用 sudo yum repolist enabled安装软件包 sudo yum install <package-name> -y更新软件包 sudo yum update -y仅更新指定的软件包。 su…...

python+vlisp实现对多段线范围内土方体积的计算
#在工程中,经常用到计算土方回填、土方开挖的体积。就是在一个范围内,计算土被挖走,或者填多少,这个需要测量挖填前后这个范围内的高程点。为此,我开发一个app,可以直接在autocad上提取高程点,然…...
鸿蒙Flutter实战:25-混合开发详解-5-跳转Flutter页面
概述 在上一章中,我们介绍了如何初始化 Flutter 引擎,本文重点介绍如何添加并跳转至 Flutter 页面。 跳转原理 跳转原理如下: 本质上是从一个原生页面A 跳转至另一个原生页面 B,不过区别在于,页面 B是一个页面容器…...

APM32小系统键盘PCB原理图设计详解
APM32小系统键盘PCB原理图设计详解 一、APM32小系统简介 APM32微控制器是国内半导体厂商推出的一款高性能ARM Cortex-M3内核微控制器,与STM32高度兼容,非常适合DIY爱好者用于自制键盘、开发板等电子项目。本文将详细讲解如何基于APM32 CBT6芯片设计一款…...
【C/C++】多线程开发:wait、sleep、yield全解析
文章目录 多线程开发:wait、sleep、yield全解析1 What简要介绍详细介绍wait() — 条件等待(用于线程同步)sleep() — 睡觉,定时挂起yield() — 自愿让出 CPU 2 区别以及建议区别应用场景建议 3 三者协作使用示例 多线程开发&#…...
uint8_t是什么数据类型?
一、引言 在C语言编程中,整数类型是最基本的数据类型之一。然而,你是否真正了解这些看似简单的数据类型?本文将深入探索C语言中的整数类型,在编程中更加得心应手。 二、C语言整数类型的基础 2.1 标准整数类型 C语言提供了多种…...
SystemUtils:你的Java系统“探照灯“——让环境探测不再盲人摸象
各位Java系统侦探们好!今天要介绍的是Apache Commons Lang3中的SystemUtils工具类。这个工具就像编程界的"雷达系统",能帮你一键获取所有系统关键信息,再也不用满世界找System.getProperty()了! 一、为什么需要SystemU…...

对象存储(Minio)使用
目录 1.安装 MinIO(Windows) 2.启动minio服务: 3.界面访问 4.进入界面 5.前后端代码配置 1)minio前端配置 2)minio后端配置 1.安装 MinIO(Windows) 官方下载地址:[Download High-Perform…...

yolov11使用记录(训练自己的数据集)
官方:Ultralytics YOLO11 -Ultralytics YOLO 文档 1、安装 Anaconda Anaconda安装与使用_anaconda安装好了怎么用python-CSDN博客 2、 创建虚拟环境 安装好 Anaconda 后,打开 Anaconda 控制台 创建环境 conda create -n yolov11 python3.10 创建完后&…...
历史数据分析——宁波港
个股走势 公司简介: 货物吞吐量和集装箱吞吐量持续保持全球港口前列。 经营分析: 码头开发经营、管理;港口货物的装卸、堆存、仓储、包装、灌装;集装箱拆拼箱、清洗、修理、制造、租赁;在港区内从事货物驳运,国际货运代理;铁路货物运输代理,铁路工程承建,铁路设备…...

知识宇宙:技术文档该如何写?
名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、技术文档的价值与挑战1. 为什么技术文档如此重要2. 技术文档面临的挑战 二、撰…...
DeepSeek 赋能数字农业:从智慧种植到产业升级的全链条革新
目录 一、数字农业的现状与挑战二、DeepSeek 技术解析2.1 DeepSeek 的技术原理与优势2.2 DeepSeek 在人工智能领域的地位与影响力 三、DeepSeek 在数字农业中的应用场景3.1 精准种植决策3.2 病虫害监测与防治3.3 智能灌溉与施肥管理3.4 农产品质量追溯与品牌建设 四、DeepSeek …...

技嘉主板怎么开启vt虚拟化功能_技嘉主板开启vt虚拟化教程(附intel和amd开启方法)
最近使用技嘉主板的小伙伴们问我,技嘉主板怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术,当CPU支持VT-x虚拟化技术,有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中,手动进行设置ÿ…...

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用
Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用 一、引言 在 Java 并发编程中,CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控…...

PT5F2307触摸A/D型8-Bit MCU
1. 产品概述 ● PT5F2307是一款51内核的触控A/D型8位MCU,内置16K*8bit FLASH、内部256*8bit SRAM、外部512*8bit SRAM、触控检测、12位高精度ADC、RTC、PWM等功能,抗干扰能力强,适用于滑条遥控器、智能门锁、消费类电子产品等电子应用领域。 …...
矩阵方程$Ax=b$的初步理解.
对于矩阵方程 A x b A\textbf{\textit{x}}\textbf{\textit{b}} Axb,可能就是一学而过,也可能也就会做做题,但是从如何直观地理解它呢? 这个等式可以用多种理解方式,这里就从向量变换角度浅谈一下。其中的 A A A是矩阵&#…...

线性代数中的向量与矩阵:AI大模型的数学基石
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
[特殊字符] 使用增量同步+MQ机制将用户数据同步到Elasticsearch
在开发用户搜索功能时,我们通常会将用户信息存储到 Elasticsearch(简称 ES) 中,以提高搜索效率。本篇文章将详细介绍我们是如何实现 MySQL 到 Elasticsearch 的增量同步,以及如何通过 MQ 消息队列实现用户信息实时更新…...
LeetCode 2942.查找包含给定字符的单词:使用库函数完成
【LetMeFly】2942.查找包含给定字符的单词:使用库函数完成 力扣题目链接:https://leetcode.cn/problems/find-words-containing-character/ 给你一个下标从 0 开始的字符串数组 words 和一个字符 x 。 请你返回一个 下标数组 ,表示下标在数…...
【mediasoup】MS_DEBUG_DEV 等日志形式转PLOG输出
输出有问题 MS_DEBUG_DEV("[pacer_updated pacing_kbps:%" PRIu32 ",padding_budget_kbps:%" PRIu32 "]",pacing_bitrate_kbps_,/*cc给出的目标码率 * 系数*/padding_rate_bps / 1000 /*设置值*/);...

打卡第27天:函数的定义与参数
知识点回顾: 1.函数的定义 2.变量作用域:局部变量和全局变量 3.函数的参数类型:位置参数、默认参数、不定参数 4.传递参数的手段:关键词参数 5.传递参数的顺序:同时出现三种参数类型时 作业: 题目1&a…...

python训练营day34
知识点回归: CPU性能的查看:看架构代际、核心数、线程数GPU性能的查看:看显存、看级别、看架构代际GPU训练的方法:数据和模型移动到GPU device上类的call方法:为什么定义前向传播时可以直接写作self.fc1(x) 作业 复习今…...

人工智能在医疗影像诊断上的最新成果:更精准地识别疾病
摘要:本论文深入探讨人工智能在医疗影像诊断领域的最新突破,聚焦于其在精准识别疾病方面的显著成果。通过分析深度学习、多模态影像融合、三维重建与可视化以及智能辅助诊断系统等关键技术的应用,阐述人工智能如何提高医疗影像诊断的准确性和…...

塔能节能平板灯:点亮苏州某零售工厂节能之路
在苏州某零售工厂的运营成本中,照明能耗占据着一定比例。为降低成本、提升能源利用效率,该工厂与塔能科技携手,引入塔能节能平板灯,开启了精准节能之旅,并取得了令人瞩目的成效。 一、工厂照明能耗困境 苏州该零售工厂…...

3DMAX插件UV工具UV Tools命令参数详解
常规: 打开UV工具设置对话框。 右键点击: 隐藏/显示主界面。 添加 为选定对象添加展开修改器。 将从下拉菜单中选择映射通道。 Ctrl+点击: 克隆任何当前的修饰符。 右键点击: 找到第一个未展开的修改器。 地图频道 设置展开映射通道。 Ctrl+Click:添加选定的映射通道的展开…...

Docker 与微服务架构:从单体应用到容器化微服务的迁移实践
随着软件系统规模和复杂性的日益增长,传统的单体应用(Monolithic Application)在开发效率、部署灵活性和可伸缩性方面逐渐暴露出局限性。微服务架构(Microservice Architecture)作为一种将大型应用拆分为一系列小型、独立、松耦合服务的模式,正成为现代企业构建弹性、敏捷…...

《岁月深处的童真》
在那片广袤而质朴的黄土地上,时光仿佛放慢了脚步,悠悠地流淌着。画面的中央,是一个扎着双髻的小女孩,她静静地伫立着,宛如一朵绽放在岁月缝隙中的小花。 小女孩身着一件略显陈旧的中式上衣,布料的纹理间似乎…...

文件夹图像批处理教程
前言 因为经常对图像要做数据清洗,又很费时间去重新写一个,我一直在想能不能写一个通用的脚本或者制作一个可视化的界面对文件夹图像做批量的修改图像大小、重命名、划分数据训练和验证集等等。这里我先介绍一下我因为写过的一些脚本,然后我…...