本次测试包含基本底层——在不冲突的条件下,其包含了数码管, led,按键, DS13B20,DS1302,EEMPRO,串口
的使用,等明天会更新其他的NE555(5位)以及超声波的使用

hc573.c
#include <STC15F2K60S2.H> void SelectHC573(unsigned char n) { switch(n) { case
4: P2 = (P2&0x1f)|0x80; P2 &= 0x1f; break; case 5: P2 = (P2&0x1f)|0xa0; P2 &=
0x1f; break; case 6: P2 = (P2&0x1f)|0xc0; P2 &= 0x1f; break; case 7: P2 =
(P2&0x1f)|0xe0; P2 &= 0x1f; break; } }
led.c
#include <STC15F2K60S2.H> #include "hc573.h" void Led_Disp(unsigned char
addr,enable) { static unsigned char temp = 0x00; static unsigned char temp_old
= 0xff; if(enable) temp |= 0x01<<addr; else temp &= ~(0x01<<addr); if(temp !=
temp_old) { P0 = ~temp; SelectHC573(4); temp_old = temp; } } void Beep(unsigned
char flag) { static unsigned char temp = 0x00; static unsigned char temp_old =
0xff; if(flag) temp |= 0x40; else temp &= ~0x40; if(temp != temp_old) { P0 =
temp; SelectHC573(5); temp_old = temp; } } void Relay(unsigned char flag) {
static unsigned char temp = 0x00; static unsigned char temp_old = 0xff;
if(flag) temp |= 0x40; else temp &= ~0x40; if(temp != temp_old) { P0 = temp;
SelectHC573(5); temp_old = temp; } }
key.c
#include <STC15F2K60S2.H> #include "hc573.h" unsigned char Key_Read() {
unsigned char temp=0; P44=0;P42=1;P35=1;P34=1; if(P33==0) temp=4; if(P32==0)
temp=5; if(P31==0) temp=6; if(P30==0) temp=7; P44=1;P42=0;P35=1;P34=1;
if(P33==0) temp=8; if(P32==0) temp=9; if(P31==0) temp=10; if(P30==0) temp=11;
P44=1;P42=1;P35=0;P34=1; if(P33==0) temp=12; if(P32==0) temp=13; if(P31==0)
temp=14; if(P30==0) temp=15; P44=1;P42=1;P35=1;P34=0; if(P33==0) temp=16;
if(P32==0) temp=17; if(P31==0) temp=18; if(P30==0) temp=19; return temp; }
seg.h
#include <STC15F2K60S2.H> #include "hc573.h" unsigned char code seg_dula[] = {
0xc0, //0 0xf9, //1 0xa4, //2 0xb0, //3 0x99, //4 0x92, //5 0x82, //6 0xf8, //7
0x80, //8 0x90, //9 0xff, 0x88, //A 0x83, //b 0xc6, //C 0xa1, //d 0x86, //E
0x8e //F }; unsigned char code
seg_wela[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void Seg_Disp(unsigned
char wela,dula,point) { P0 = 0xff; SelectHC573(7); //7为内容,消隐 P0 =
seg_wela[wela]; SelectHC573(6); //6为位置,和上面的wela配合,显示每一位 P0 = seg_dula[dula];
if(point) P0 &= 0x7f; SelectHC573(7); //7显示内容以及小数点 }
init.c 初始化函数
#include <STC15F2K60S2.H> #include "hc573.h" void Init() { P0 = 0xff;
SelectHC573(4); P0 = 0x00; SelectHC573(5); }
onewire.c 温度传感器
/* # 单总线代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2.
参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求,进行代码调试和修改。 */ /* 温度模块 */
#include "reg52.h" #include "intrins.h" sbit DQ = P1^4; // void
Delay_OneWire(unsigned int t) { unsigned char i; while(t--){ for(i=0;i<12;i++);
} } // void Write_DS18B20(unsigned char dat) { unsigned char i;
for(i=0;i<8;i++) { DQ = 0; DQ = dat&0x01; Delay_OneWire(5); DQ = 1; dat >>= 1;
} Delay_OneWire(5); } // unsigned char Read_DS18B20(void) { unsigned char i;
unsigned char dat; for(i=0;i<8;i++) { DQ = 0; dat >>= 1; DQ = 1; if(DQ) { dat
|= 0x80; } Delay_OneWire(5); } return dat; } // bit init_ds18b20(void) { bit
initflag = 0; DQ = 1; Delay_OneWire(12); DQ = 0; Delay_OneWire(80); DQ = 1;
Delay_OneWire(10); initflag = DQ; Delay_OneWire(5); return initflag; } float
rd_temp() { unsigned char high,low; init_ds18b20(); Write_DS18B20(0xcc);
Write_DS18B20(0x44); // 先转化,再读取,看顺序,手册 init_ds18b20(); Write_DS18B20(0xcc);
Write_DS18B20(0xbe); low = Read_DS18B20(); high = Read_DS18B20(); return
((high<<8)|low)/16.0; }
iic.c 包含EEMPROM 与 DAC与ADC
/* # I2C代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2.
参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求,进行代码调试和修改。 */ #include
"reg52.h" #include "intrins.h" sbit scl = P2^0; sbit sda = P2^1; #define
DELAY_TIME 5 // static void I2C_Delay(unsigned char n) { do {
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_(); } while(n--); } // void I2CStart(void)
{ sda = 1; scl = 1; I2C_Delay(DELAY_TIME); sda = 0; I2C_Delay(DELAY_TIME); scl
= 0; } // void I2CStop(void) { sda = 0; scl = 1; I2C_Delay(DELAY_TIME); sda =
1; I2C_Delay(DELAY_TIME); } // void I2CSendByte(unsigned char byt) { unsigned
char i; for(i=0; i<8; i++){ scl = 0; I2C_Delay(DELAY_TIME); if(byt & 0x80){ sda
= 1; } else{ sda = 0; } I2C_Delay(DELAY_TIME); scl = 1; byt <<= 1;
I2C_Delay(DELAY_TIME); } scl = 0; } // unsigned char I2CReceiveByte(void) {
unsigned char da; unsigned char i; for(i=0;i<8;i++){ scl = 1;
I2C_Delay(DELAY_TIME); da <<= 1; if(sda) da |= 0x01; scl = 0;
I2C_Delay(DELAY_TIME); } return da; } // unsigned char I2CWaitAck(void) {
unsigned char ackbit; scl = 1; I2C_Delay(DELAY_TIME); ackbit = sda; scl = 0;
I2C_Delay(DELAY_TIME); return ackbit; } // void I2CSendAck(unsigned char
ackbit) { scl = 0; sda = ackbit; I2C_Delay(DELAY_TIME); scl = 1;
I2C_Delay(DELAY_TIME); scl = 0; sda = 1; I2C_Delay(DELAY_TIME); } unsigned char
Ad_Read(unsigned char addr) { unsigned char dat; I2CStart(); I2CSendByte(0x90);
I2CWaitAck(); I2CSendByte(addr); I2CWaitAck(); I2CStart(); I2CSendByte(0x91);
I2CWaitAck(); dat = I2CReceiveByte(); I2CSendAck(1); I2CStop(); return dat; }
void Da_Write(unsigned char temp) { I2CStart(); I2CSendByte(0x90);
I2CWaitAck(); I2CSendByte(0x40); I2CWaitAck(); I2CSendByte(temp); I2CWaitAck();
I2CStop(); } void EMMPROM_Write(unsigned char *string,unsigned char
addr,unsigned char num) { I2CStart(); I2CSendByte(0xa0); I2CWaitAck();
I2CSendByte(addr); I2CWaitAck(); while(num--) { I2CSendByte(*string++);
I2CWaitAck(); I2C_Delay(200); } I2CStop(); } void EMMPROM_Read(unsigned char
*string,unsigned char addr,unsigned char num) { I2CStart(); I2CSendByte(0xa0);
I2CWaitAck(); I2CSendByte(addr); I2CWaitAck(); I2CStart(); I2CSendByte(0xa1);
I2CWaitAck(); while(num--) { *string++ = I2CReceiveByte(); if(num)
I2CSendAck(0); else I2CSendAck(1); } I2CStop(); }
ds1302.c 时钟函数
/* # DS1302代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2.
参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求,进行代码调试和修改。 */ #include
"reg52.h" #include "intrins.h" sbit SCK = P1^7; sbit RST = P1^3; sbit SDA =
P2^3; unsigned char Write_addr[]={0x84,0x82,0x80}; unsigned char
Read_addr[]={0x85,0x83,0x81}; // void Write_Ds1302(unsigned char temp) {
unsigned char i; for (i=0;i<8;i++) { SCK = 0; SDA = temp&0x01; temp>>=1; SCK=1;
} } // void Write_Ds1302_Byte( unsigned char address,unsigned char dat) {
RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302(address);
Write_Ds1302(dat); RST=0; } // unsigned char Read_Ds1302_Byte ( unsigned char
address ) { unsigned char i,temp=0x00; RST=0; _nop_(); SCK=0; _nop_(); RST=1;
_nop_(); Write_Ds1302(address); for (i=0;i<8;i++) { SCK=0; temp>>=1; if(SDA)
temp|=0x80; SCK=1; } RST=0; _nop_(); SCK=0; _nop_(); SCK=1; _nop_(); SDA=0;
_nop_(); SDA=1; _nop_(); return (temp); } void Set_Rtc(unsigned char *ucRtc) {
unsigned char i; Write_Ds1302_Byte(0x8e,0x00); for(i=0;i<3;i++) {
Write_Ds1302_Byte(Write_addr[i],ucRtc[i]); } Write_Ds1302_Byte(0x8e,0x80); }
void Read_Rtc(unsigned char *ucRtc) { unsigned char i; for(i=0;i<3;i++)
ucRtc[i] = Read_Ds1302_Byte(Read_addr[i]); }

