继续上传另外12个分卷,这网速忒不用活了
我实在没辙了。
这网络也忒悲剧。诶,死活传不上,算。
刚才买了一条数据线,果断把视频放U盘上,明早回公司再折腾折腾。
[ 本帖最后由 辛昕 于 2011-4-26 23:59 编辑 ]
呵呵。。。LZ不错哦。本人一直觉得用51做东西比用TI的片子做东西要难。。
嘿嘿。。
不知道LZ对RLC分别用的什么方法喃、
RL分别用NE555稳态触发器输出频率实现的吧。而对C的测量应该是用电容三点式做的吧。。。
回复 6楼 辛昕 的帖子
诶,总算传上去.
还有另外12个PART传在LS。
回复 22楼 shilaike 的帖子
额,完全不是那么回事。
是LM311的。
你可以参考我们的系列规整帖。
回复 25楼 quanzx 的帖子
呵呵,大叔来了呀,呵呵,是应该的。
不过弄完以后一直放着没整理程序,不太好意思扔上来。
BTW,公司网速好,视频总算上传好了,不过要等待它处理才可上传。
截图
回复 28楼 zxcscm 的帖子
谢谢,视频终于通过审核,可以贴到主题帖里,欢迎大家围观
刚才看自己的操作过程的时候,忽然想起一件很重要的事情。
就是因为这里涉及了几个机械按键,可是该死的我居然一直忘记了 消抖。
因为几个按键的操作都涉及获取 自校准频率 与 标准电容校准频率,这两个值对测量值和精度的影响还是很重要的。
而且刚才看了看,最开始测那个51P的云母电容的精度也是2%,但是其实还是有浮动,如此说来,改变测试方式还不是提高精度的唯一办法。
希望以后能多多发现这些疏忽,一点一点完善。
因为这个测量电路,硬件本身可以说是非常完美,我们要做的是在软件上不断提升它应该有的性能。
另外,刚才大叔的回复提醒了我,我会抓紧时间整理文档的,首先把程序贴上来。
主源程序(完整程序项目文件见附件)
#include "STC12C5A.h"
#include "LCD1602.h"
typedef unsigned char UCHAR;
typedef unsigned int UINT;
#define C_TESTING "Now Cx is check"
#define C_OPEN "Keep TEST Open "
#define L_TESTING "Now Lx is check"
#define L_SHORT "Keep TEST Short"
#define RESET "Please Reset..."
#define INDICATE "By press key "
#define ADJUSTING "It is adjusting"
#define ORIGINAL "The origin Freq"
#define STANDARD "Standard Freq:"
#define ADJ P37
#define SIGNAL P35
#define L_C P33
#define L 0
#define C 1
#define C0 1000
#define L0 1000000000000.0000/C0
#define PI 3.1415
#define TIMES 1000 //计数次数
#define BASE 1000000 //对应一条机器周期的倒数,12M的晶振
#define SUM (TIMES * BASE) //先计算该常数,提高速度
#define COUNT_HIGH (65535 - TIMES) / 256
#define COUNT_LOW (65535 - TIMES) % 256
uint test(void);
long calculate(uint);
void transfer(uchar Dis[],long value);
long Get_Frequency(void);
float Key_Div(long x,long y);
void show_float(uchar Dis[],float value);
//--------------------------------------------------------------
//--------------------------------------------------------------
void main(void)
{
uint cycle1 = 0;
uint cycle2 = 0;
bit project = C;
uint time = 0;
uchar char1[16]="Freq: Hz";
uchar Lx[16] = "Lx= uH";
uchar Cx[16] = "Cx= pF";
long frequency = 0;
long F1 = 0;
long F2 = 0;
long F3 = 0;
float X = 0.0000;
//------------------------------------------------------------------
TMOD=0x51; //计数器0作为16位定时器,计数器0作16位计数器
P3M0=0x28;
P3M1=0x00; //设P33 P35 P37为高阻
Lcd_Ini(); //LCD1602初始化操作,包括初始清屏
/*---------------开机检测测量项目---------------------------------*/
while(cycle1++ < 30)
{
if(!L_C)
project = L;
}
cycle1 = 0;
if(project == L)
{
Lcd_Write_String(1,1,L_TESTING);
Lcd_Write_String(2,1,L_SHORT);
}
else
{
Lcd_Write_String(1,1,C_TESTING);
Lcd_Write_String(2,1,C_OPEN);
}
for(cycle1 = 0;cycle1 < 1000;cycle1++)
for(cycle2 = 0;cycle2 < 2000;cycle2++)
{}
F1 = Get_Frequency();
transfer(char1,F1);
Lcd_Clear_Line(1);
Lcd_Clear_Line(2);
Lcd_Write_String(1,1,ORIGINAL);
Lcd_Write_String(2,1,char1);
for(cycle1 = 0;cycle1 < 1000;cycle1++)
for(cycle2 = 0;cycle2 < 2000;cycle2++)
{}
Lcd_Clear_Line(1);
Lcd_Clear_Line(2);
Lcd_Write_String(1,1,RESET);
Lcd_Write_String(2,1,INDICATE);
while(ADJ);
Lcd_Write_String(1,1,ADJUSTING);
F2 = Get_Frequency();
transfer(char1,F2);
Lcd_Clear_Line(1);
Lcd_Clear_Line(2);
Lcd_Write_String(1,1,STANDARD);
Lcd_Write_String(2,1,char1);
while(!ADJ); //等待松开校准按钮
while(1)
{
X = 0.0000;
Delay_s(1);
F3 = Get_Frequency();
transfer(char1,F3);
Lcd_Clear_Line(1);
Lcd_Write_String(1,1,char1);
if(project == L)
{
X = Key_Div(F1,F2);
X *= Key_Div(F1,F3);
X *= L0;
X *= 1000000.0000/4.0/(float)F1/(float)F1/(float)PI/(float)PI;
show_float(Lx,X);
Lcd_Clear_Line(2);
Lcd_Write_String(2,1,Lx);
}
else
{
X = Key_Div(F1,F3);
X /= Key_Div(F1,F2);
X *= C0;
show_float(Cx,X);
Lcd_Clear_Line(2);
Lcd_Write_String(2,1,Cx);
}
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------*/
uint test(void)
{
//设置计数器1初值
TH1 = COUNT_HIGH;
TL1 = COUNT_LOW;
//设置定时器0初值
TL0 = 0;
TH0 = 0;
//开计数器1,开始计数
TR1 = 1;
//立即启动定时器0,开始定时
TR0 = 1;
//等待计数器溢出
while(TF1 == 0);
//关闭定时器0,再关闭计数器1
TR0 = 0;
TR1 = 0;
//软件清溢出标志位
TF1 = 0;
TF0 = 0;
return (256 * TH0 + TL0);
}
/*------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------*/
long calculate(uint time)
{
long frequency = 0;
frequency = SUM / time; //time为主函数传递来的100个脉冲的时间长度
return frequency;
}
/*------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------*/
void transfer(uchar Dis[],long value)
{
uchar i = 0;
for(i = 5;i < 13;i++)
Dis = 32;
for(i = 2; ;i++) //从数组末开始存储
{
Dis[15 - i] = value % 10 + 0x30; //从末位开始取
value /= 10; //截取末位
if(!value)
break;
}
}
#define TOTAL 20
long Get_Frequency(void)
{
uchar cycle1 = 0;
long Result = 0;
for(cycle1 = 0;cycle1 < TOTAL;cycle1++)
Result += calculate(test());
Result = Result / TOTAL;
return Result;
}
float Key_Div(long x,long y)
{
float a = 0;
float b = 0;
float c = 0.0000;
a = (float)x * (float)x;
b = (float)y * (float)y;
c = a/b - 1;
return c;
}
void show_float(uchar Dis[],float a)
{
long value = 0;
uchar i = 0;
for(i = 3;i < 13;i++)
Dis = 32;
value = a * 10000;
Dis[9] = 46;
for(i = 2; ;i++) //从数组末开始存储
{
if(i == 6)
continue;
Dis[15 - i] = value % 10 + 0x30; //从末位开始取
value /= 10; //截取末位
if(!value)
break;
}
}
[ 本帖最后由 辛昕 于 2011-4-27 20:43 编辑 ]
关于上面这个程序的一点说明
大家稍微看看就会发现,这个程序的组织方式很有问题。
因为我们的头文件里居然有函数定义!
其实这个问题,最初我与anqi90商量过,BTW,这个程序中的1602部分是来自于他,我本来是在他的基础上改动,后来一个不小心居然全改了,变得面目全非。
这两天在看LINUX C编程,才真正了解有了一些以前有所察觉到没弄明白的概念,关于库文件,头文件,编译的包含,源文件之间的链接。
之前我试过在KEIL里做多源文件的链接编译,但是设置好后,可能是因为我的KEIL是EVAL版,没破解全,所以功能上有所限制一直没成功。
所以当时跟anqi90商量了下,最后还是决定用这种头文件包括函数定义的方法。
这种方法应该说是不可接受的,所以希望懂这方面知识的大虾们给我们一些指导,也欢迎拍砖。
顶一下,辛昕辛苦了,看来到了最后整合的时候了。。。。
关于头文件,我其实也不太明白,只是感觉这样比较方便,期待专家讲解一下
[
本帖最后由 anqi90 于 2011-4-27 20:50 编辑 ]
回复 34楼 anqi90 的帖子
嘻嘻~~
其实我也没弄懂过,这两天刚有点儿概念.....
神奇啊,你居然在.....
关于进一步的文档整理和收尾工作的一些想法
此前,对于如何整理文档和收尾,由于我的思路始终被此前策划活动的旧路子影响了,所以始终觉得无从入手。
这两天晚上下班后都没一头扎入没完没了的各种是情理,在闲闲地看网页,发呆。
刚才忽然想到:其实,这个东西做到现在,完全可以分成两大部分考虑。
一就是单片机部分,当然,1602作为最常见的51外围之一,也可以归入进去,我的意思是,这一部分在硬件(原理)上已基本不存在需要特别讨论的地方。
所以,这一部分剩下的任务或者是进一步优化空间主要在于程序。
前面说了,我们的程序在组织的方式上存在很大问题,这主要是我们对于如何规划一个程序还缺乏知识和经验。
其中是如何规划头文件,库文件以及实际实现在KEIL下完成这些工作。
对这方面的成效,我个人的目标目前只有一个:
进一步减少程序占用的FLASH空间,目前我写的程序编译出来后大概占用3.5K左右,我希望能够做到在2K以内,如同原作者一样,可以在2051下面跑。这样,可以物尽其用,我做的那个完整的基于STC12C2052的硬件电路板也能重新发挥作用,也能更进一步的成为一个独立的测量工具。
另一方面,自然就是LM311的测量电路。
在最开始,我的工作就是分析这个电路,当时我以为我已经基本把原理分析清楚了,后来,虽然现在知道当时遇到的问题与硬件无关,只是软件上的失误,但在这些看似无效的硬件分析中,我却也得以更深一步去分析这个电路,我发现了好多我曾经没有注意到的盲点。
所以,关于这一部分,下一步我希望我能更深地透彻分析这个电路,至少说服自己,再说服别人,比如XU_CHANGHUA老师。
因为这个电路真的堪称神兵利器。
500K的高频电路,可是在制作上几乎无需任何注意,起振容易,却又不轻易被干扰。
做的过程里我多次网上搜索相关资料,网上模仿的人很多,包括对这方面要求比较苛刻的无线电爱好者,但是我的观察是,无论是什么人,只要仿制了,并且仿制成功的,无一例外不是惊叹这是个令人amazing的电路。
关于一点补充
32L上传的程序有一点问题。
原来anqi90的程序里用了预定义的方式定义了一些无符号类型数据类型的简单写法
#define uchar unsigned char。
后来我觉得这个写法并不规范,于是就改为 typedef UCHAR unsigned char 当时很奇怪,居然没改动程序别的地方也可以编译通过,后来晚上睡觉的时候想起可能在别的头文件里也定义了,也就是说那个是无意义的。
晚上回来后检查了一下,发现果然如此,于是修改了整个程序。
[
本帖最后由 辛昕 于 2011-4-29 09:23 编辑 ]