蓝桥杯单片机代码精要

  • 138译码器 ,led控制

led低电平点亮0xff全部关闭,0x00打开全部

void InitHC138(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;break;
	}
		P2 = (P2 & 0x1f) | 0x00;
}
//系统初始化,先给数值,后选位
void Init_System()
{
 	P0 = 0xff;
	Init_74HC138(4);
	P0 = 0x00;
	Init_74HC138(5);
	SMG_All(0xff);
}
  • 数码管动态显示

原理图y6c选位置,y7设置值

p0=0x00;po<<=1;  0000变为0010

p0=0x00;po<<=1; p0|=1;变为0011

void DisPlaysmg_Bit(unsigned char value,unsigned char pos) 
{
P0=0x01<<pos;
InitHC138(6);选择位置
P0=value;或者P0=~value;共阳变共阴
InitHC138(7); 选择值
}
void dongtai()
{显示值,每个值延时500
DisPlaysmg_Bit(SMG_duanma[2],0);
Delay(500);
DisPlaysmg_Bit(SMG_duanma[0],1);
Delay(500);
}
延迟中若要显示则必须用到该函数:
void Delayzhuyong(unsigned int t)
{
     while(t--)  
    { 
         dongtai();
     }
}

  • 蜂鸣器继电器

蜂鸣器和继电器由Y5控制12。控制时,先选择Y5,然后编写P0即可控制,0为关,1为开

蜂鸣器和继电器由Y5控制12。控制时,先选择Y5,然后编写P0即可控制,0为关,1为开

void OutPutP0(unsigned char channel, unsigned char dat)
{
	InitHC138(channel);
	P0 = dat;
}
OutPutP0(5,0x10);开启
OutPutP0(5,0x00);关闭
  • 独立按键

if(S7 == 0)
	{
	Delay(100);按键防抖,如按键时候需要显示则数码管显示操作
	}

矩阵键盘

选某行=0,列为1,其他行为1;

当检测到某列为0,判断为值,例如1行1列等于0,则为1,例如:

sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C4 = P3^4;
sbit C3 = P3^5;
sbit C2 = P4^2;
sbit C1 = P4^4;
键盘扫描函数:
R1 = 0;
	R2 = R3 = R4 = 1;
	C1 = C2 = C3 = C4 =1;
	if(C1 == 0)
	{
		while(C1 == 0)//注意显示问题;
		key_num = 0;
		DisplayKeyNum(SMG_duanma[key_num]);
	}

外部中断

手册查6.5,6.6,7.1,7.2相关寄存器:触发引脚:into为p32,int1为p33

void Init_INT0()
{
	IT0 = 1;
	EX0 = 1;			//若为0;低电平触发,即按下持续期间触发
	EA = 1;
}
void ServiceINT0() interrupt 0
{
	stat_int = 1;
}
当stat_int = 1;时候执行操作
  • 定时器中断

开启stc-isp,系统频率12,定时器0,16位自动重载,12t

开启stc-isp,系统频率12,定时器0,16位自动重载,12t,8位为0-225,16位为65535,自动重载意味着不用再中断函数输入th0,tl0。

然后后面加入:ET0 = 1; EA=1;

void Timer_Init(void)
{
	AUXR |= 0x80;	
	TMOD &= 0xF0;
	TL0 = 0xCD;		
	TH0 = 0xD4;		
	TF0 = 0;		
	TR0 = 1;		
	ET0 = 1;手动添加
	EA=1; 
}
//中断服务函数
void timer0() interrupt 1  
{
//1ms进一次中断。
}

利用PWM控制灯光亮度:定时器定时10ms,代表频率,50%亮度意味着前5ms灯亮,后5ms灯灭。