uart.c 串口函数——发送与初始化  服务函数放在主函数
#include <STC15F2K60S2.H> #include "intrins.h" void UartInit(void)
//9600bps@12.000MHz,³õʼ»¯º¯Êý { SCON = 0x50; AUXR |= 0x01; AUXR |= 0x04; T2L =
0xC7; T2H = 0xFE; AUXR |= 0x10; EA = 1; ES = 1; } void Send_Byte(unsigned char
dat) { SBUF = dat; while(TI == 0); //²»ÊÇ0¾ÍÍ˳ö TI = 0; } void
Send_String(unsigned char *dat) { while(*dat != '\0') Send_Byte(*dat++); }
 超声波,我们使用的是T1定时器,其中TH为高位TL为低位,TR为计数器,TF为溢出

wave.c
#include "reg52.h" #include "intrins.h" sbit Tx = P1^0; sbit Rx = P1^1; void
Delay13us() //@12.000MHz { unsigned char i; _nop_(); _nop_(); i = 36; while
(--i); } void Wave_Init() { Tx = 1; Delay13us(); Tx = 0; Delay13us(); }
unsigned int Rd_distance() { unsigned int time=0; TMOD &= 0x0f; TH1 = TL1 = 0;
Wave_Init(); TR1 = 1; //¿ªÊ¼¼Æʱ while((Rx == 1)&&(TF1 == 0)); TR1 = 0; if(TF1
== 0) { time = (TH1<<8)|TL1; return (time*0.017); } else { TF1=0; return 0; } }

