今天去白嫖了学校发的一块板子,把常用模块的代码敲一遍再熟悉一下
关于BCD码加减那里是借鉴了博主自由学者亻伊宸
使用P4端口的话要定义一下(使用reg52.h头文件的话)P4=0xc0;
unsigned char duanma[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char duanmadot[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//由duanma高四位减去8得到
unsigned char Writeaddr [7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char Readaddr [7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char Timer[7] = {0x00};//秒 分 时 日 月 周 年
锁存器和板子初始化省略
PCF8591 数模转换 读取电压值
//读取电位器Rb2(03)或者光敏电阻rd1(01)
void ReadRd1 ()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
rb2 = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
}
void PCFADC ()
{
IIC_Start();
IIC_SendByte(0x90);
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 (uchar dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat); //输入255对应输出为5V
IIC_WaitAck();
IIC_Stop();
}
AT24c02 E2PROM掉电存储
uchar 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(int型的);还要注意写入和读取出来的数据都是小于255,否则需要先除以一个数变小
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
DS1802 测量实时温度的
void Read_Temp () //如果读取的温度有问题,那么应该将onewire.c中的延时时间统一扩大10倍
{
unsigned char LSB;
unsigned char MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
tem = (MSB << 8) | LSB;
if ((tem & 0xf800) == 0x0000)
{
tem = tem >> 4;
}
精确到小数点后几位
if ((temp & 0xf800) == 0x0000)
{
temp = temp >> 4;//先把小数位都移走
temp = temp * 10;
temp = temp + (LSB & 0x0f) * 0.0625 * 10; //扩大十倍后的整数部分加上小数部分(小数部分每一个数表示0.0625 C)
}
}
DS1302时钟
void Write_Timer () //需要Writeaddr[7]、Readaddr[7]、Timer[7]三个数组 //Timer[7]用数码管显示的需要/16,因为1302是以十六进制进行存储的
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for (i = 0;i <= 7;i++)
{
Write_Ds1302_Byte(Writeaddr[i],Timer[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void Read_Timer ()
{
unsigned char i;
for (i = 0;i <= 7;i++)
{
Timer[i] = Read_Ds1302_Byte(Readaddr[i]);
}
}
//时钟BCD码加
unsigned char BCD_add(uchar 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码减
unsigned char BCD_minus(uchar 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用跳帽连接P34(T0),然后用定时器的T0计数功能
void InitTime ()
{
TMOD = 0x16;
TH1 = (65535 - 100) / 256;
TL1 = (65535 - 100) % 256;
TH0 = 0xff;
TL0 = 0xff;
TR0 = 1;
TR1 = 1;
ET0 = 1;
ET1 = 1;
EA = 1;
}
void ServiceT0 () interrupt 1
{
}
void ServiceT1 () interrupt 3
{
TH1 = (65535 - 100) / 256;
TL1 = (65535 - 100) % 256;
count++;
if (count >= 10000)
{
count = 0;
}
//数码管实现秒闪
count++;
if (count >= 10000)
{
count = 0;
smg_f = ~smg_f;
}
//pwm脉宽调制
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; //只能用T1口
TL1 = 0xfd;
TR1 = 1;
ES = 1;
EA = 1;
AUXR = 0x00;
SCON = 0x50;
}
void ServiceUart () interrupt 4
{
if (RI == 1)
{
command = SBUF;
RI = 0;
}
}
void SendByte (uchar dat)
{
SBUF = dat;
while (TI == 0);
TI = 0;
}
void SendString (uchar* addr)
{
uchar i = 0;
while (*addr != '\0')
{
SendByte(*addr);
addr = addr + 1;
}
}
void ExecuteCommand ()
{
if (command != 0x00)
{
switch (command & 0xf0)
{
case: 0xa0:
//
command = 0x00;
break;
case: 0xb0:
//
command = 0x00;
break;
//...
}
}
}
数码管和按键不写了,关键是逻辑
超声波 要用到"intrins.h"头文件
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 (来回)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)