STC89C52RC/LE52RC

STC89C52RC

  • 芯片手册
  • 原理图
    • 扩展版原理图
  • 功能示例
    • LED灯
      • ==LED灯的常亮效果==
      • ==LED灯的闪烁==
      • ==LED灯的跑马灯效果:从左到右,从右到左==
    • 数码管
      • 静态数码管
      • 数码管计数
        • mian.c
        • 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

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

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

相关文章

踩坑记录:RecyclerView 局部刷新notifyItemChanged多次调用只触发一次 onBindViewHolder 的原因

1. 问题背景 在做项目的时候&#xff0c;RecyclerView需要使用局部刷新&#xff0c;使用 notifyItemChanged(position, payload) 实现局部刷新&#xff0c;但发现调用多次只执行了一次&#xff0c;第二个刷新不生效。 2. 错误示例&#xff08;只处理 payloads.get(0)&#xff…

OpenLayers 加载鹰眼控件

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图控件是一些用来与地图进行简单交互的工具&#xff0c;地图库预先封装好&#xff0c;可以供开发者直接使用。OpenLayers具有大部分常用的控件&#x…

WPF···

设置启动页 默认最后一个窗口关闭,程序退出,可以设置 修改窗体的icon图标 修改项目exe图标 双击项目名会看到代码 其他 在A窗体点击按钮打开B窗体,在B窗体设置WindowStartupLocation=“CenterOwner” 在A窗体的代码设置 B.Owner = this; B.Show(); B窗体生成在A窗体中间…

github公开项目爬取

