求一个单片机程序 通过独立按键向1602输入键值,按一下加1,最多到3,可以与温度传感器采集到的值相比较

求一个单片机程序 通过独立按键向1602输入键值,按一下加1,最多到3,可以与温度传感器采集到的值相比较,第1张

看看这个,可能稍加修改就可以适合你。

#include <reg52.h>

#include <intrins.h>

#include <stdio.h>

#include <string.h>

#include <absacc.h>

#include <math.h>

#define uchar unsigned char

#define uint unsigned int

sbit LcdRs=P2^0        //1602液晶端口定义

sbit LcdRw=P2^1

sbit LcdEn=P2^2

sbit led1=P3^0

sbit led2=P3^4   //报警灯端口定义

sbit ACC0=ACC^0

sbit ACC7=ACC^7

sbit k_ud=P2^4//定义上下限选择

sbit k_ws=P2^5//定义温度/湿度 选择

sbit k_add=P2^6//定义按键 +

sbit k_sub=P2^7//定义按键 -

bit flag_ud,flag_ws

bit start

uchar str[7]

//向LCD写命令

#define LCD_COMMAND       0    //Command

#define LCD_DATA          1     //Data

#define LCD_CLEAR_SCREEN  0x01      //清屏

#define LCD_HOMING    0X02      //光标返回原点

//设置显示模式

#define LCD_SHOW      0x04    迹桥  //显示开

#define LCD_HIDE      0x00      //显示关

#define LCD_CURSOR    0x02      //显示光标

#define LCD_NO_CURSOR 0x00      //无光标

#define LCD_FLASH     0x01      //光标闪动

#define LCD_NO_FLASH  0x00      //光标不闪动

//输入设置

#define LCD_AC_UP     0x02

#define LCD_AC_DOWN   0x00      //default

#define LCD_MOVE      0x01      //画面可平移

#define LCD_NO_MOVE   0x00      //default

unsigned char  TEMP_UP=20      //温度上限

unsigned char  TEMP_DOWN=0     //温度下限

unsigned char 纤州陆 HUMUP=30     //湿度上限

unsigned char  HUMDOWN=10     //湿度下限

unsigned char dis[4]

unsigned char LCD_Wait(void)

//SHT10设置

sbit SCK =P1^2 毁顷      //定义通讯时钟端口

sbit DATA=P1^3       //定义通讯数据端口

typedef union

{ uint i     //定义了两个共用体

float f

}value

enum {TEMP,HUMI}     //TEMP=0,HUMI=1

#define noACK 0       //用于判断是否结束通讯

#define ACK   1       //结束数据传输

//adr  command  r/w

#define STATUS_REG_W 0x06   //000  0011  0

#define STATUS_REG_R 0x07   //000  0011  1

#define MEASURE_TEMP 0x03   //000  0001  1

#define MEASURE_HUMI 0x05   //000  0010  1

#define RESET        0xle   //000  1111  0

//定义函数

void s_transstart(void)       //启动传输函数

void s_connectionreset(void)  //连接复位函数

char s_write_byte(unsigned char value)//SHT10写函数

char s_read_byte(unsigned char ack)//SHT10读函数

char s_measure(unsigned char*p_value,unsigned char*p_checksum,unsigned char mode)//测量温湿度函数

void calc_dht90(float*p_humidity,float*p_temperature)//温湿度补偿

void LCD_Write(bit style, unsigned char input)

//液晶显示子程序

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

{

int x

for(x=zx>0x--)

{

int y

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

}

}

void dat_char(uchar ff,uchar a)

{

dis[0]=ff      

dis[1]='_'

dis[2]=0x30+a/10

dis[3]=0x30+a%10

}

void LCD_Write(bit style,unsigned char input)

{

LcdRs=style

P0=input

delay(5)

LcdEn=1

delay(5)

LcdEn=0

}

void LCD_SetDisplay(unsigned char DisplayMode)   //设置输出

{

LCD_Write(LCD_COMMAND,0x08|DisplayMode)

}

void LCD_SetInput(unsigned char InputMode)       //设置输入

{

LCD_Write(LCD_COMMAND,0x04|InputMode)

}

void LCD_Initial()        //初始化LCD函数

{

LcdEn=0

LCD_Write(LCD_COMMAND,0x38)      //8位数据端口,2行显示,5*7点阵

LCD_Write(LCD_COMMAND,0x38)

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR)     //开启显示,无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN)    //清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE)        //AC递增,画面不动

}

void GotoXY(uchar x, uchar y)  //液晶字符输入的位置

{

if(y==0)

LCD_Write(LCD_COMMAND,0x80|x)

if(y==1)

LCD_Write(LCD_COMMAND,0x80|(x-0x40))

}

