网站后期维护协议,销售网站开发步骤,东莞佳诚网站建设有限公司,wordpress手动更新插件资料查找#xff1a;
01 方案选择
使用单片机测量电阻有多种方法#xff0c;以下是一些常见的方法及其原理#xff1a;
串联分压法#xff08;ADC#xff09; 原理#xff1a;根据串联电路的分压原理#xff0c;通过测量已知电阻和待测电阻上的电压#xff0c;计算出…资料查找
01 方案选择
使用单片机测量电阻有多种方法以下是一些常见的方法及其原理
串联分压法ADC 原理根据串联电路的分压原理通过测量已知电阻和待测电阻上的电压计算出待测电阻的阻值。优点电路简单易于实现。缺点测量精度受电源电压稳定性和电压测量精度的影响。 对于89C5x单片机一般需要外接PCF8591A/D转换芯片 直流电桥法 原理利用直流电桥的平衡原理通过调节电位器使电桥平衡从而计算出待测电阻的阻值。优点测量精度较高。缺点电路相对复杂调节较为麻烦。恒流源法 原理将恒流源施加到待测电阻上通过测量电阻两端的电压来计算电阻值。优点测量精度较高不受电源电压波动的影响。缺点需要稳定的恒流源电路实现相对复杂。频率法 原理利用RC振荡电路和555定时器电路将电阻转换为频率信号通过测量频率来计算电阻值。优点测量速度快适用于动态测量。缺点测量精度受振荡电路稳定性和频率测量精度的影响。IO口测量法 原理使用单片机的IO口通过电容充电时间来测量电阻。电容充电时间与电阻成正比通过测量充电时间来计算电阻值。优点不需要额外的AD转换电路利用单片机IO口即可实现。缺点测量精度受单片机定时器精度和电容稳定性的影响。 以为大部分单片机通用试了一下发现STC89C52内部上拉有干扰 2 使用单片机的IO口通过电容充电时间来测量电阻
测量原理
使用两个单片机IO口连接两个电阻向同一个电容充电。设置一个IO口为输出端口另一个为输入端口。输出端口通过连接的电阻向电容充电。电容上的电压上升当超过一定阈值输入端口逻辑电平就会变成1。 关于阈值可以通过输入三角波得到但是我们并不需要知道比值可消 这个充电时间与终止电压、阈值电压以及RC对应的时间常数有关系。具体数值由这个公式决定 对应的时间与R2成正比。因此两次时间的比值就等于电阻的比值。如果已知其中一个电阻阻值另外一个电阻便可以根据时间比值计算出来。12
实验步骤
需要一个电容和两个电阻。电容容值为313.8nF电阻1的阻值为19.545kΩ电阻2的阻值为4.718kΩ。电容一端接地另外一端与两个电阻相连。两个电阻分别与单片机的PF0PF1端口相连。设置PF0为输出端口PF1为输入端口。周期改变PF0高低电平。分别测量PF0以及电容上的电压信号。测量软件先将PF0PF1输出0电平对于电容进行放电。然后将其中一个设置为输入端口另外一个置为高电平对电容充电。同时启动定时器1进行计时。在此过程中监视输入端口逻辑电平是否为1。当输入端口变为1时停止定时器并读取时间。然后再进行放电更换另外一个端口为输入端口。测试充电时间。1
实验结果
测试298个数据进行统计。数据的平均值为4.119标准方差为0.043。测量平均值比实际电阻比值4.143小了0.6%。1 3 硬件部分 4 软件部分 介绍
STC89C52的端口P2是一个双向I/O口每个引脚如P2.0、P2.1等
P01时为上拉输出P00时为低电平输出
因此在已有上拉输入的条件下也同样理论可行 最终按照如图思路把代码改出来了但发现因为单片机太低级了影响了开发效率 那就准备直接ADC写了算了 main.c
#include reg52.h//0.000 001 0850694444444441
sbit IO1 P2^2;
sbit IO2 P2^3;
sbit ADDR0 P1^0;
sbit ADDR1 P1^1;
sbit ADDR2 P1^2;
sbit ADDR3 P1^3;
sbit ENLED P1^4;void Delay_ms(int ms) //11.0592MHz
{unsigned char data i, j;do{i 15;j 90;do{while (--j);} while (--i);}while (--ms);
}unsigned char code LedChar[] { //数码管显示字符转换表0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] { //数码管显示缓冲区0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};bit StopwatchRunning 0; //秒表运行标志
bit StopwatchRefresh 1; //秒表计数刷新标志
unsigned char DecimalPart 0; //秒表的小数部分
unsigned int IntegerPart 0; //秒表的整数部分
unsigned char T0RH 0; //T0重载值的高字节
unsigned char T0RL 0; //T0重载值的低字节
unsigned long time_R1, time_R2; // 用于存储充电时间
unsigned long Rx 0;
float ratio 0;
unsigned char flag1s 0;
void ConfigTimer0(unsigned int ms);
unsigned long timer_read();
void U_Measure();
void LedScan();
void LCD_paly();
void main()
{EA 1; //开总中断ENLED 0; //使能选择数码管ADDR3 1;P2 0xFE; //P2.0置0选择第4行按键作为独立按键ConfigTimer0(6); //配置T0定时2mswhile (1){U_Measure();while (1){LedScan();LCD_paly();}}
}void U_Measure()
{// 第一步放电IO1 1;IO2 1;TR0 0;Delay_ms(20); // 确保电容放电干净// 第二步测量参考电阻回路上的充电时间IO1 0;IO2 1;TR0 1;while(IO20); // 等待充电结束time_R1 timer_read(); // 读取计时器值// 第三步放电IO1 1;IO2 1;TR0 0;Delay_ms(20); // 确保电容放电干净// 第四步测温度电阻回路上的充电时间IO1 1;IO2 0;TR0 1;while(IO10); // 等待充电结束time_R2 timer_read(); // 读取计时器值// 第五步计算电阻比率ratio ((time_R1*10) / (time_R2*10))/10;Rxratio;//flag1s 1;}
/* 配置并启动T0ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)//最大71ms
{unsigned long tmp; //临时变量tmp 11059200 / 12; //定时器计数频率tmp (tmp * ms) / 1000; //计算所需的计数值tmp 65536 - tmp; //计算定时器重载值tmp tmp 18; //补偿中断响应延时造成的误差经验值
// T0RH (unsigned char)(tmp8); //定时器重载值拆分为高低字节
// T0RL (unsigned char)tmp;T0RH 0; //定时器重载值拆分为高低字节T0RL 0;TMOD 0xF0; //清零T0的控制位TMOD | 0x01; //配置T0为模式116位TH0 T0RH; //加载T0重载值TL0 T0RL;ET0 1; //使能T0中断}
/* 秒表计数显示函数 */
void LedScan()
{// flag1s 0; //1秒定时标志清零//以下代码将Rx按十进制位从低到高依次提取并转为数码管显示字符LedBuff[0] LedChar[Rx%10];LedBuff[1] LedChar[Rx/10%10];LedBuff[2] LedChar[Rx/100%10];LedBuff[3] LedChar[Rx/1000%10];LedBuff[4] LedChar[Rx/10000%10];LedBuff[5] LedChar[Rx/100000%10];}
void LCD_paly()
{static signed char i;P0 0xFF; //显示消隐switch (i){case 0: ADDR20; ADDR10; ADDR00; i; P0LedBuff[0]; break;case 1: ADDR20; ADDR10; ADDR01; i; P0LedBuff[1]; break;case 2: ADDR20; ADDR11; ADDR00; i; P0LedBuff[2]; break;case 3: ADDR20; ADDR11; ADDR01; i; P0LedBuff[3]; break;case 4: ADDR21; ADDR10; ADDR00; i; P0LedBuff[4]; break;case 5: ADDR21; ADDR10; ADDR01; i0; P0LedBuff[5]; break;default: break;}}/* 定时停止函数 */
unsigned long timer_read()
{unsigned long tmp1 0;TR0 0; tmp1 (unsigned char)((TH0-T0RH)8)|(unsigned char)(TL0-T0RL); //定时器重载值拆分为高低字节TH0 T0RH; //重新加载重载值TL0 T0RL;return tmp1;
}/* T0中断服务函数完成数码管、按键扫描与秒表计数 */
void InterruptTimer0() interrupt 1
{TH0 T0RH; //重新加载重载值TL0 T0RL;
// LedScan(); //数码管扫描显示} 02 使用方法——串联分压法ADC测电阻 完整工程代码部分待课设结束再公开 如果需要技术支持可以加我的QQ交流
27969203789
02 实验现象 03 硬件部分
金沙滩51单片机需要测量相近的电阻 04 软件部分
核心部分
val (GetADCValue(0)*2.5); //获取ADC通道0的转换值 电压值转换结果*2.48V/255式中的25隐含了一位十进制小数
Rx(val/(6375-val))*R1;XX 拓展资料收集资料仅供参考
虽然STC89C52无法配置上下拉操作但是一般现代翻新的芯片都可以配置至于配置方法可能类似如下 例如 有些单片机的端口P2的输入和输出模式通过配置端口的P2M0和P2M1寄存器来控制。P2M0和P2M1分别是P2端口的输入/输出模式控制寄存器。 关于P2M1 和 P2M0 寄存器介绍 P2M1 和 P2M0 寄存器是常见的微控制器例如 51 系列单片机中的特定控制寄存器用于设置端口特别是端口 2的功能模式。 通常在 51 系列单片机中P2M1 和 P2M0 寄存器用于控制端口 2 的工作模式例如是否作为 I/O 端口或者是否用于特殊功能。 1. P2M1 寄存器 P2M1 寄存器的位数通常是 8 位每一位对应于端口 2 的各个引脚的模式。具体来说P2M1 中的每一位控制端口 2 的每一个引脚的工作方式。 位 7 (P2.7) 0: 作为 I/O 端口1: 用于特殊功能。 位 6 (P2.6) 0: 作为 I/O 端口1: 用于特殊功能。 依此类推P2M1 的每一位控制对应的端口引脚的模式。 2. P2M0 寄存器 P2M0 寄存器也是 8 位与 P2M1 配合使用进一步控制端口 2 的引脚模式。它的每一位也用于设置端口 2 上每个引脚的功能模式。例如 位 7 (P2.7)可以通过设置此位来选择端口引脚的功能是 I/O还是其他功能。位 6 (P2.6)控制端口引脚的工作模式。 P2M1 和 P2M0 的配合 P2M1 和 P2M0 配合使用通常具有以下几个常见的工作模式以位 P2.x 为例 00作为普通的数字 I/O 端口01用于某些特定的功能如外部中断等10用于其他一些特殊功能例如定时器、串口等11也可以用于其他特定功能模式。 总结 P2M1 和 P2M0 寄存器通常是 8 位每一位对应端口 2 上的一个引脚P2.0 到 P2.7的功能控制。每一位设置为 0 或 1控制对应引脚是作为 I/O 端口还是用于特定的功能模式 P2 引脚P2M1P2M0描述P2.x00普通输入无上下拉电阻P2.x01带下拉电阻输入模式低电平有效P2.x10推挽输出模式P2.x11开漏输出模式 一般高级的51单片机的寄存器操作可以通过P2M1和P2M0的配置来控制P2口的工作模式 配置P2.0为下拉输入模式。我们清除P2M1的对应位即 P2M1 0xFE然后设置P2M0的对应位即 P2M0 | 0x01来启用下拉电阻。 配置P2.0为推挽输出模式。我们设置P2M1的对应位即 P2M1 | 0x01并清除P2M0的对应位即 P2M0 0xFE int IN1(void)
{
// 设置P2.0为下拉输入模式P2M1 0xFE; // P2M1位为0P2M0 | 0x01; // 设置P2M0位为1启用下拉输入模式}int IN2(void)
{
// 设置P2.0为下拉输入模式P2M1 0xFD; // P2M1位为0P2M0 | 0x02; // 设置P2M0位为1启用下拉输入模式}void ON1(void)
{// 设置P2.0为推挽输出模式P2M1 | 0x01; // 设置P2M1位为1P2M0 0xFE; // 设置P2M0位为0设置为推挽输出模式
}void ON2(void)
{// 设置P2.0为推挽输出模式P2M1 | 0x02; // 设置P2M1位为1P2M0 0xFD; // 设置P2M0位为0设置为推挽输出模式
}