STC8增强型单片机开发day04

2024-05-13 20:52

本文主要是介绍STC8增强型单片机开发day04,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

热敏电阻

NTC(Negative Temperature Coefficient)是指随温度上升电阻减小、具有负温度系数的热敏电阻现象和材料

原理图

在这里插入图片描述

ADC功能引脚
ADC0P1.0
ADC1P1.1
ADC2P5.4
ADC3P1.3
ADC4P1.4
ADC5P1.5
ADC6P1.6
ADC7P1.7
ADC8P0.0
ADC9P0.1
ADC10P0.2
ADC11P0.3
ADC12P0.4
ADC13P0.5
ADC14P0.6

温度计算步骤

1. 通过ADC采样计算出热敏电阻位置的电压

V n t c 2.5 = A D C _ V a l u e 4096 V n t c = 2.5 × A D C _ V a l u e 4096 \begin{aligned} \frac{V_{ntc}}{2.5} &= \frac{ADC\_Value}{4096} \\ \\ V_{ntc} &= 2.5 \times \frac{ADC\_Value}{4096} \end{aligned} 2.5VntcVntc=4096ADC_Value=2.5×4096ADC_Value

○ ADC_Value就是通过ADC采样出来的的数值,范围是0-4096。
○ V_ntc即为对应的电压值

2. 通过欧姆定律计算热敏电阻的阻值

V n t c R n t c = 3.3 V − V n t c R 10 K = 3.3 V R 10 K + R n t c \frac{V_{ntc}}{R_{ntc}} = \frac{3.3V-V_{ntc}}{R_{10K}} = \frac{3.3V}{R_{10K} + R_{ntc}} RntcVntc=R10K3.3VVntc=R10K+Rntc3.3V

串联分压,电流不变。上面是热敏电阻ntc和10k电阻的电流等式,根据公式推导出热敏电阻的阻值计算公式:
R n t c = V n t c ⋅ R 10 k 3.3 V − V n t c R_{ntc} = \frac{V_{ntc} \cdot R_{10k}}{3.3V-V_{ntc}} Rntc=3.3VVntcVntcR10k

3. 通过阻值查表得到温度

在这里插入图片描述
采用表的方式来记录 电阻值和温度的关系。
其中,表中记录的是阻值,下标记录的是温度。可以通过阻值比对,查询出下标,下标就是对应的温度。

u16 code temp_table[]= {58354, // -5555464, // -5452698, // -5350048, // -5247515, // -5145097, // -5042789, // -4940589, // -4838492, // -4736496, // -4634597, // -4532791, // -4431075, // -4329444, // -4227896, // -4126427, // -4025034, // -3923713, // -3822460, // -3721273, // -3620148, // -3519083, // -3418075, // -3317120, // -3216216, // -3115361, // -3014551, // -2913785, // -2813061, // -2712376, // -2611728, // -2511114, // -2410535, // -239986,  // -229468,  // -218977,  // -208513,  // -198075,  // -187660,  // -177267,  // -166896,  // -156545,  // -146212,  // -135898,  // -125601,  // -115319,  // -105053,  // -94801,  // -84562,  // -74336,  // -64122,  // -53920,  // -43728,  // -33546,  // -23374,  // -13211,  // 03057,  // 12910,  // 22771,  // 32639,  // 42515,  // 52396,  // 62284,  // 72177,  // 82076,  // 91978,  // 101889,  // 111802,  // 121720,  // 131642,  // 141568,  // 151497,  // 161430,  // 171366,  // 181306,  // 191248,  // 201193,  // 211141,  // 221092,  // 231044,  // 241000,  // 25957,   // 26916,   // 27877,   // 28840,   // 29805,   // 30771,   // 31739,   // 32709,   // 33679,   // 34652,   // 35625,   // 36600,   // 37576,   // 38552,   // 39530,   // 40509,   // 41489,   // 42470,   // 43452,   // 44434,   // 45417,   // 46401,   // 47386,   // 48371,   // 49358,   // 50344,   // 51331,   // 52318,   // 53306,   // 54295,   // 55284,   // 56274,   // 57264,   // 58254,   // 59245,   // 60236,   // 61228,   // 62220,   // 63212,   // 64205,   // 65198,   // 66191,   // 67184,   // 68178,   // 69172,   // 70166,   // 71160,   // 72155,   // 73150,   // 74145,   // 75140,   // 76135,   // 77131,   // 78126,   // 79122,   // 80118,   // 81115,   // 82111,   // 83107,   // 84104,   // 85101,   // 8697,    // 8794,    // 8891,    // 8989,    // 9086,    // 9183,    // 9281,    // 9378,    // 9476,    // 9574,    // 9671,    // 9769,    // 9867,    // 9965,    // 10063,    // 10161,    // 10260,    // 10358,    // 10456,    // 10555,    // 10653,    // 10752,    // 10850,    // 10949,    // 11047,    // 11146,    // 11245,    // 11343,    // 11442,    // 11541,    // 11640,    // 11739,    // 11838,    // 11937,    // 12036,    // 12135,    // 12234,    // 12333,    // 12432,    // 125
};