void ServiceTimer0() interrupt 1
{
//	TH0 = (65535 - 100) / 256;
//	TL0 = (65535 - 100) % 256;
//	若未开重载
	count++;
	if(count == pwm_duty)
	{
		L1 = 1;灯关
	}
	else if(count == 100)
	{
		L1 = 0;开
		count = 0;
	}

温度传感器

不记得记得看赛点手册,初始化,忽略rom,启动温度转换,等待转换完成

void Read_Dsiplay_DS18B20()
{
  unsigned char LSB,MSB;      
  unsigned int temp = 0;      
  init_ds18b20();              //初始化DS18B20
  Write_DS18B20(0xcc);        //忽略ROM操作
  Write_DS18B20(0x44);        //启动温度转换
  DisplaySMG_Temp();
  init_ds18b20();              //初始化DS18B20
  Write_DS18B20(0xcc);        //忽略ROM操作
  Write_DS18B20(0xbe);        //读出内部存储器
  LSB = Read_DS18B20();        //第0字节:温度低8位
  MSB = Read_DS18B20();        //第1字节:温度高8位
  init_ds18b20();              //初始化,停止读取
  temp = MSB;                  //合成16位温度原始数据
  temp = (temp << 8) | LSB;
  temp_ds18b20 = temp * 0.0625;  //计算实际温度值
  smg_ds18b20 = temp_ds18b20 * 10;
  DisplaySMG_Temp();
}

DS18B20的单总线底层驱动代码:若提供的是52的,需要将时序*10,但要注意到底需要不需要进行修改

  • 实时时钟

时钟写
void write_Ds1302()
{
unsigned char i=0;
unsigned char adr=0x80;
Write_Ds1302(0x8e,0x00);允许时钟写开
for(i=0;i<7;i++)
	{
	Write_Ds1302(adr,read_time[i]);
	adr+=2;
	}
Write_Ds1302(0x8e,0x80);关
}
时钟读
void read_tem()
{
unsigned char i=0;
unsigned char t,date1;
unsigned char adr=0x81;

for(i=0;i<7;i++)
	{
	t=Read_Ds1302(adr);
	date1=t/16;
	date1=date1*10;
	read_time[i]=date1+t%16;
	adr+=2;
	}
}
  • iic

  • PCF8591(光敏电阻,可调电阻,ad(0x0),da转换)

PCF8591读操作地址为:0x91;而写操作地址则为:0x90

ad模拟转数字转换流程:

      1-发送写设备地址,选择IIC总线上的PCF8591器件。
      2--发送控制字节,选择模拟量输入模式和通道。
      3--发送读设备地址,选择IIC总线上的PCF8591器件。
      4--读取PCF8591中目标通道的数据。

ad转换,实际上是读取电阻中的值

void Read_AIN3()
{
	IIC_Start();		//IIC总线起始信号							
	IIC_SendByte(0x90); 	//PCF8591的写设备地址		
	IIC_WaitAck();  	//等待从机应答		
	IIC_SendByte(0x03); 	//写入PCF8591的控制字节		
// IIC_SendByte(0x01); //通道1,光敏电阻电压
	IIC_WaitAck();  	//等待从机应答						
	IIC_Stop(); 		//IIC总线停止信号					
	
	IIC_Start();		//IIC总线起始信号									
	IIC_SendByte(0x91); 	//PCF8591的读设备地址		
	IIC_WaitAck(); 		//等待从机应答		
	dat = IIC_RecByte();	//读取PCF8591通道3的数据 			
	IIC_Ack(0); 		//产生非应答信号				
	IIC_Stop(); 		//IIC总线停止信号					
}

光明电阻在ani1引脚,可调电阻在ani3引脚

设置dac可调电阻输出为:则第六位为1,第0,1位为11

{
	IIC_Start();					
	IIC_SendByte(0x90);		//PCF8591的写设备地址 
	IIC_WaitAck();	
	IIC_SendByte(0x43); 	//输出DAC,转换AIN3	
	IIC_WaitAck(); 								
	IIC_SendByte(dat); 		//设置DAC电压输出参数
	IIC_WaitAck(); 			//产生非应答信号 								
	IIC_Stop();
}
  • 存储器24c02

24C02的设备的读操作地址为:0xA1;而写操作地址则为:0xA0。

4C02的字节写操作,参考代码:
void Write_24C02(unsigned char addr, unsigned char dat)
{
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa0); 	//24C02的写设备地址
	IIC_WaitAck();		//等待从机应答	
	IIC_SendByte(addr); 	//内存字节字节
	IIC_WaitAck(); 		//等待从机应答	
	IIC_SendByte(dat); 	//写入目标数据
	IIC_WaitAck();		//等待从机应答	
	IIC_Stop();		//IIC总线停止信号		
}
24C02的字节读操作,参考代码:
unsigned char Read_24C02(unsigned char addr)
{
	unsigned char tmp;
	//进行一个伪写操作
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa0); 	//24C02写设备地址
	IIC_WaitAck();		//等待从机应答	
	IIC_SendByte(addr); 	//内存自己地址
	IIC_WaitAck(); 		//等待从机应答	
	//进行字节读操作
	IIC_Start();		//IIC总线起始信号					
	IIC_SendByte(0xa1); 	//24C02读设备地址
	IIC_WaitAck();		//等待从机应答	
	tmp = IIC_RecByte();	//读取目标数据
	IIC_Ack(0); 		//产生非应答信号		
	IIC_Stop();		//IIC总线停止信号			
	return tmp;
}

55频率技术

实际上将t0当作计数器,t1当作定时器。计算每秒内脉冲的数量

例如

void Init_Timer()
{
	//定时器0用作计数,8位重装
	TH0 = 0XFF;
	TL0 = 0XFF;
	//定时器1用作定时,定时时间50ms
	TH1 = (65535 - 50000 + 1) / 256;
	TL1 = (65535 - 50000 + 1) % 256;
	TMOD = 0X16;//0001 0110
	ET0 = 1;
	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
}

void Service_T0() interrupt 1
{
	count_f++;
}

void Service_T1() interrupt 3
{
	TH1 = (65535 - 50000 + 1) / 256;
	TL1 = (65535 - 50000 + 1) % 256;
	
	count_t++;
	if(count_t == 20)
	{
		dat_f = count_f;
		count_f = 0;
		count_t = 0;
	}
}

上述代码统计每秒内脉定时器中断数量

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值