From f11925818e8590075725fa238dbf26e1c7cd76df Mon Sep 17 00:00:00 2001 From: fengbh <1953356163@qq.com> Date: Fri, 29 Dec 2023 00:57:13 +0800 Subject: [PATCH] init --- .gitignore | 2 + Makefile | 42 +++++++++++ include/ds18b20.h | 14 ++++ include/intrins.h | 26 +++++++ include/public.h | 14 ++++ include/smg.h | 18 +++++ include/uart.h | 22 ++++++ src/ds18b20.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 80 +++++++++++++++++++++ src/public.c | 25 +++++++ src/smg.c | 36 ++++++++++ src/uart.c | 41 +++++++++++ 12 files changed, 495 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 include/ds18b20.h create mode 100644 include/intrins.h create mode 100644 include/public.h create mode 100644 include/smg.h create mode 100644 include/uart.h create mode 100644 src/ds18b20.c create mode 100644 src/main.c create mode 100644 src/public.c create mode 100644 src/smg.c create mode 100644 src/uart.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a31864 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode/ +uart_temp.hex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bf59b29 --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +# set CC TOOL +CC := sdcc +PACKIHX := packihx + +# set DIR +INCDIR = include +SRCDIR = src +OBJDIR = obj +TARGET = obj/main.ihx + +INC := ./include +SRC := $(wildcard $(SRCDIR)/*.c) +# OBJ := $(SRC:%.c=%.rel) +OBJ := $(patsubst src/%.c, obj/%.rel, $(SRC)) + +.PHONY: all clean + +all: uart_temp.hex + +clean: + -del /q obj\* + +$(OBJ):obj/%.rel:src/%.c + -$(CC) -I $(INC) -c $^ -o $@ + +$(TARGET): $(OBJ) + -$(CC) $^ -o $@ + +uart_temp.hex: $(TARGET) + -$(PACKIHX) $(TARGET) > uart_temp.hex + +flash: + -stcgal -P stc89 -p COM3 .\uart_temp.hex + +#led.bin:led.hex +# objcopy -I ihex -O binary led.hex led.bin + +#led.hex:main.ihx +# packihx main.ihx > led.hex + +# led.bin:main.ihx +# makebin main.ihx led.bin \ No newline at end of file diff --git a/include/ds18b20.h b/include/ds18b20.h new file mode 100644 index 0000000..2801f74 --- /dev/null +++ b/include/ds18b20.h @@ -0,0 +1,14 @@ +#ifndef _ds18b20_H +#define _ds18b20_H + +#include "public.h" + +//管脚定义 +#define DS18B20_PORT P3_7 //DS18B20数据口定义 + +#define _nop_() __asm NOP __endasm +//函数声明 +u8 ds18b20_init(void); +float ds18b20_read_temperture(void); + +#endif \ No newline at end of file diff --git a/include/intrins.h b/include/intrins.h new file mode 100644 index 0000000..b8d7c0a --- /dev/null +++ b/include/intrins.h @@ -0,0 +1,26 @@ +#ifndef _INTRINS_H_ +#define _INTRINS_H_ + +/* warning: __push __pop 使用堆栈临时保存 sfr 数据,必需成对使用! + __push(x); + ... // 保护代码块 + __pop(x); //缺少无该语句编译不会出错,但运行错误! +*/ + #define __push(x) __asm push _##x __endasm /* void _push_ (unsigned char _sfr); */ + #define __pop(x) __asm pop _##x __endasm /* void _pop_ (unsigned char _sfr); */ + + #define _push_ __push  /*兼容 keil c51*/ + #define _pop_ __pop  /*兼容 keil c51*/ + +/* 安全使用保护宏: + pushSfr(x); + ... // 受保护代码块 + popSfr(x); // 缺少无该语句编译出错,确保生成正确代码。 +*/ + #define pushSfr(x) do{\ + __push(x) + + #define popSfr(x) __pop(x);\ + }while(0) + +#endif //_INTRINS_H_ \ No newline at end of file diff --git a/include/public.h b/include/public.h new file mode 100644 index 0000000..499afe6 --- /dev/null +++ b/include/public.h @@ -0,0 +1,14 @@ +#ifndef _public_H +#define _public_H + +// #include "reg52.h" +#include <8052.h> + +typedef unsigned int u16; +typedef unsigned char u8; + + +void delay_10us(u16 ten_us); +void delay_ms(u16 ms); + +#endif diff --git a/include/smg.h b/include/smg.h new file mode 100644 index 0000000..d8ef1aa --- /dev/null +++ b/include/smg.h @@ -0,0 +1,18 @@ +#ifndef _smg_H +#define _smg_H + +#include "public.h" + + +#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口 + +//定义数码管位选信号控制脚 +#define LSA P2_2 +#define LSB P2_3 +#define LSC P2_4 + +extern u8 gsmg_code[17]; + +void smg_display(u8 dat[],u8 pos); + +#endif \ No newline at end of file diff --git a/include/uart.h b/include/uart.h new file mode 100644 index 0000000..85729cc --- /dev/null +++ b/include/uart.h @@ -0,0 +1,22 @@ +/************************************************************************************** +深圳市普中科技有限公司(PRECHIN 普中) +技术支持:www.prechin.net + +实验名称:串口通信实验 +接线说明: +实验现象:下载程序后,当串口助手发送数据给单片机,单片机原封不动转发给串口助手显示 +注意事项:使用黄色跳线帽将CH340旁的P5端子的UTX和P30短接,URX和P31短接,出厂默认已短接好 +***************************************************************************************/ +#ifndef _uart_H +#define _uart_H + +#include "public.h" + +extern __bit busy; + +void uart_init(u8 baud); +void send_string(char *s); +void send_data(u8 dat); +int putchar(char c); + +#endif \ No newline at end of file diff --git a/src/ds18b20.c b/src/ds18b20.c new file mode 100644 index 0000000..8d66bea --- /dev/null +++ b/src/ds18b20.c @@ -0,0 +1,175 @@ +#include "ds18b20.h" +#include "intrins.h" + +/******************************************************************************* +* 函 数 名 : ds18b20_reset +* 函数功能 : 复位DS18B20 +* 输 入 : 无 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_reset(void) +{ + DS18B20_PORT=0; //拉低DQ + delay_10us(75); //拉低750us + DS18B20_PORT=1; //DQ=1 + delay_10us(2); //20US +} + +/******************************************************************************* +* 函 数 名 : ds18b20_check +* 函数功能 : 检测DS18B20是否存在 +* 输 入 : 无 +* 输 出 : 1:未检测到DS18B20的存在,0:存在 +*******************************************************************************/ +u8 ds18b20_check(void) +{ + u8 time_temp=0; + + while(DS18B20_PORT&&time_temp<20) //等待DQ为低电平 + { + time_temp++; + delay_10us(1); + } + if(time_temp>=20)return 1; //如果超时则强制返回1 + else time_temp=0; + while((!DS18B20_PORT)&&time_temp<20) //等待DQ为高电平 + { + time_temp++; + delay_10us(1); + } + if(time_temp>=20)return 1; //如果超时则强制返回1 + return 0; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_bit +* 函数功能 : 从DS18B20读取一个位 +* 输 入 : 无 +* 输 出 : 1/0 +*******************************************************************************/ +u8 ds18b20_read_bit(void) +{ + u8 dat=0; + + DS18B20_PORT=0; + _nop_();_nop_(); + DS18B20_PORT=1; + _nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据 + if(DS18B20_PORT)dat=1; //如果总线上为1则数据dat为1,否则为0 + else dat=0; + delay_10us(5); + return dat; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_byte +* 函数功能 : 从DS18B20读取一个字节 +* 输 入 : 无 +* 输 出 : 一个字节数据 +*******************************************************************************/ +u8 ds18b20_read_byte(void) +{ + u8 i=0; + u8 dat=0; + u8 temp=0; + + for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位 + { + temp=ds18b20_read_bit(); + dat=(temp<<7)|(dat>>1); + } + return dat; +} + +/******************************************************************************* +* 函 数 名 : ds18b20_write_byte +* 函数功能 : 写一个字节到DS18B20 +* 输 入 : dat:要写入的字节 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_write_byte(u8 dat) +{ + u8 i=0; + u8 temp=0; + + for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位 + { + temp=dat&0x01;//选择低位准备写入 + dat>>=1;//将次高位移到低位 + if(temp) + { + DS18B20_PORT=0; + _nop_();_nop_(); + DS18B20_PORT=1; + delay_10us(6); + } + else + { + DS18B20_PORT=0; + delay_10us(6); + DS18B20_PORT=1; + _nop_();_nop_(); + } + } +} + +/******************************************************************************* +* 函 数 名 : ds18b20_start +* 函数功能 : 开始温度转换 +* 输 入 : 无 +* 输 出 : 无 +*******************************************************************************/ +void ds18b20_start(void) +{ + ds18b20_reset();//复位 + ds18b20_check();//检查DS18B20 + ds18b20_write_byte(0xcc);//SKIP ROM + ds18b20_write_byte(0x44);//转换命令 +} + +/******************************************************************************* +* 函 数 名 : ds18b20_init +* 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在 +* 输 入 : 无 +* 输 出 : 1:不存在,0:存在 +*******************************************************************************/ +u8 ds18b20_init(void) +{ + ds18b20_reset(); + return ds18b20_check(); +} + +/******************************************************************************* +* 函 数 名 : ds18b20_read_temperture +* 函数功能 : 从ds18b20得到温度值 +* 输 入 : 无 +* 输 出 : 温度数据 +*******************************************************************************/ +float ds18b20_read_temperture(void) +{ + float temp; + u8 dath=0; + u8 datl=0; + u16 value=0; + + ds18b20_start();//开始转换 + ds18b20_reset();//复位 + ds18b20_check(); + ds18b20_write_byte(0xcc);//SKIP ROM + ds18b20_write_byte(0xbe);//读存储器 + + datl=ds18b20_read_byte();//低字节 + dath=ds18b20_read_byte();//高字节 + value=(dath<<8)+datl;//合并为16位数据 + + if((value&0xf800)==0xf800)//判断符号位,负温度 + { + value=(~value)+1; //数据取反再加1 + temp=value*(-0.0625);//乘以精度 + } + else //正温度 + { + temp=value*0.0625; + } + return temp; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..68bd7a8 --- /dev/null +++ b/src/main.c @@ -0,0 +1,80 @@ +/************************************************************************************** +深圳市普中科技有限公司(PRECHIN 普中) +技术支持:www.prechin.net + +实验名称:DS18B20温度传感器实验 +接线说明: +实验现象:下载程序后,插上DS18B20温度传感器,数码管显示检测的温度值 +注意事项:注意温度传感器的方向,在接口处我们已经用丝印画了一个凸起, + 所以只需要将温度传感器对应插入即可 +***************************************************************************************/ +#include "public.h" +#include "smg.h" +#include "ds18b20.h" +#include "uart.h" +#include "stdio.h" + + +/******************************************************************************* +* 函 数 名 : main +* 函数功能 : 主函数 +* 输 入 : 无 +* 输 出 : 无 +*******************************************************************************/ +void main(void) +{ + + u8 i=0; + int pre_temp_value=0; + int temp_value=0; + u8 temp_buf[5]; + + uart_init(0XFA);//波特率为9600 + ds18b20_init();//初始化DS18B20 + + while(1) + { + i++; + if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间 + temp_value=ds18b20_read_temperture()*10;//保留温度值小数后一位 + + // 数码管显示 + if(temp_value<0)//负温度 + { + temp_value=-temp_value; + temp_buf[0]=0x40;//显示负号 + } + else + temp_buf[0]=0x00;//不显示 + temp_buf[1]=gsmg_code[temp_value/1000];//百位 + temp_buf[2]=gsmg_code[temp_value%1000/100];//十位 + temp_buf[3]=gsmg_code[temp_value%1000%100/10]|0x80;//个位+小数点 + temp_buf[4]=gsmg_code[temp_value%1000%100%10];//小数点后一位 + smg_display(temp_buf,4); + + // 串口打印 + if(pre_temp_value != temp_value){ + pre_temp_value = temp_value; + printf("temp = %f\n", temp_value/10.0); + } + } +} + +void uart(void) __interrupt (4) //串口通信中断函数 +{ + u8 rec_data; + + if(RI) + { + RI = 0; //清除接收中断标志位 + rec_data=SBUF; //存储接收到的数据 + SBUF=rec_data; //将接收到的数据放入到发送寄存器 + while(!TI); //等待发送数据完成 + TI=0; //清除发送完成标志? + } + if(TI) + { + TI = 0; + busy = 0; + } +} \ No newline at end of file diff --git a/src/public.c b/src/public.c new file mode 100644 index 0000000..0e77372 --- /dev/null +++ b/src/public.c @@ -0,0 +1,25 @@ +#include "public.h" + +/******************************************************************************* +* 函 数 名 : delay_10us +* 函数功能 : 延时函数,ten_us=1时,大约延时10us +* 输 入 : ten_us +* 输 出 : 无 +*******************************************************************************/ +void delay_10us(u16 ten_us) +{ + while(ten_us--); +} + +/******************************************************************************* +* 函 数 名 : delay_ms +* 函数功能 : ms延时函数,ms=1时,大约延时1ms +* 输 入 : ms:ms延时时间 +* 输 出 : 无 +*******************************************************************************/ +void delay_ms(u16 ms) +{ + u16 i,j; + for(i=ms;i>0;i--) + for(j=110;j>0;j--); +} \ No newline at end of file diff --git a/src/smg.c b/src/smg.c new file mode 100644 index 0000000..1bc9781 --- /dev/null +++ b/src/smg.c @@ -0,0 +1,36 @@ +#include "smg.h" + +//共阴极数码管显示0~F的段码数据 +u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, + 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; + +/******************************************************************************* +* 函 数 名 : smg_display +* 函数功能 : 动态数码管显示 +* 输 入 : dat:要显示的数据 + pos:从左开始第几个位置开始显示,范围1-8 +* 输 出 : 无 +*******************************************************************************/ +void smg_display(u8 dat[],u8 pos) +{ + volatile u8 i=0; + u8 pos_temp=pos-1; + + for(i=pos_temp;i<8;i++) + { + switch(i)//位选 + { + case 0: LSC=1;LSB=1;LSA=1;break; + case 1: LSC=1;LSB=1;LSA=0;break; + case 2: LSC=1;LSB=0;LSA=1;break; + case 3: LSC=1;LSB=0;LSA=0;break; + case 4: LSC=0;LSB=1;LSA=1;break; + case 5: LSC=0;LSB=1;LSA=0;break; + case 6: LSC=0;LSB=0;LSA=1;break; + case 7: LSC=0;LSB=0;LSA=0;break; + } + SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据 + delay_10us(100);//延时一段时间,等待显示稳定 + SMG_A_DP_PORT=0x00;//消音 + } +} diff --git a/src/uart.c b/src/uart.c new file mode 100644 index 0000000..5bd6078 --- /dev/null +++ b/src/uart.c @@ -0,0 +1,41 @@ +#include "uart.h" + +__bit busy = 0; +/******************************************************************************* +* 函 数 名 : uart_init +* 函数功能 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间 +* 输 入 : baud:波特率对应的TH、TL装载值 +* 输 出 : 无 +*******************************************************************************/ +void uart_init(u8 baud) +{ + TMOD|=0X20; //设置计数器工作方式2 + SCON=0X50; //设置为工作方式1 + PCON=0X80; //波特率加倍 + TH1=baud; //计数器初始值设置 + TL1=baud; + ES=1; //打开接收中断 + EA=1; //打开总中断 + TR1=1; //打开计数器 +} + +void send_string(char *s) +{ + while(*s) + { + send_data(*s++); + } +} + +void send_data(u8 dat) +{ + while(busy); + busy = 1; + SBUF = dat; +} + +int putchar(char c)//重定向 +{ + send_data(c); + return c; +} \ No newline at end of file