历史上的今天
今天是: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 "
史海拾趣
|
戏法人人会变,各有巧妙不同--用有限状态机对键盘模块的另类实现 最近阿姨家里的几个表哥都在热烈的讨论着状态机,表弟我心痒,也想来凑凑热闹。要想加入他们的讨论,首先得明白什么是状态机,这是今天的主题之一,不过我会首先给出定义,然后谈谈我的浅薄的理解。另外,前些日子正在学习GOF的《设计模式》,其中 ...… 查看全部问答> |
|
节能灯寿命为2500~5000小时,而半导体LED照明灯正常情况下的寿命是5万-8万小时,但LED灯的耗电量只有普通白炽灯、霓虹灯的1/10。因此,如果我国的照明全部采用LED灯,则一年节约的电费相当于建造了6座三峡电站。有关部门应该采取强制措施推广节能产 ...… 查看全部问答> |
|
1. 要和人配合。以我们做硬件的工程师为例,测试的时候一般都需要软件的配合,一个对硬件来说无比复杂的工作,可能在软件工程师看来就是几行简单的代码。所以要和人配合,多听听别人的意见,这样必然可以产生新的 know-how 从而加快测试和开发的速 ...… 查看全部问答> |
|
谁有MSC51单片机视频教程及课件,最好是北航的!谢谢! 我的QQ号:250193148 它发到我邮箱里或者在线传给我 谢谢了!… 查看全部问答> |
|
秀下我做的调试工具:UsbHub+xlink+USB转串口/485/Nrf24L01/红外 秀下我的调试工具UsbHub+xlink+USB转串口/485/Nrf24L01/红外 看了小马哥的多功能调试工具真是羡慕啊,于是也做了个高速USBhub托了个xlink, 用stm32实现 USB转串口TTL/串口232/串口485(通过跳线来实现)/NRF24L01/红外,同时支持输出一路PWM输出。 ...… 查看全部问答> |
|
我下了光盘,按照HELPER2416_V2 开发板LINUX 用户手册 的说明按装上了。fedora开发环境。 没有什么可注意的地方,有一个地方就是安装fedora那个选项,直接选中解压后的F12目录就行。我不知怎么搞出两个fedora文件,反正也好用: 我现在的 ...… 查看全部问答> |