import requestsdef search_github_repositories(keyword, tokenNone, languageNone, max_results1000):"""通过 GitHub API 搜索仓库&#xff0c;支持分页获取所有结果&#xff08;最多 1000 条&#xff09;:param keyword: 搜索关键词:param token: GitHub To…

防震基座在半导体晶圆制造设备抛光机详细应用案例-江苏泊苏系统集成有限公司

在半导体制造领域&#xff0c;晶圆抛光作为关键工序&#xff0c;对设备稳定性要求近乎苛刻。哪怕极其细微的振动&#xff0c;都可能对晶圆表面质量产生严重影响&#xff0c;进而左右芯片制造的成败。以下为您呈现一个防震基座在半导体晶圆制造设备抛光机上的经典应用案例。 企…

S32K开发环境搭建详细教程(一、S32K IDE安装注册)

一、S32K IDE安装注册 1、进入恩智浦官网https://www.nxp.com.cn/&#xff08;需要在官网注册一个账号&#xff09; 2、直接搜索 “Standard Software”&#xff0c;找到S32K3 Standard Software&#xff0c;点击进入 3、下载 (1)Automotive SW - S32K3 - S32 Design Studio…

Spring Cloud Gateway 微服务网关实战指南

上篇文章简单介绍了SpringCloud系列OpenFeign的基本用法以及Demo搭建&#xff08;Spring Cloud实战&#xff1a;OpenFeign远程调用与服务治理-CSDN博客&#xff09;&#xff0c;今天继续讲解下SpringCloud Gateway实战指南&#xff01;在分享之前继续回顾下本次SpringCloud的专…

MSP430G2553 USCI模块串口通信

1.前言 最近需要利用msp430连接蓝牙模块传递数据&#xff0c;于是死磕了一段时间串口&#xff0c;在这里记录一下 2.msp430串口模块 msp430的串口模块可以有USCI模块提供 在异步模式中&#xff0c; USCI_Ax 模块通过两个外部引脚&#xff0c; UCAxRXD 和 UCAxTXD&#xff0…

【产品经理从0到1】用户端产品设计与用户画像

思考 xx新闻的第一个版本应该做哪些事情呢&#xff1f; 用户端核心功能 用户端通用页面设计 思考 回想一下&#xff0c;大家在第一次使用一个新下载的App的时候会看到一些什么样的页面?这样的页面一般都是展示了一些什么内容? 引导页 概念 第一次安装App或者更新App后第…

多场景游戏AI新突破!Divide-Fuse-Conquer如何激发大模型“顿悟时刻“?

多场景游戏AI新突破&#xff01;Divide-Fuse-Conquer如何激发大模型"顿悟时刻"&#xff1f; 大语言模型在强化学习中偶现的"顿悟时刻"引人关注&#xff0c;但多场景游戏中训练不稳定、泛化能力差等问题亟待解决。Divide-Fuse-Conquer方法&#xff0c;通过…

佰力博科技与您探讨压电材料的原理与压电效应的应用

压电材料的原理基于正压电效应和逆压电效应&#xff0c;即机械能与电能之间的双向转换特性。 压电材料的原理源于其独特的晶体结构和电-机械耦合效应&#xff0c;具体可分为以下核心要点&#xff1a; 1. ‌正压电效应与逆压电效应的定义‌ ‌正压电效应‌&#xff1a;当压电…

算法备案审核周期

&#xff08;一&#xff09;主体备案审核 主体备案审核周期通常为7-10个工作日&#xff0c;监管部门将对企业提交的资质信息进行严格审查&#xff0c;审核重点包括&#xff1a; 营业执照的真实性、有效性及与备案主体的一致性。法人及算法安全责任人身份信息的准确性与有效性…

管理系统的接口文档

一、接口概述 本接口文档用于描述图书管理系统中的一系列 Restful 接口&#xff0c;涵盖图书的查询、添加、更新与删除操作&#xff0c;以及用户的登录注册等功能&#xff0c;方便客户端与服务器之间进行数据交互。 二、接口基础信息 接口地址&#xff1a;https://book-manag…

杰发科技AC7801——PWM获取固定脉冲个数

测试通道6 在初始化时候打开通道中断 void PWM1_GenerateFrequency(void) {PWM_CombineChConfig combineChConfig[1]; //组合模式相关结构体PWM_IndependentChConfig independentChConfig[2];//独立模式相关结构体PWM_ModulationConfigType pwmConfig; //PWM模式相关结构体PWM…

RL电路的响应

学完RC电路的响应&#xff0c;又过了一段时间了&#xff0c;想必很多人都忘了RC电路响应的一些内容。我们这次学习RL电路的响应&#xff0c;以此同时&#xff0c;其实也是带大家一起回忆一些之前所学的RC电路的响应的一些知识点。所以&#xff0c;这次的学习&#xff0c;其实也…

鸿蒙Flutter实战:21-混合开发详解-1-概述

引言 在前面的系列文章中&#xff0c;我们从搭建开发环境开始&#xff0c;讲到如何使用、集成第三方插件&#xff0c;如何将现有项目进行鸿蒙化改造&#xff0c;以及上架审核等内容&#xff1b;还以高德地图的 HarmonyOS SDK 的使用为例&#xff0c; 讲解了如何将高德地图集成…

Vmware ubuntu22.04 虚拟机 连接Windows主机虚拟串口

1. Windows虚拟串口配置 虚拟串口下载&#xff1a;教程网址 虚拟串口使用&#xff1a;教程网址 2. Ubuntu 虚拟串口配置 Vmware ubuntu22.04 虚拟机 连接windows主机虚拟串口_vmware中ttys0连接的是哪个端口-CSDN博客 注意&#xff1a;虚拟添加串口的时候&#xff0c;一直…

编译rk3568的buildroot不起作用

一、环境&#xff1a; 使用kickpi k1开发板&#xff0c;芯片为rk3568。 vmware ubuntu22.04 kickpi给的sdk包&#xff0c;应该不同友商是通用的。 使用的根文件为buildroot 二、问题&#xff1a; 由于 1、wpa_supplicant -D wext -c /etc/wpa_supplicant.conf -i wlan0 …

【动态规划】简单多状态(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

如何选择支持AI接入的开发语言与框架

选择支持AI接入的开发语言与框架 在AI系统开发中,语言和框架的选择不仅决定了代码实现方式,更深刻影响模型服务的接入效率、调用方式、性能表现和未来的可维护性。相比传统后端系统的语言选择只需关注并发性能或生态成熟度,AI架构下的开发语言必须同时满足以下几类能力: 具…