This commit is contained in:
fengbh 2023-12-29 00:57:13 +08:00
commit f11925818e
12 changed files with 495 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.vscode/
uart_temp.hex

42
Makefile Normal file
View File

@ -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

14
include/ds18b20.h Normal file
View File

@ -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

26
include/intrins.h Normal file
View File

@ -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_

14
include/public.h Normal file
View File

@ -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

18
include/smg.h Normal file
View File

@ -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

22
include/uart.h Normal file
View File

@ -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

175
src/ds18b20.c Normal file
View File

@ -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;
}

80
src/main.c Normal file
View File

@ -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;
}
}

25
src/public.c Normal file
View File

@ -0,0 +1,25 @@
#include "public.h"
/*******************************************************************************
* : delay_10us
* : ten_us=110us
* : ten_us
* :
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* : delay_ms
* : ms延时函数ms=11ms
* : msms延时时间
* :
*******************************************************************************/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}

36
src/smg.c Normal file
View File

@ -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
pos1-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;//消音
}
}

41
src/uart.c Normal file
View File

@ -0,0 +1,41 @@
#include "uart.h"
__bit busy = 0;
/*******************************************************************************
* : uart_init
* : TH和TL即可确定定时时间
* : baudTHTL装载值
* :
*******************************************************************************/
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;
}