代码参考

创建NTC.h,写入如下内容

#ifndef __NTC_H__
#define __NTC_H__#include "Config.h"// 求绝对值
#define abs(x)	((x > 0) ? (x) : (-(x)))#define NTC_GPIO			GPIO_P0#define NTC_GPIO_PIN	GPIO_Pin_4#define NTC_ACD_CH		ADC_CH12// 初始化NTC
void NTC_init();// 获取温度值
int NTC_get_temperature();#endif

创建一个NTC.c文件,写入如下内容,请自行将temp_table拷贝进来

#include "NTC.h"
#include "GPIO.h"
#include "ADC.h"
#include "NVIC.h"
#include <stdio.h>static void GPIO_config(void) {GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = NTC_GPIO_PIN;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_HighZ;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(NTC_GPIO, &GPIO_InitStructure);//初始化
}/******************* AD配置函数 *******************/
void	ADC_config(void)
{ADC_InitTypeDef		ADC_InitStructure;		//结构定义ADC_InitStructure.ADC_SMPduty   = 31;		//ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)ADC_InitStructure.ADC_CsSetup   = 0;		//ADC 通道选择时间控制 0(默认),1ADC_InitStructure.ADC_CsHold    = 1;		//ADC 通道选择保持时间控制 0,1(默认),2,3ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X1T;		//设置 ADC 工作时钟频率	ADC_SPEED_2X1T~ADC_SPEED_2X16TADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;	//ADC结果调整,	ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIEDADC_Inilize(&ADC_InitStructure);		//初始化ADC_PowerControl(ENABLE);				//ADC电源开关, ENABLE或DISABLENVIC_ADC_Init(DISABLE,Priority_0);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}// 初始化NTC
void NTC_init() {GPIO_config();ADC_config();
}static int search_temp(float rst_Rx10){int i, min_index = 0;// 计算数组长度int len = sizeof(temp_table) / sizeof(u16);// 记录最小差值 float min_diff = abs(rst_Rx10 - temp_table[0]);for (i = 1; i < len; i++){// 计算数组里每一个阻值和rst_Rx10的差值float diff = abs(rst_Rx10 - temp_table[i]);// 得到差值最小元素对应的索引iif(diff < min_diff){// 如果有更小的差值,赋值min_diff = diff;min_index = i;}}printf("len: %d R: %.2f min_diff: %.2f min_index: %d \n", len, rst_Rx10, min_diff, min_index);return min_index;
}// 获取温度值
int NTC_get_temperature() {u16 adc_value;float rst_V;float rst_R;int rst_T;// 获取对应的ADC值adc_value = Get_ADCResult(NTC_ACD_CH);// adc_value返回的值范围 0 -> 4096// 等同于P05引脚的电压值和Vref的占比  1024// X = ADC_V  * Vref / 4096// 计算电压rst_V = adc_value * 2.5 / 4096;// 计算电阻值rst_R = rst_V * 10 / (3.3 - rst_V);// 9.36KΩ 将阻值兑换成温度rst_T = search_temp(rst_R * 100) - 55;printf("ADC: %d voltage: %.2f R = %.2f T = %d℃ \n", adc_value, rst_V, rst_R, (int)rst_T);return rst_T;
}

main函数中:


int rst_T;
NTC_init();rst_T = NTC_get_temperature();
printf("温度:%d \n", rst_T);

独立按键

原理图

在这里插入图片描述

按键消抖

  1. 软件延时法:在按键按下时,使用软件延时一段时间,例如10毫秒,然后再检测按键是否还处于按下状态,如果是,则认为按键有效。这种方法简单易行,但会浪费一定的处理器时间,同时需要根据实际情况调整延时时间。

  2. 硬件滤波法:在按键输入引脚上添加RC滤波电路,可以有效地去除按键信号上的瞬间噪声。这种方法对于高频噪声的去除效果较好,但需要一定的电路设计能力。

  3. 程序消抖法:在程序中记录按键前后两次的状态,如果两次状态不同,则认为按键有效。这种方法可以根据需要调整检测时间,消抖效果较好,但需要额外的程序设计。

我们采用程序消抖法。

软件设计

要求

当用户按下,或者松开按键时,捕获到这个事件。将事件通过串口发出来。

分析

监控引脚的高低电平变化。记录状态,比对实时状态。
● 监控:死循环去读取电平信息
● 记录与比对:通过变量记录,实时拿到当前状态,与记录的上一次进行比对。

实现单个按钮
#include "Config.h"
#include "Delay.h"
#include "GPIO.h"
#include "UART.h"
#include "NVIC.h"
#include "Switch.h"#define KEY1 P51void GPIO_config(void) {P5_MODE_IO_PU(GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
}void UART_config(void) {COMx_InitDefine		COMx_InitStructure;					//结构定义COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}u8 last_key_state = 1; // 抬起void main(){GPIO_config();UART_config();EA = 1;while(1){if(KEY1 == 1 && last_key_state == 0){ // 当前是抬起Up 1, 上一次是按下Down 0printf("KEY1 up\n");last_key_state = 1;}else if(KEY1 == 0 && last_key_state == 1){// 当前是按下Down 0, 上一次是抬起Up 1printf("KEY1 down\n");	last_key_state = 0;}delay_ms(20);}
}
实现多个按钮
#include "Config.h"
#include "Delay.h"
#include "GPIO.h"
#include "UART.h"
#include "NVIC.h"
#include "Switch.h"#define KEY1 P51
#define KEY2 P52
#define KEY3 P53
#define KEY4 P54void GPIO_config(void) {P5_MODE_IO_PU(GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
}void UART_config(void) {COMx_InitDefine		COMx_InitStructure;					//结构定义COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}#define	DOWN	0
#define	UP		1u8 last_key_states[] = {UP, UP, UP, UP};		// key的最后一次状态// 判断指定位置【是否是】按下或抬起
#define	IS_KEY_DOWN(i)		last_key_states[i] == DOWN
#define	IS_KEY_UP(i)		last_key_states[i] == UP// 将指定位置值【设置】为按下或抬起
#define SET_KEY_DOWN(i)		last_key_states[i] = DOWN
#define SET_KEY_UP(i)		last_key_states[i] = UPvoid main(){GPIO_config();UART_config();EA = 1;while(1){if(KEY1 && IS_KEY_DOWN(0)){ // 这次是抬起Up 1, 上一次是按下Down 0printf("KEY1 up\n");SET_KEY_UP(0);}else if(!KEY1 && IS_KEY_UP(0)){// 这次是按下Down 0, 上一次是抬起Up 1printf("KEY1 down\n");	SET_KEY_DOWN(0);}if(KEY2 && IS_KEY_DOWN(1)){ // 这次是抬起Up 1, 上一次是按下Down 0printf("KEY2 up\n");SET_KEY_UP(1);}else if(!KEY2 && IS_KEY_UP(1)){// 这次是按下Down 0, 上一次是抬起Up 1printf("KEY2 down\n");	SET_KEY_DOWN(1);}if(KEY3 && IS_KEY_DOWN(2)){ // 这次是抬起Up 1, 上一次是按下Down 0printf("KEY3 up\n");SET_KEY_UP(2);}else if(!KEY3 && IS_KEY_UP(2)){// 这次是按下Down 0, 上一次是抬起Up 1printf("KEY3 down\n");	SET_KEY_DOWN(2);}if(KEY4 && IS_KEY_DOWN(3)){ // 这次是抬起Up 1, 上一次是按下Down 0printf("KEY4 up\n");SET_KEY_UP(3);}else if(!KEY4 && IS_KEY_UP(3)){// 这次是按下Down 0, 上一次是抬起Up 1printf("KEY4 down\n");	SET_KEY_DOWN(3);}delay_ms(20);}
}
使用位操作存储状态
// P51, P52, P53, P54
//u8 last_key_states[] = {UP, UP, UP, UP}; 
// 0b 0 0 0 0 - 1 1 1 1
u8 last_key_states = 0x0F; 	// KEY最后一次状态的8个位(只使用低4位)// 判断指定位置【是否】是按下
//  0b 0 0 0 0 - 0 0 0 0
//& 0b 0 0 0 0 - 0 1 0 0		----- 判断指定位i=2是否是0
//  0b 0 0 0 0 - 0 0 0 0			== 0
#define IS_KEY_DOWN(i)			(last_key_states & (1 << i)) == 0// 判断指定位置【是否】是抬起
//  0b 0 0 0 0 - 1 1 0 0
//& 0b 0 0 0 0 - 1 0 0 0		----- 判断指定位i=3是否是1
//  0b 0 0 0 0 - 1 0 0 0			> 0
#define IS_KEY_UP(i)			(last_key_states & (1 << i)) > 0// 将指定位置值【设置】为按下
//   0b 0 0 0 0 - 1 1 0 0			
//&= 0b 1 1 1 1 - 1 0 1 1		------ 将指定位i=2设置为0,按下
//&=~0b 0 0 0 0 - 0 1 0 0
//	 0b 0 0 0 0 - 1 0 0 0		
#define SET_KEY_DOWN(i)			last_key_states &= ~(1 << i)// 将指定位置值【设置】为抬起
//   0b 0 0 0 0 - 1 1 0 0			
//|= 0b 0 0 0 0 - 0 0 1 0		------ 将指定位i=1设置为1,抬起
//   0b 0 0 0 0 - 1 1 1 0
#define SET_KEY_UP(i)			last_key_states |= (1 << i)

● u16存储状态: 16个 1 << i 只能存 16 位
● u32存储状态: 32个, 1 << i 要改成 1L << i 能存32位

这篇关于STC8增强型单片机开发day04的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986801

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者

pico2 开发环境搭建-基于ubuntu

pico2 开发环境搭建-基于ubuntu 安装编译工具链下载sdk 和example编译example 安装编译工具链 sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib 注意cmake的版本,需要在3.17 以上 下载sdk 和ex