记录一下自己的学习过程
共阳数码管段码表
#include "reg52.h"
#include "ds1302.h"
#include "iic.h"
//定时器辅助寄存器
sfr AUXR = 0x8e; //串口通信时会用到
//独立按键
sbit S4 = P3^3;
sbit S5 = P3^2;
sbit S6 = P3^1;
sbit S7 = P3^0;
//矩阵键盘
sfr P4 = 0xC0; //52的头文件没有P4口,需要我们自己定义
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
//0~9,A-F,“-”,“.”
unsigned char code SMG_Duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0x88,0x80,
0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
//锁存器的选择 传参4是LED小灯接口,5是蜂鸣器继电器,6是数码管位置,7是数码管显示的数值
void SelectHC573(unsigned char channel)
{
switch(channel)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
case 0:
P2 = (P2 & 0x1f) | 0x00;
}
}
//==============================================//
//*****************初始化函数****************//
void InitSystem()
{
SelectHC573(4);
P0 = 0xff;
SelectHC573(5);
P0 = 0x00;
SelectHC573(0);
}
//==============================================//
//*****************PCF8591****************//
//读取电位器Rb2(03)或者光敏rd1
void ReadRd1()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x30);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
rb2 = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
}
//==============================================//
//*****************PCF实现D/A、A/D************//
void PCFADC()
{
IIC_start();
IIC_SendByte(0x90); // 9是1001为固定部分 后面可编程部分0写1读
IIC_WaitAck();
IIC_SendByte(0x43);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
rb2 = IIC_RecByte(); //(用的时候*1.961)
IIC_SendAck(1);
IIC_Stop();
}
void PCFDAC(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat); //输入255对应输出为5V
IIC_WaitAck();
IIC_Stop();
}
//==============================================//
//*****************AT24C02*********************//
unsigned char Read24c02(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1)
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
void Write24c02(unsigned char addr,unsigned char dat)//注意两次写入之间要延时1000(注意Delay的必须是uint类型的);还要注意写入和读取出来的数据都是小于255,否则需要处理才能写入
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//==============================================//
//*******************DS18B20*******************//
void Read_Temp() //当显示出现错误时,可能是底层代码函数提供的频率为12MHZ,而开发板的频率为1MHZ,所以把底层驱动代码所有延时函数时间扩大10倍或者12倍
{
unsigned char LSB; //低八位
unsigned char MSB; //高八位
init_ds18b20();
Write_DS18B20(0xcc);//跳过row字节
Write_DS18B20(0x44);//装换温度
Delay_OneWire(80);//延时 等待温度转换完成
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);//存储温度
// <1> CCH:跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起各种温度转换指令。
// <2> 44H:温度转换指令,启动DS18B20进行温度转换,转换时间最长为500ms(典型值为200ms),结果保存在高速RAM中。
// <3> BEH:读暂存器指令,读取高速暂存存储器9个字节的内容。
LSB = Read_DS18B20(); //低八位先出来
MSB = Read_DS18B20(); //高八位后出来
init_ds18b20(); //DS18B20复位,停止温度读取
tem = MSB & 0x0f; //去掉MS BYTE前的SSSS
tem = (tem << 8) | LSB; //将低八位和高八位合并
if ((tem & 0xf800) == 0x0000) //判断温度正负,高五位为符号位 0为正 1为负
{
tem = tem >> 4; //相当于*0.0625 为什么右移四位相当于*0.0625
}
//国赛可能需要精确到小数点后几位
/*if ((temp & 0xf800) == 0x0000)
{
temp = temp >> 4;//先把小数位都移走
temp = temp * 10;
temp = temp + (LSB & 0x0f) * 0.0625 * 10; //扩大十倍后的整数部分加上小数部分(小数部分每一个数表示0.0625 C)
}*/
}
//============================================================//
//*******************DS1302******************//
void Write_Timer()
{
unsigned char i;
Write_Ds1302_Byte(0x80,0x00);
for(i = 0;i<=7;i++)
{
Write_Ds1302_Byte(Writeaddr[i],Timer[i]);
}
Write_Ds1302_Byte(0x80,0x80);
}
void Read_Timer()
{
unsigned char i;
for(i = 0;i <= 7;i++)
{
Timer[i] = Read_Ds1302_Byte(Readaddr[i]);
}
}
//时钟BCD码加
uchar BCD_add(unsigned char dat)
{
dat = dat + 1;
switch (dat)
{
case 10:dat = 16;break;
case 26:dat = 32;break;
case 42:dat = 48;break;
case 58:dat = 64;break;
case 74:dat = 80;break;
case 90:dat = 0;break;
}
return dat;
}
//时钟BCD码减
uchar BCD_minus(unsigned char dat)
{
dat = dat - 1;
switch (dat)
{
case -1:dat =89;break;
case 79:dat = 73;break;
case 63:dat = 57;break;
case 47:dat = 41;break;
case 31:dat = 25;break;
case 15:dat = 9;break;
}
return dat;
}
//============================================================
//*******************定时器******************//
//T1(16位计时)定时100us,T0(8位自动重装计数)用作NE555 NE555自动输出一定频率的信号到SIGNAL引脚,用跳帽连接P34(T0),然后用定时器的T0计数功能
void InitTime()
{
TMOD = 0x16;
TH1 = (65535-100)/256;
TL1 = (65535-100)%256;
TH0 = 0xff;
TH1 = 0xff;
TR0 = 1;
TR1 = 1;
ET0 = 1;
ET1 = 1;
EA = 1;
}
void ServiceT0() interrupt 1
{
f_c++;
}
void ServiceT1() interrupt 3
{
TH1 = (65535-100)/256;
TL1 = (65535-100)%256;
count++;
if(count >= 10000)
{
dat_f = f_c;
count = 0;
f_c= 0;
}
//数码管实现秒闪
count++;
if (count >= 10000)
{
count = 0;
smg_f = ~smg_f;
}
//pwm脉宽调制 //共一百份,下面的函数给pwm_t赋值,pwm_f作为控制开关
pwm_c ++;
if (pwm_c >= pwm_t)
{
pwm_f = 0;
if (pwm_c >= 100)
{
pwm_c = 0;
pwm_f = 1;
}
}
}
//============================================================
//*******************外部中断******************//
void InitINT0()
{
IT0 = 1;
EX0 = 0;
EA = 1;
}
void ServiceINT0() interrupt 0
{
//写下启动中后进行的程序
}
//============================================================//
//*******************串口通信******************//
void InitUart()
{
TMOD = 0x21;
TH1 = 0xfd;
TL1 = 0xfd;
TR1= 1;
ES = 1;
EA = 1;
AUXR = 0x00;
SCON = 0x50;
}
void ServiceUart() interrupt 4
{
if(RI == 1)
{
command = SUBF;
RI = 0;
}
}
void SendByte(unsigned char dat)
{
SBUF = dat;
while ( TI == 0);
TI = 0;
}
void SendString(unsigned char *addr)
{
unsigned char i = 0;
while(*addr != '\0')
{
SendByte(*addr);
addr++;
}
}
void ExecuteCommand ()//这个函数是用来判断啥的????????
{
if (command != 0x00)
{
switch (command & 0xf0)
{
case: 0xa0:
//
command = 0x00;
break;
case: 0xb0:
//
command = 0x00;
break;
//...
}
}
}
//============================================================//
//*******************数码管******************//
void Delay_SMG(unsigned int t)
{
while(t--);
}
void ShowSMG_Bit(unsigned char value,unsigned char pos)
{
SelectHC573(7);
P0 = 0xff;
SelectHC573(6);
P0 = 0x01 << pos-1;
SelectHC573(7);
P0 = value;
SelectHC573(0);
}
void ShowALlSMG(unsigned char dat)
{
SelectHC573(6);
P0 = 0xff;
SelectHC573(7);
P0 = dat;
}
void ShowSMG() //这个函数是用来干嘛的
{
if (k4 == 0)
{
ShowSMG_Bit(1,0xc1);
Delay_SMG (500);
ShowSMG_Bit(6,duanmadot[dat_u / 100]);
Delay_SMG (500);
ShowSMG_Bit(7,duanma[(dat_u / 10) % 10]);
Delay_SMG (500);
ShowSMG_Bit(8,duanma[dat_u % 10]);
Delay_SMG (500);
}
else if (k4 == 1)
{
ShowSMG_Bit(1,0x8e);
Delay_SMG (500);
if (dat_f > 99999)
{
ShowSMG_Bit(3,duanma[(dat_f / 100000) % 10]);
Delay_SMG (500);
}
if (dat_f > 9999)
{
ShowSMG_Bit(4,duanma[(dat_f / 10000) % 10]);
Delay_SMG (500);
}
if (dat_f > 999)
{
ShowSMG_Bit(5,duanma[(dat_f / 1000) % 10]);
Delay_SMG (500);
}
if (dat_f > 99)
{
ShowSMG_Bit(6,duanma[(dat_f / 100) % 10]);
Delay_SMG (500);
}
if (dat_f > 9)
{
ShowSMG_Bit(7,duanma[(dat_f / 10) % 10]);
Delay_SMG (500);
}
ShowSMG_Bit(8,duanma[(dat_f / 1) % 10]);
Delay_SMG (500);
}
All_SMG(0xff);
}
//============================================================
//*************************独立按键*********************
void Dealy(unsigned char t)
{
while(t--);
}
void ScanKeys()
{
if(S4 == 0)
{
Delay(500);
if(S4 == 0)
{
while(S4 == 0)
{
//
}
}
}
if(S5 == 0)
{
Delay(500);
if(S5 == 0)
{
while(S5 == 0)
{
//
}
}
}
if(S6 == 0)
{
Delay(500);
if(S6 == 0)
{
while(S6 == 0)
{
//
}
}
}
if(S7 == 0)
{
Delay(500);
if(S7 == 0)
{
while(S7 == 0)
{
//
}
}
}
}
//===================================================
//*******************矩阵键盘***************************
void ScanKeysMulti()
{
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
//S7
}
else if(C2 == 0)
{
}
else if(C3 == 0)
{
}
else if(C4 == 0)
{
}
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
}
else if(C2 == 0)
{
}
else if(C3 == 0)
{
}
else if(C4 == 0)
{
}
//.........
}
//*********************超声波************************
void Delay12us() //@12.000MHz //烧录软件生成的软件精准延时函数(stc_Y5)
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void SendWave () //40KHZ,8组方波脉冲,TX发射
{
uchar i;
for (i = 0;i < 8;i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void DistanceMeasure () //定时器TH0,TL0从空开始计时
{
TMOD &= 0x0f; //TMOD = 0x00;
TH1 = 0x00; //定时器0也可以,到时候根据需要选择即可
TL1 = 0x00;
//ET1 = 1;
//EA = 1;
SendWave ();
TR1 = 1;
while ((RX == 1) && (TF1 == 0)); //如果没有溢出也没有接收到那就一直等,RX为低有效
TR1 = 0;
if (TF1 == 1)
{
distance = 999;
TF1 = 0; //溢出之后要把标志位恢复
}
else
{
time = (TH1 << 8) | TL1;
distance = time * 0.0172; //0.0172cm/us (来回)
}
}
void Delay (uchar n) //多次显示,效果更好一点
{
while (n--)
{
ShowSMG ();
}
}
//=========================================================
void main()
{
while(1)
{}
}