文章目录
1. 需要记住的寄存器总结
2. 需要记住的20种必背功能模块代码
//****************存储模块****************************//
void write_eeprom(unsigned char add,unsigned char val)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(val);
IIC_WaitAck();
IIC_Stop();
}
write_eeprom(0,juli);
delay(10);
//在主函数里初始化读取
juli=read_eeprom(0);
//读存储值
unsigned char read_eeprom(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
temp=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return temp;
}
//****************读ADC模块****************************//
unsigned char adc_pcf8591(unsigned char a)
{ unsigned char ad;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(a);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ad=IIC_RecByte();//从总线上读数据
IIC_Ack(0); //应答
IIC_Stop();
return ad;
}
//****************读ADC模块****************************//
//****************读DAC输出模块****************************//
void dac_pcf8591(unsigned char dat)
{
i2c_start();
i2c_sendbyte(0x90);
i2c_waitack();
i2c_sendbyte(0x40); //DAC输出模式
i2c_waitack();
i2c_sendbyte(dat);
i2c_waitack();
i2c_stop();
}
//****************读DAC输出模块****************************//
//****************读时间模块****************************//
//---DS1302写入和读取时分秒的地址 ---//
//---秒分时日月周年-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//---DS1302时钟初始化为2013年1月1日星期二12点00分00秒 ---//
uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};
unsigned char time_table[]={0x00,0x30,0x08};//必须要加0x00
unsigned char write[]={0x80,0x82,0x84};
unsigned char read[]={0x81,0x83,0x85};
void Ds1302_init()
{
unsigned char n;
//Ds1302_Single_Byte_Write(0x8e,0x01); //可以省略
for(n=0;n<2;n++)
Ds1302_Single_Byte_Write(write[n],time_table[n]);
//Ds1302_Single_Byte_Write(0x8e,0x00);
}
void read_time()
{
unsigned char i;
for(i=0;i<2;i++)
time_table[i]=Ds1302_Single_Byte_Read(read[i]);
}
//****************读时间模块****************************//
//****************读温度模块****************************//
unsigned char read_18b20_data()
{
unsigned char low,high,da;
//温度转换命令
Init_DS18B20();
Write_DS18B20(0xcc);//跳过ROM操作
Write_DS18B20(0x44);//温度转换命令
Delay_OneWire(200);
//发送温度转换
Init_DS18B20();
Write_DS18B20(0xcc);//跳过ROM操作
Write_DS18B20(0xbe);//发送读取温度命令
//读温度
low=Read_DS18B20();
high=Read_DS18B20();
da=(low>>4)|(high<<4);
return da;
}
//温度只需要读取,无需换算(为两位数)
buf[4]=temp/10;
buf[5]=temp%10;
//****************读温度模块****************************//
//****************数码管显示模块****************************//
//段选 //-- //C
uchar duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};
//位选
uchar Disp_sbuf[]={10,10,11,10,10,11,10,10};
//一、显示第一种(首选第一种)
uchar Disp_i;
void Display()
{
P2=((P2&0X1F)|0XE0);
P0=0XFF;
P2&=0X1F;
P0=1<<Disp_i;
P2=((P2&0X1F)|0XC0);
P2&=0X1F;
P0=Disp_tab[Disp_sbuf[Disp_i]];
P2=((P2&0X1F)|0Xe0);
P2&=0X1F;
if( ++Disp_i == 8 )
{
Disp_i = 0;
}
}
//二、显示第二种
code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
uchar wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void display(uchar adr,uchar dat)
{
uchar i=255;
P2=P2&0x1f|0xc0;
P0=wei[adr];
P2=P2&0x1f|0Xe0;
P0=duan[dat];
while(i--);
P0=0xff;
P2&=0x1f;
}
//定时器0
//显示函数放这里面
void time0()
{
TMOD|=0X01;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
ET0=1;
TR0=1;
EA=1;
}
void time() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
display();
}
//****************数码管显示模块****************************//
//****************独立按键检测模块****************************//
Uchar R, key_value;
Void key ()
{
if((P3&0X0F)!=0X0F)
{
delay(10); //10ms
if((P3&0X0F)!=0X0F)
{
R=1;
switch(P3&0X0F)
{
case 0x0d: key_value=2;break;
case 0x0b: key_value=3;break;
case 0x07: key_value=4;break;
}
}
}
if(R==1)
{
R=0;
return key_value;
}
return 0xff;
}
//****************独立按键检测模块****************************//
//****************矩阵键盘检测模块****************************//
uchar key_re=0;
uchar key_press;
uchar key_value;
uchar key_1()
{
static uchar col;
P3=0xf0;P42=1;P44=1;
if((P3!=0xf0)||(P42!=1)||(P44!=1))
key_press++;
else
key_press = 0;
if(key_press == 3)
{
key_press = 0;
key_re = 1;
// if(P44 == 0) col = 1;
if(P42 == 0) col = 0;
if((P3 & 0x20) == 0) col = 1;
if((P3 & 0x10) == 0) col = 2;
P3 = 0x0F; P42 = 0; P44 = 0;
if((P3&0x01) == 0) key_value = (col+6);
if((P3&0x02) == 0) key_value = (col+3);
if((P3&0x04) == 0) key_value = (col+0);
if((P3&0x08) == 0) key_value = (col+9);
}
if(key_re == 1)
{
key_re = 0;
return key_value;
}
return 0xff;
}
//****************矩阵键盘检测模块****************************//
//****************温度记录器模块****************************//
//温度记录器 间隔采集
uchar time[4]={1,5,30,60};//温度采集间隔可选值
void DisplayTime()
{
static uchar CountNum,flag;
uchar second= Timevalue[0];//读取时间
uint NowTime=Timevalue[1]*60+Timevalue[0];
if(second-CountNum!=0) //间隔闪烁
{
CountNum=second;
flag++;
flag%=2;
}
if((NowTime-FirstTime)!=0)//达到需要的时间
{
if((NowTime-FirstTime)%time[WidthNumIndex]==0)
{
FirstTime=NowTime;
if(SaveTemp(Tempvalue)==1)//存储数据并判断是否存满
{
MenNum=2;//数据存满 显示温度
LEDcontrol(1);//开启LED
}
}
}
if(flag)//间隔闪烁
{
DisplayBit(2,10);
DisplayBit(5,10);
}
DisplayBit(0,Timevalue[2]/16);
DisplayBit(1,Timevalue[2]%16);
DisplayBit(3,Timevalue[1]/16);
DisplayBit(4,Timevalue[1]%16);
DisplayBit(6,second/16);
DisplayBit(7,second%16);
}
//****************温度记录器模块****************************//
//****************模拟风扇控制系统****************************//
//模拟风扇控制系统 调占空比
uchar pwm_h=10;
uchar pwm_l=10;
uchar pwm=0;
void time1() interrupt 3 //一定是3
{
if(pwm_flag==1)
{ pwm++;
if(pwm==pwm_h-pwm_count)
P04=1;
if(pwm==pwm_l)
{P04=0;
pwm=0;
}
}
}
//****************模拟风扇控制系统****************************//
//****************LED控制模块****************************//
#define led1 0xfe
#define led2 0xfd
#define led3 0xfb
#define led_off 0xff
void tishi_led()
{
if(a==1)
{
P2=P2&0X1F|0X80;
P0=led_off&led;
P2&=0X1F;
}
if(a==0)
{
P2=P2&0X1F|0X80;
P0=led_off;
P2&=0X1F;
}
}
//****************LED控制模块****************************//
//****************模拟智能灌溉系统****************************//
//难点:手动模式切换提示音
#define buzz_open 0x40
#define relay_open 0x10
#define br_off 0x00
uchar buzz=buzz_open,relay=br_off;
if(moshi==1)
{
if(b1==0)
{
if(AD<yuzhi)
{
P2=P2&0X1F|0XA0;
P0=relay|buzz;//前者是继电器 或者 蜂蜜器
P2&=0X1F;
b1=1;b2=0;
}
}
if(b2==0)
{
if(AD>yuzhi)
{
P2=P2&0X1F|0XA0;
P0=relay|br_off;
P2&=0X1F;
b1=0;b2=1;
}
}
}
//****************模拟智能灌溉系统****************************//
//****************温度采集与控制装置****************************//
//难点:1.LED在不同模式下闪烁频率不同 2.修改温度上下限
//清除
if(KeyValue==11)
{
for(i=0;i<4;i++)
buf[i]=0;
i=0;
}
if(MenNum&&(KeyValue<=9))
{ //if(status)//不能删
// {
// status=0;
MenNum=2;
// }
buf[i++]=KeyValue;//位置不能变
i%=4;
}
}
//不同频率闪烁
void timer_1() interrupt 1
{
static uchar i=0,flag;
TH0=(65536-10000)/256; // 10ms
TL0=(65536-10000)%256;
i++;
switch(way)
{ case 0:
if(i==80)
{
i=0;
flag++;
flag%=2;
if(flag) led_control(control,1);
else led_control(control,0);
};break;
case 1:
if(i==40)
{
i=0;
flag++;
flag%=2;
if(flag) led_control(control,1);
else led_control(control,0);
};break;
case 2:
if(i==20)
{
i=0;
flag++;
flag%=2;
if(flag)
led_control(control,1);
else
led_control(control,0);
};break;
}
}
//l当MAX<MIN时其L2一直亮
//LED控制
void led_control(uchar a,uchar b)
{
if(a&b)
{
P2=P2&0X1F|0X80;
P0=0Xfc; //低位前两位灯亮 or ~0x03
P2&=0x1f;
}
else if(a&b==0)
{
P2=P2&0X1F|0X80;
P0=0Xfd;
P2&=0x1f;
}
else if(a==0&b)
{
P2=P2&0X1F|0X80;
P0=~0X01;
P2&=0x1f;
}
else
{
P2=P2&0X1F|0X80;
P0=0xff;
P2&=0x1f;
}
}
//****************温度采集与控制装置****************************//
//****************超声波模块****************************//
//1.定时器0
uchar wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void Init()
{
P2=P2&0x1f|0x80;
P2=P2&0x1f|0xa0;
P0=0x00;
P2&=0x1f;
}
void DisplayBit(uchar adr,uchar dat)
{
uchar i=200;
P2=P2&0x1f|0xc0;
P0=wei[adr];
P2&=0x1f;
P2=P2&0x1f|0xe0;
P0=duan[dat];
while(i--);
P0=0xff;
P2&=0x1f;
}
void delay_8us()
{
uchar i;
_nop_();
_nop_();
i=21;
while(i--);
}
uint StartCheck()
{
uchar i;
uint distance,time;
for(i=0;i<8;i++)
{
P10=1;
delay_8us();
P10=0;
delay_8us();
}
TR0=1;
while(P11==1&&(TF0==0));
TR0=0;
if(TF0)
{
TF0=0;
distance=4000;
}
else
{
time=TH0;
time<<=8;
time|=TL0;
distance=(uint)(time*0.017);//us *1000000 =s *340m/s *100cm
TH0=0;
TL0=0;
}
return distance;
}
void Timerinit()
{
TMOD|=0x01;
TH0=0;
TL0=0;
TR0=0;
TF0=0;
}
uint dis;
void main()
{
uchar i=0;
Init();
Timerinit();
while(1)
{
dis=StartCheck();
}
}
//2.定时器1
void time1()
{
TMOD|=0X10;
TH1=0;
TL1=0;
TR1=0;
}
void friger_t() //振荡
{
uchar r=0;
for(;r<8;r++)
{
Delay8us();//8US最好
P10=~P10;
}
}
//第一种“测距”核心代码
uint receive_distance()
{
uint distance;
friger_t();
TR1=1; //开始计数
while((P11==1)&&TF1==0); //正常接收返回低电平P11=0,溢出时返回TF1=1
TR1=0; //关闭计数
if(TF1)
{
TF1=0;
distance=150;
}
else
{
distance=(uint)(8<<TH1)+TL1;
distance=distance*0.17*1.08;
}
TH1=0;
TL1=0;
return distance;
}
int main() //主函数调用超声波模块
{
int_1();
time1();
while(1)
{
if(flag==1) //最好10MS读一次
{
flag=0;
dis_juli=receive_distance(); //读距离
}
display1();
}
}
//超声波的显示格式
DisplayBit(1,dis/1000);
DisplayBit(2,dis%1000/100);
DisplayBit(3,dis%100/10);
DisplayBit(4,dis%10);
//第二种“测距”核心代码
void trigSig()
{
unsigned char i;
for(i=0;i<8;i++)
{
delayus(); //这个延时要保证P10保持在40Khz的情况下震荡
P10=~P10;
}
}
//接收并处理函数如下:(这里采用的是定时器1)
unsigned int recevieSig()
{
unsigned int distance;
TH1=0;
TL1=0; //初始化计数
trigSig(); //发送信号
TR1=1; //开启定时器计数
while(P11==1&&TF1==0); //当P11=0或者计数计满时跳出
TR1=0; //停止计数
if(TF1) //表示计数计满 达到软件限定最远距离
{
distance =150;
TF1=0;
}
else
{
distance = (unsigned int)(TH1<<8)+TL1;
distance = distance *0.017*1.085; //单位cm
}
return distance;
}
//****************超声波模块****************************//
//****************读电位器值(光敏电阻)模块****************************//
Temp = PCF8591_ADC_Read();
Temp = Temp * 0.0195 * 100;
Disp_sbuf[5] = Temp / 100;
Disp_sbuf[6] = Temp % 100 / 10;
Disp_sbuf[7] = Temp % 10;
if(Temp > 100)
{
P0=0Xfe;
P2=((P2&0X1F)|0X80);
P2&=0X1F;
}
else
{
P0=0Xfd;
P2=((P2&0X1F)|0X80);
P2&=0X1F;
}
//通过调adc控制LED的亮度
if(PCF85091_read_flag)
{ PCF85091_read_flag=0;
PCF85091_read_val = PCF85091_read(0x03); //1-4四个亮度 0-255
PCF85091_read_val = PCF85091_read_val/255*5;
if((PCF85091_read_val >= 0)&&(PCF85091_read_val < 1.25))
{
LED_level_index =5;
}
else if((PCF85091_read_val >= 1.25)&&(PCF85091_read_val < 2.5))
{
LED_level_index =10;
}
if((PCF85091_read_val >= 2.5)&&(PCF85091_read_val < 3.75))
{
LED_level_index =15;
}
if((PCF85091_read_val >= 3.75)&&(PCF85091_read_val <= 5))
{
LED_level_index =20;
}
}
void time0() interrupt 1
{
static uint q;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
j++;
t++;
q++;
display();
if(q>=200)
{
q=0;
PCF85091_read_flag =1;
}
if(key_value)
{
display1();
key_value=0;
}
if(t==50){led_flag=1;}
if(j >=20) j=0;
if(j <= LED_level_index)
{
P2=P2&0X1F|0X80;P0 =led_temp; P2&=0X1F;
}
else
{
P2=P2&0X1F|0X80; P0 =0xff; P2&=0X1F;
}
}
//****************读电位器值(光敏电阻)模块****************************//
//****************几种按键控制模块总结****************************//
//一、一直按按键显示,不按不显示
void jiance_key()
{
key_return1 = key();
switch(key_return1)
{
case 1: LED_level_flag =1; break;
case 2:
{
LED_level_flag =0;
buf[0]=buf[1]=buf[2]=buf[3]=buf[4]=buf[5]=buf[6]=buf[7]=10;
}break;
}
}
//二、两种一直按才执行的按键
//1. 第一种
uchar key()
{
key_press=0xff;
if(P30==0) key_press=0x77;
switch(key_state)
{
case 0:if(key_press!=0xff){ key_state =1;break; } //真的按下,还没有松开
case 1:
if(key_press!=0xff)
{
switch(key_press)
{
case 0x77: key_return =1; break;
}
key_state =2;
}
else
{
key_state =0;
break;
}
case 2:
if(key_press == 0xff)
{
key_state =0;
key_return =2;
break;
}
}
return key_return;
}
//第二种 时间超短(比赛用)
uchar key_scan()
{
keypress=0xff;
if(P30==0)keypress=0x66;
switch(keypress)
{
case 0x66:return 0;break;
case 0xff:return 1;break;
}
}
//三、长按键(按一段时间才执行)
if(P30==0)
{
delay(300); //多延长点时间就可以实现
if(P30==0)
{
R=1;
key_value=1;
}
while(!P30);
}
//****************几种按键控制模块总结****************************//
//****************串口模块总结****************************//
//一、串口发送数据
void send_data(uchar c) //发送单个字符
{
SBUF=c;
while(!TI);
TI=0;
}
void sedn_str(uchar str[],uchar len) //发送字符串
{
uchar i=0;
for(;i<len;i++)
{
send_data(str[i]);
}
}
void send_temp() //发送温度
{
sedn_str("temp:",5);
send_data('0'+temp/10);
send_data('0'+temp%10);
send_data('\r');
send_data('\n');
}
void uart_int()
{
SCON=0X50; //选择模式一
AUXR=0X00;
TMOD|=0X20;
PCON=0X80;//加这一句波特率变翻倍变为19200,没有这一句为4800
TH1=0XFD;
TL1=0XFD;
TR1=1;
}
//二、串口接收数据
void uart_int()
{
SCON=0X50;
TMOD|=0X20;
AUXR=0X00;
PCON=0X80;//¼ÓÕâÒ»¾äÖ®ºó²¨ÌØÂÊ·±¶Îª19200£¬È¥µôÖ®ºóΪ4800
TH1=0XFD;
TL1=0XFD;
TR1=1;
//加上中断就可以在中断里接收了
ES=1;
EA=1;
}
//接收数字用HEX模式,字符用文本模式
void recive_data() interrupt 4
{
if(RI)
{
RI=0;
flag=SBUF;
}
}
//****************串口模块总结****************************//
//****************ds1302写时间总结****************************//
//ds1302写时间
//DS1302写小时
void WriteHour(uchar Hour)
{
Hour %= 24;
Ds1302_Single_Byte_Write(ds1302_hr_addr,((Hour / 10) << 4) | (Hour % 10));
}
//DS1302写分钟
void WriteMinute(uchar Minute)
{
Minute %= 60;
Ds1302_Single_Byte_Write(ds1302_min_addr,((Minute / 10) << 4) | (Minute % 10));
}
//DS1302写秒
void WriteSecond(uchar Second)
{
uchar dat;
Second %= 60;
dat = (Ds1302_Single_Byte_Read(ds1302_sec_addr) & 0x80) | ((uchar)(((Second / 10) << 4) | (Second % 10)));
Ds1302_Single_Byte_Write(ds1302_sec_addr,dat);
}
//****************ds1302写时间总结****************************//
//****************频率信号输入总结****************************//
//频率信号输入
void time1() //定时模式
{
TMOD&=0X0F;
AUXR&=0XBF;
TH1=0XFC;
TL1=0X66;
ET1=1;
TR1=1;
EA=1;
}
void time0() //计数模式
{
TMOD|=0X05;
AUXR&=0X7F; //选择12分频
TH0=0x00;
TL0=0x00;
TF0=0;
TR0=1;
}
int main()
{
int_1();
time0();
time1();
while(1)
{
display1();
}
}
void time_zd() interrupt 3
{
static uint time=0;
if(++time==1000)
{
TR0=0;
time=0;
fre=TH0*256+TL0;
TH0=0;
TL0=0;
TR0=1;
}
display();
}
//****************频率信号输入总结****************************//
//****************外部中断总结****************************//
//外部中断
-----S5-INT0----
-----S4-INT1----
Void int()
{
EX0 = 1;
IT0 = 1; //边沿触发方式(下降沿)
EX1 = 1;
IT1 = 1; //边沿触发方式(下降沿)
EA = 1; //开启总中断
}
void isr_intr_0(void) interrupt 0
{
P2 = ((P2&0x1f)|0x80);
LED1 = ~LED1;
P2 = P2&0x1f;
}
void isr_intr_1(void) interrupt 2
{
P2 = ((P2&0x1f)|0x80);
LED2 = ~LED2;
P2 = P2&0x1f;
}
//****************外部中断总结****************************//
3. 蓝桥杯单片机竞赛各种必背练习模块及代码汇总
汇总文件地址: 自取
🤞🤞🤞
以上代码需根据具体代码场景调整(例如变量和函数名称),如有错误请及时提出, 创作不易,请伸出您发财的小手,打赏下博主,谢谢。
🤞🤞🤞