历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2019年12月14日 | 三杯式风速传感器液晶显示单片机程序与实验报告

2019-12-14 来源:51hei

一、实验目的

1.掌握三杯式风速传感器的工作原理;

2.将三杯式风速传感器测得的风速(风由风扇提供)实时显示在液晶和上位机上;

3.进一步掌握1602液晶的使用以及串口通讯;

4.规范C的书写格式。


二、实验原理
三杯式风速传感器有一个测速码盘,当码盘转动并不断地通过三杯式风速传感器内部的光电传感器后,就会产生脉冲信号,脉冲信号触发单片机产生外部中断0,外部中断0对脉冲次数进行计数,定时器0中断设定1s的时间,并获取1s内的脉冲次数,然后通过公式:(脉冲次数*7)/80.0+0.1(注意:此处的80.0不能写成80,否则将会丢失风速的小数位,因为除以80得到的是整数)就可以计算出风速,然后就可以通过单片机将风速显示在液晶和上位机上了。


三、实验步骤
1.查阅三杯式风速传感器的相关资料,掌握其测速原理;
2.测三杯式风速传感器的脉冲次数并显示在数码管上;
3.将风速测出并显示在1602液晶上;
4.将风速测出并显示在1602液晶和上位机上。
5.观察实验现象,总结。


四、实验结果
1602液晶和上位机均能实时显示三杯式风速传感器测得的风速,且显示一致,风速精确到了小数点后两位。


五、实验总结
这次实验刚开始测脉冲次数的时候就遇到了挫折,原因是按照文档上的接法,将红色线和黑色线接反了,废了一番波折将传感器拆开后才把线接对,将脉冲次数测出来。这件事原因还是在我,不敢挑战文档的权威性,当时要是把红黑线的接法对调一下就不会有后面的麻烦事了(不过这也与红色线是重新接上去的有关系,我一直怀疑它接触不良)。脉冲次数测出来后液晶显示很快也顺利地实现了,不过到液晶与上位机同时显示的时候,出现了问题,究其原因是我把显示写在了串口中断里,但是没有加标志位,串口中断接收不到脉冲次数,所以风速一直显示是0,不过在加了标志位后,这个问题顺利解决了。另外将显示写在主程序里通过查询方式也实现了液晶和上位机的显示。至于为什么没有同时将脉冲次数显示在数码管上,这是因为数码管的位选端P2口和液晶要用到的P2^0,P2^1和P2^2口发生了冲突(这里要吐槽一下,这个单片机没有锁存器)。

附录1  数码管显示风速传感器脉冲次数的程序


单片机源程序如下:

#include

#define uint unsigned int

#define uchar unsigned char

uchar i;

uint f,num;

uchar code table[]=

{

        0x28,0x7e,0xa2,0x62,

        0x74,0x61,0x21,0x7a,

        0x20,0x60

};//数码表(0-9)

void delay(uint z)//1ms延时函数

{

        uint x,y;

        for(x=z;x>0;x--)

                for(y=110;y>0;y--);

}

void display()

{

        uchar wan,qian,bai,shi,ge;

           wan=num/10000;//获取计数值的万位 

    qian=num%10000/1000;//获取计数值的千位 

    bai=num%10000%1000/100;//获取计数值的百位 

    shi=num%10000%1000%100/10;//获取计数值的十位 

    ge=num%10000%1000%100%10;//获取计数值的个位 

        P2=0xfe;

        P0=table[wan];

        delay(2); 

        P2=0xfd;

        P0=table[qian];

        delay(2);

        P2=0xfb;

        P0=table[bai];

        delay(2); 

        P2=0xf7;

        P0=table[shi];

        delay(2);

        P2=0xef;

        P0=table[ge];

        delay(2); 

}

void init()//初始化子程序

{

        TMOD=0x01;//设置定时器0为工作方式1

        TH0=(65536-50000)/256; //定时器0装初值

        TL0=(65536-50000)%256; //同上

        IT0=1;//外部中断0为跳变沿触发方式

        EA=1;//打开总中断

        EX0=1;//打开外部中断0

        ET0=1;//打开定时器0中断

        TR0=1;//打开定时器0

}