void Rrint(uchar *str)                  //将字符输出到液晶显示

{

while(*str!='\0')

{

LCD_Write(LCD_DATA,*str)

str++

}

}

void zhuanhuan(float a)                      //浮点数转换成字符串函数

{

memset(str,0,sizeof(str))

sprintf(str,"%f",a)

}

void welcome()          //初始界面函数

{

LCD_Initial()

GotoXY(0,0)

Rrint("   Welcome!  ")

GotoXY(0,1)

Rrint("  Code of sht10 ")

delay(200)

}

/*

void delay_n10us(uint n)   //延时n个10us@12M晶振

{

uint i

for(i=ni>0i--)

{

_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()

}

} */

void s_transstart(void)         //启动函数

{

DATA=1SCK=0

_nop_()

SCK=1

_nop_()

DATA=0

_nop_()

SCK=0

_nop_()_nop_()_nop_()

SCK=1

_nop_()

DATA=1

_nop_()

SCK=0

}

void s_connectionreset(void)      //连接复位函数

{

uchar i

DATA=1SCK=0              //Initial state

for(i=0i<9i++)           //9 SCK cycles

{

SCK=1

SCK=0

}

s_transstart()

}

char s_write_byte(unsigned char value)    //SHT10写字节函数

{

uchar i,error=0

for (i=0x80i>0i/=2)         //shift bie for masking

{

if(i&value)DATA=1       //masking value with i,write to SENSI-BUS

else DATA=0

SCK=1

_nop_()_nop_()_nop_()    //pulswith approx. 3 us

SCK=0

}

DATA=1        //release DATA-line

SCK=1        //clk#9for ack

error=DATA     //check ack(DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。

_nop_()_nop_()_nop_()

SCK=0

DATA=1                     //release DATA-line

return error    //error=1 in case of no acknowledge//返回:0成功 1失败

}

//SHT10读取函数

char s_read_byte(uchar ack)

{

uchar i,val=0

DATA=1        //release DATA-line

for(i=0x80i>0i/=2)    //shift bit for masking

{SCK=1

if(DATA)val=(val|i)     //read bit

_nop_()_nop_()_nop_()     //pulswith approx.3 us

SCK=0

}

if(ack==1)DATA=0         //in case of"ack==1"pull down DATA-Line

else DATA=1         //如果是校验(ack=0),读取完后结束通讯

_nop_()_nop_()_nop_()  //pulswith approx. 3 us

SCK=1             //clk#9 for ack

_nop_()_nop_()_nop_()   //pulswith approx. 3 us

SCK=0

_nop_()_nop_()_nop_()   //pulswith approx. 3 us

DATA=1                    //release DATA-line

return val

}

//测量温湿度函数

char s_measure(uchar *p_value,uchar *p_checksum,uchar mode)

{

unsigned error=0

uint i

s_transstart()      //transstart atart

switch(mode)     //send command to sensor

{

case TEMP :error+=s_write_byte(MEASURE_TEMP)break

case HUMI :error+=s_write_byte(MEASURE_HUMI)break

default   :break

}

for(i=0i<65535i++)if(DATA==0)break  //wait until sensor has finishede the measurement

if(DATA)error+=1      //or timeout(~2 sec.)is reached

*(p_value) =s_read_byte(ACK)  //read the first byte(MSB)

*(p_value+1)=s_read_byte(ACK)  //read the second byte(LSB)

*p_checksum=s_read_byte(noACK)  //read checksum

return error

}

void calc_sht90(float*p_humidity,float*p_temperature)  //温湿度补偿函数

{

const float C1=-4.0     //for 12 Bit

const float C2=+0.0405  //for 12 Bit

const float C3=-0.0000028  //for 12 Bit

const float T1=+0.01       //for 14 Bit@5V

const float T2=+0.00008    //for 14 Bit@5V

float rh=*p_humidity       //rh:  Humidity[Ticks]12 Bit

float t=*p_temperature     //t:   Temperature[Ticks]14 Bit

float rh_lin               //rh_lin: Humidity linear

float rh_true              //rh_true:Temperature compensated humidity

float t_C                  //t_C : Temperature[C]

t_C=t*0.01-40            //calc.temperature from ticks to [C]

rh_lin=C3*rh*rh+C2*rh+C1  //calc.humidity from ticks to[%RH]

rh_true=(t_C-25)*(T1+T2*rh)+rh_lin  //calc.temperature compensated humidity[%RH]

if(rh_true>100)rh_true=100   //cut if the value is outside of

if(rh_true<0.1)rh_true=0.1   //the physical possible range

*p_temperature=t_C       //return temperature[C]

*p_humidity=rh_true       //return humidity[%RH]

}