最后则是他们的使用 main.c
#include <STC15F2K60S2.H> #include "led.h" #include "init.h" #include "seg.h"
#include "key.h" #include "onewire.h" #include "iic.h" #include "ds1302.h"
#include "uart.h" #include "wave.h" #include <stdio.h> /* ÉùÃ÷ÇøÓò */ unsigned
char Key_val,Key_old,Key_down; unsigned char Key_Slow_Down; unsigned char
Seg_Buf[]={10,10,10,10,10,10,10,10}; unsigned char
Seg_Point[]={0,0,0,0,0,0,0,0}; unsigned char Seg_Pos; unsigned int
Seg_Slow_Down; unsigned char ucLed[]={0,0,0,0,0,0,0,0}; unsigned char ucRtc[3]
= {0x08,0x30,0x00}; unsigned char ucRtc_Index=0; unsigned char Uart_Buf[12];
unsigned char Uart_num=0; float temp; float V_dat; unsigned char V_Disp=35;
unsigned int distance; unsigned char Seg_Mode; /* °´¼üº¯Êý */ void Key_Proc() {
if(Key_Slow_Down) return; Key_Slow_Down = 1; Key_val = Key_Read(); Key_down =
Key_val&(Key_old^Key_val); Key_old = Key_val; switch(Key_down) { case 4:
if(++Seg_Mode==5) Seg_Mode = 0; break; case 5: if(Seg_Mode==2) { V_Disp =
V_Disp+5; if(V_Disp==95) V_Disp=0; } break; case 6: if(Seg_Mode==2) { V_Disp =
V_Disp-5; if(V_Disp==0) V_Disp=95; } break; case 7: EMMPROM_Write(&V_Disp,0,1);
break; case 8: sprintf(Uart_Buf,"V=%.2fV \r\n",V_dat); Send_String(Uart_Buf);
break; } } /* ÊýÂë¹Üº¯Êý */ void Seg_Proc() { if(Seg_Slow_Down) return;
Seg_Slow_Down = 1; /* Êý¾Ý¶ÁÈ¡ÇøÓò */ temp = rd_temp(); V_dat =
Ad_Read(0x03)/51.0; Read_Rtc(ucRtc); //¶Áȡʱ¼ä distance = Rd_distance(); /*
Êý¾ÝÏÔʾÇøÓò */ switch(Seg_Mode) { case 0: Seg_Buf[0]=10; Seg_Buf[1]=10;
Seg_Buf[3]=10; Seg_Buf[4]=10; Seg_Buf[5]=(unsigned char)temp/10;
Seg_Buf[6]=(unsigned char)temp%10; Seg_Buf[7]=(unsigned char)(temp*10) % 10;
Seg_Point[6]=1; break; case 1: Seg_Buf[0]=10; Seg_Buf[1]=10; Seg_Buf[3]=10;
Seg_Buf[4]=10; Seg_Buf[5]=(unsigned char)V_dat; // 0~5 Seg_Buf[6]=(unsigned
char)(V_dat*10)%10; Seg_Buf[7]=(unsigned char)(V_dat*100)%10; Seg_Point[6]=0;
Seg_Point[5]=1; break; case 2: Seg_Buf[0]=10; Seg_Buf[1]=10; Seg_Buf[3]=10;
Seg_Buf[4]=10; Seg_Buf[5]=0; Seg_Buf[6]=V_Disp/10; Seg_Buf[7]=V_Disp%10;
Seg_Point[6]=0; Seg_Point[5]=0; break; case 3: Seg_Buf[0]=ucRtc[0]/16;
Seg_Buf[1]=ucRtc[0]%16; Seg_Buf[3]=ucRtc[1]/16; Seg_Buf[4]=ucRtc[1]%16;
Seg_Buf[5]=10; Seg_Buf[6]=ucRtc[2]/16; Seg_Buf[7]=ucRtc[2]%16; break; case 4:
Seg_Buf[0]=10; Seg_Buf[1]=10; Seg_Buf[3]=10; Seg_Buf[4]=10;
Seg_Buf[5]=distance/100; Seg_Buf[6]=distance/10%10; Seg_Buf[7]=distance%10;
break; } } void Led_Proc() { ucLed[0]=1; } void Uart_Proc() { if(Uart_num != 0)
{ if(Uart_Buf[0]=='T'&&Uart_Buf[1]=='i'&&Uart_Buf[2]=='m'&&Uart_Buf[3]=='e') {
Uart_num=0; sprintf(Uart_Buf,"V:is%.2fV\r\n",V_dat); Send_String(Uart_Buf); } }
} void Timer0Init(void) //1??@12.000MHz { AUXR &= 0x7F; //?????12T?? TMOD &=
0xF0; //??????? TL0 = 0x18; //?????? TH0 = 0xFC; //?????? TF0 = 0; //??TF0??
TR0 = 1; //???0???? ET0 = 1; EA = 1; } void TimerServer() interrupt 1 {
if(++Key_Slow_Down==10) Key_Slow_Down=0; if(++Seg_Slow_Down==500)
Seg_Slow_Down=0; if(++Seg_Pos==8) Seg_Pos=0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]); } void UartServer() interrupt 4 { if(RI == 1)
{ RI = 0; Uart_Buf[Uart_num]=SBUF;
//½ÓÊÕÖÃ1£¬È»ºóÖÃ0£¬È»ºó°Ñ·¢Ë͵Ķ«Î÷·Åµ½Êý×éÀï Uart_num++; } } void main() {
Set_Rtc(ucRtc); Init(); EMMPROM_Read(&V_Disp,0,1); Timer0Init(); UartInit();
while(1) { Uart_Proc(); Seg_Proc(); Led_Proc(); Key_Proc(); } }
最后的几天搞定这一篇,明白所有的使用方法,注意的是内存函数那可能出现显示问题,注意需要那个值放入,哪个值显示,可以进行切换尝试一下

同时注意定时器是否有打开,使用什么中断

对于按键长按,如果让他跳的话,就会跳的很快,如果加上延时的话,就没办法显示,所以我在按键中又进行了显示
if(Key_down == 15) Time_Flag=1; if(count<500) { if(Key_up == 15) {
Time_Flag=count=0; temp++; } } else { if(Key_old == 15) { Delay500ms();
Seg_Buf[0]=11; Seg_Buf[6]=temp/10; Seg_Buf[7]=temp%10; temp++; if(temp==100)
temp =99; } if(Key_up == 15) Time_Flag=count=0; }
NE555,我们接好        SIGNAL与P34,调节Rb3
void Timer0Init(void) //1??@12.000MHz { AUXR &= 0x7F; //?????12T?? TMOD &=
0xF0; //??????? TMOD |= 0x05; TL0 = 0; //?????? TH0 = 0; //?????? TF0 = 0;
//??TF0?? TR0 = 1; //???0???? } void Timer1Init(void) //1??@12.000MHz { AUXR |=
0x40; //?????1T?? TMOD &= 0x0F; //??????? TL1 = 0x20; //?????? TH1 = 0xD1;
//?????? TF1 = 0; //??TF1?? TR1 = 1; //???1???? ET1 = 1; EA = 1; } void
TimerServer() interrupt 3 { if(++Key_Slow_Down==10) Key_Slow_Down=0;
if(++Seg_Slow_Down==500) Seg_Slow_Down=0; if(++Seg_Pos==8) Seg_Pos=0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]); if(++Timer_1s==1000) { Timer_1s = 0; TR0=0;
//停止 Freq = (TH0 << 8) | TL0; //TH为高位 TR0=1; //开始 TH0 = TL0 = 0; //重新 } }

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信