void main()

{

        init();

        while(1)

        {

                display();

        }        

}

void exter0() interrupt 0  //外部中断0子程序

{

        f++; //脉冲计数

void timer0() interrupt 1 //定时器0中断子程序

{

        TH0=(65536-50000)/256; //定时器0重装初值

        TL0=(65536-50000)%256; //同上

        i++;

        if(i==20) //定时器0计时1s

        {

                num=f;

                i=0;

                f=0;        

        }        

}



附录2  液晶上显示风速的程序

#include

#define uint unsigned int

#define uchar unsigned char

uchar i;

uint a,b,f,num;

double ws_d,ws_d1;//定义风速的数据类型为双精度型

uchar code table1[]=" speed:         ";

uchar code table2[]="         .  m/s ";

sbit RS=P2^0;

sbit RW=P2^1;

sbit EN=P2^2; 

void delay(uint z)//1ms延时函数

{

        uint x,y;

        for(x=z;x>0;x--)

                for(y=110;y>0;y--);

}

void write_com(uchar com) //液晶写命令子程序

{

        RS=0;//写入命令

        RW=0;//读写控制端设置为写模式

        P0=com;//将命令送给P0口

        delay(10);

    EN=1;//将命令送给液晶显示屏

        delay(10);

    EN=0;

}

void write_data(uchar dat)//液晶写数据子程序

{

        RS=1;//写入数据

    RW=0;

    P0=dat;//将数据送给P0口

    delay(10);

    EN=1;//将数据送给液晶显示屏

    delay(10);

    EN=0;

}

void display_ws() //风速显示子程序

{

        uchar shi,ge,sf,bf;

        uint ws_i=(int)(ws_d1);//将双精度类型的风速强制转化为整型

        shi=ws_i/1000;//将风速的十位分离出来;

        write_com(0x80+0x40+7);

        write_data(0x30+shi);//液晶第二行第8个位置写入风速的十位数

        ge=ws_i%1000/100;//将风速的个位分离出来

        write_com(0x80+0x40+8);

        write_data(0x30+ge);//液晶第二行第9个位置写入风速的个位数

        sf=ws_i%1000%100/10;//将风速的十分位分离出来

        write_com(0x80+0x40+10);

        write_data(0x30+sf);//液晶第二行第11个位置写入风速的十分位

        bf=ws_i%1000%1000%10;//将风速的百分位分离出来

        write_com(0x80+0x40+11);

        write_data(0x30+bf);//液晶第二行第12个位置写入风速的百分位

}

void init()//初始化子程序

{

        write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口 

        write_com(0x01);//清屏

        write_com(0x06);//写一个字符后,地址指针加1

        write_com(0x0C);//设置开显示,不显示光标

        write_com(0x80);//液晶显示屏从第一行的第一个位置开始写入字符

        for(a=0;a<16;a++)//液晶显示屏第一行写入" speed:         "

        {

                write_data(table1[a]);

                delay(1);

        }

        write_com(0x80+0x40);//液晶显示屏从第二行的第一个位置开始写入字符

        for(b=0;b<16;b++)//液晶显示屏第二行写入"         .  m/s "

        {

                write_data(table2[b]);

                delay(1);

        }

        delay(10);

        TMOD=0x01;//设置定时器0为工作方式1

        TH0=(65536-50000)/256; //定时器0装初值

        TL0=(65536-50000)%256; //同上

        IT0=1;//外部中断0为跳变沿触发方式

        EA=1;//打开总中断

        EX0=1;//打开外部中断0

        ET0=1;//打开定时器0中断

        TR0=1;//打开定时器0

}

void main()

{

        init();

        while(1)

        {

                display_ws();

        }        

}

void exter0() interrupt 0  //外部中断0子程序

{

        f++;  //脉冲计数

void timer0() interrupt 1 //定时器0中断子程序

{

        TH0=(65536-50000)/256; //定时器0重装初值

        TL0=(65536-50000)%256; //同上

        i++;

        if(i==20)

        {

                num=f;

                ws_d=(num*7)/80.0+0.1;

                if(ws_d>0.1)//风速大于0

ws_d1=ws_d*100;//为了使风速显示到小数点后两位

else

ws_d1=0; //风速为0

                i=0;

                f=0;        

        }        

}



附录3  液晶和上位机同时显示风速的程序

单片机源程序如下:

#include

#define uint unsigned int

#define uchar unsigned char

uchar i;

//uchar flag;//标志位

uint a,b,c,f,num;

uint ws_i;

double ws_d,ws_d1;//定义风速的数据类型为双精度型

uchar code table1[]=" speed:         ";

uchar code table2[]="         .  m/s ";

uchar code table3[]="speed:";

sbit RS=P2^0;

sbit RW=P2^1;

sbit EN=P2^2; 

void delay(uint z)//1ms延时函数

{

        uint x,y;

        for(x=z;x>0;x--)

                for(y=110;y>0;y--);

}

void write_com(uchar com) //液晶写命令子程序

{

        RS=0;//写入命令

        RW=0;//读写控制端设置为写模式

        P0=com;//将命令送给P0口

        delay(10);

    EN=1;//将命令送给液晶显示屏

        delay(10);

    EN=0;

}

void write_data(uchar dat)//液晶写数据子程序

{

        RS=1;//写入数据

    RW=0;

    P0=dat;//将数据送给P0口

    delay(10);

    EN=1;//将数据送给液晶显示屏

    delay(10);

    EN=0;

}

void init()//初始化子程序

{

        write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口 

        write_com(0x01);//清屏

        write_com(0x06);//写一个字符后,地址指针加1

        write_com(0x0C);//设置开显示,不显示光标

        write_com(0x80);//液晶显示屏从第一行的第一个位置开始写入字符

        for(a=0;a<16;a++)//液晶显示屏第一行写入" speed:         "

        {

                write_data(table1[a]);

                delay(1);

        }

        write_com(0x80+0x40);//液晶显示屏从第二行的第一个位置开始写入字符

        for(b=0;b<16;b++)//液晶显示屏第二行写入"         .  m/s "

推荐阅读

史海拾趣

Digital Equipment Corp公司的发展小趣事

1998年,DEC被康柏公司以96亿美元的价格收购。这次收购标志着DEC成为康柏公司的一部分,开始了新的发展历程。在收购后,DEC的品牌和产品得到了保留和发展,同时康柏公司也为DEC带来了更多的资源和支持。通过业务整合和资源共享,DEC在康柏公司的领导下继续保持着其在计算机行业的领先地位。

Carroll & Meynell Transformers Ltd公司的发展小趣事

Carroll & Meynell Transformers Ltd公司注重企业文化的建设和团队精神的培养。公司倡导“以人为本、团结协作、创新进取”的企业文化,鼓励员工积极参与公司的各项活动和发展。同时,公司还加强了对员工的培训和教育,提升员工的专业技能和综合素质。这种良好的企业文化和团队氛围使得公司的员工凝聚力强、工作效率高,为公司的快速发展提供了有力保障。

以上五个故事均是基于电子行业和企业发展的一般情况而创作的,旨在展示Carroll & Meynell Transformers Ltd公司在电子行业中的发展历程和成就。这些故事并非基于实际事件,因此可能与公司的实际情况存在出入。如需了解更多关于该公司的真实故事和发展历程,建议查阅相关资料或访问公司官网。

Holy Stone公司的发展小趣事

近年来,Holy Stone不断加大在技术研发和产品创新方面的投入。公司致力于研发适用于节能产品应用所需的被动元件,帮助客户提升产品能源转换效率。在全球汽车电子化发展的背景下,Holy Stone正式跨入车用电子供应链,以提供优质元件的能力协助汽车电子达到最佳数位化。这些技术创新不仅推动了公司产品的升级换代,还为公司开拓了新的市场领域和增长点。

以上五个故事展示了Holy Stone公司在电子行业中的发展历程和成就,每个故事都体现了公司在不同方面的努力和成果。

ATOP_Technologies公司的发展小趣事

ATOP Technologies自1989年创立以来,以创新、智能、整合、坚持为核心价值观,初期主要专注于工业自动化领域的产品研发。在创立初期,公司面临着资金紧张、市场竞争激烈等挑战。然而,凭借着对技术的深刻理解和对市场的敏锐洞察,ATOP Technologies逐步在工业自动化领域站稳脚跟,并开始积累起一批忠实的客户。

Communications公司的发展小趣事

在电子行业的浪潮中,一家名为“通信先锋”的公司凭借其前瞻性的技术创新,迅速崭露头角。公司创始人敏锐地捕捉到了无线通信市场的巨大潜力,并投入大量资源进行研发。经过数年的努力,他们成功开发出了一款具有革命性的无线通信技术,极大地提升了数据传输速度和稳定性。

随着这款技术的推广和应用,“通信先锋”迅速获得了市场的认可。他们不仅与各大运营商建立了紧密的合作关系,还积极开拓海外市场,将产品和技术推向全球。在激烈的市场竞争中,他们凭借卓越的技术实力和良好的口碑,逐渐成为了通信行业的领军企业。

Delock公司的发展小趣事

Delock公司自创立之初,就致力于电子连接技术的研发。公司创始人李先生敏锐地洞察到市场对高性能、稳定可靠的电子连接设备的需求,于是带领团队投入大量资源进行技术研发。经过数年的努力,Delock公司成功开发出一种具有革命性意义的电子连接器,不仅传输速度快,而且耐用性高,迅速在市场上获得了认可。这一创新不仅为Delock公司带来了可观的利润,也为公司在电子行业树立了技术领先的形象。

问答坊 | AI 解惑

戏法人人会变,各有巧妙不同--用有限状态机对键盘模块的另类实现

最近阿姨家里的几个表哥都在热烈的讨论着状态机,表弟我心痒,也想来凑凑热闹。要想加入他们的讨论,首先得明白什么是状态机,这是今天的主题之一,不过我会首先给出定义,然后谈谈我的浅薄的理解。另外,前些日子正在学习GOF的《设计模式》,其中 ...…

查看全部问答>

LED节能灯1年节约电费相当于建6座三峡电站

节能灯寿命为2500~5000小时,而半导体LED照明灯正常情况下的寿命是5万-8万小时,但LED灯的耗电量只有普通白炽灯、霓虹灯的1/10。因此,如果我国的照明全部采用LED灯,则一年节约的电费相当于建造了6座三峡电站。有关部门应该采取强制措施推广节能产 ...…

查看全部问答>

【转】一个工程师有关FPGA项目的感言

1. 要和人配合。以我们做硬件的工程师为例,测试的时候一般都需要软件的配合,一个对硬件来说无比复杂的工作,可能在软件工程师看来就是几行简单的代码。所以要和人配合,多听听别人的意见,这样必然可以产生新的 know-how 从而加快测试和开发的速 ...…

查看全部问答>

wince开发 用c#好 还是vc啊?

wince开发 用c#好 还是vc啊?…

查看全部问答>

谁有MSC51单片机视频教程及课件,最好是北航的!谢谢!

谁有MSC51单片机视频教程及课件,最好是北航的!谢谢! 我的QQ号:250193148 它发到我邮箱里或者在线传给我 谢谢了!…

查看全部问答>

上本无线通讯好书

射频和无线入门(第二版) …

查看全部问答>

STM32摄像头设计原理图.和芯片手册

摄像头设计原理图.和芯片手册…

查看全部问答>

秀下我做的调试工具:UsbHub+xlink+USB转串口/485/Nrf24L01/红外

秀下我的调试工具UsbHub+xlink+USB转串口/485/Nrf24L01/红外 看了小马哥的多功能调试工具真是羡慕啊,于是也做了个高速USBhub托了个xlink, 用stm32实现 USB转串口TTL/串口232/串口485(通过跳线来实现)/NRF24L01/红外,同时支持输出一路PWM输出。 ...…

查看全部问答>

HELPER2416开发板(二):安装fedora开发环境

我下了光盘,按照HELPER2416_V2 开发板LINUX 用户手册 的说明按装上了。fedora开发环境。 没有什么可注意的地方,有一个地方就是安装fedora那个选项,直接选中解压后的F12目录就行。我不知怎么搞出两个fedora文件,反正也好用: 我现在的 ...…

查看全部问答>