void keyscan()

{

if(k_ud==0)

{

delay(10)//去抖动 100ms

if(k_ud==0)

{

while(!k_ud)

flag_ud = ~flag_ud

}

}

if(k_ws==0)

{

delay(10)//去抖动 100ms

if(k_ws==0)

{

while(!k_ws)

flag_ws = ~flag_ws

}

}

if(k_add==0)

{

delay(10)//去抖动 100ms

if(k_add==0)

{

while(!k_add)

GotoXY(12,0)

if(!flag_ws)

{

if(flag_ud){TEMP_UP++dat_char('T',TEMP_UP)}

else {TEMP_DOWN++dat_char('T',TEMP_DOWN)}

Rrint(&dis)

}

else

{

if(flag_ud){HUMUP++dat_char('H',HUMUP)}

else {HUMDOWN++dat_char('H',HUMDOWN)}

Rrint(&dis)

}

}

}

if(k_sub==0)

{

delay(10)//去抖动 100ms

if(k_sub==0)

{

while(!k_sub)

GotoXY(12,1)

if(!flag_ws)

{

if(flag_ud){TEMP_UP--dat_char('T',TEMP_UP)}

else {TEMP_DOWN--dat_char('T',TEMP_DOWN)}

Rrint(&dis)

}

else

{

if(flag_ud){HUMUP--dat_char('H',HUMUP)}

else {HUMDOWN--dat_char('H',HUMDOWN)}

Rrint(&dis)}

}

}

}

//主函数

void main()

{

value humi_val,temp_val

unsigned char error,checksum

bit status_th=0,status_ch=0

unsigned char cnt=0

LCD_Initial()

LcdRw=0

led1=0

led2=0

start=0

s_connectionreset()

welcome()         //显示欢迎画面

delay(20000)

while(1)

{

cnt++

if(!(cnt%10))

{

cnt=0

error=0

error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI)

error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP)

if(error!=0)

{

s_connectionreset()        //in case of an erroe:connection reset

}else

{

humi_val.f=(float)humi_val.i    //converts integer to float

temp_val.f=(float)temp_val.i    //converts integer to float

calc_sht90(&humi_val.f,&temp_val.f)//计算温度与湿?

LCD_Initial()

GotoXY(0,0)

Rrint("Tep:")

GotoXY(0,1)

Rrint("Hum:")

zhuanhuan(temp_val.f)   //转换温度为uchar方便液晶显示

GotoXY(4,0)

str[5]=0xDF       //℃的符号

str[6]=0x43

str[7]='\0'

Rrint(str)

if(temp_val.f>TEMP_UP-1||temp_val.f<TEMP_DOWN)

led1=1

else

led1=0

zhuanhuan(humi_val.f)    //转换湿度为uchar方便液晶显示

GotoXY(4,1)

str[5]='%'        //%的符号

str[6]='\0'       //字符串结束标志

Rrint(str)

if((humi_val.f>HUMUP-1)||(humi_val.f<HUMDOWN))

led2=1

else

led2=0

}

}

if(!flag_ws) {GotoXY(12,0)dat_char('T',TEMP_UP)Rrint(&dis)GotoXY(12,1)dat_char('T',TEMP_DOWN)Rrint(&dis)}

else   {GotoXY(12,0)dat_char('H',HUMUP)Rrint(&dis)dat_char('H',HUMDOWN)GotoXY(12,1)Rrint(&dis)}

keyscan()

}

}

P1DIR &= ~BIT3 + BIT6// 设置P1.3 为姿塌输迹肢圆入,P1.6为输出

改为:P1DIR &= ~BIT3P1DIR |= BIT6

中断:饥含

#pragma vector=PORT1_VECTOR //中断服务程序:

__interrupt void p1int(void)

{

P1OUT ^=BIT6

while(p1keyj())

delay_Nms(1)

P1IFG=0

}

独立按键式直接用I/O口线构成的单个按键电路,其特点式每个按键单独占用一根I/O口线,每个按键的工作不会影响其他I/O口线的状态。独立式按键电路配置灵活,软件结构简单,但每个芹如并按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。

独立按键的软件常采用查询式结构。先逐位查询没跟I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。

独立键盘理想的波形是按下去时保持低电平,实际上在上升沿和下降沿的过程中(即按键和离键时的一段微小时间)会出现抖动。消抖的方法有两种,一种是通过硬件:在电路上连个电容;另一种是软件消抖,根据经验增加10ms的延时。

扩展资料:

按键分类与输入原理:

按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯另一类是无触点式开关按键,如电气式按橡枣键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最嫌迹常见的是触点式开关按键。

在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入时与软件结构密切相关的过程。

对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12224340.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存