蓝桥杯第十届省赛单片机(电压频率测量)感悟及易错点

1.易错点!!!

这个是最最最重要的,我在编写电压显示的代码时,发现它只能显示出几个固定的值,如0.44,2.00等,去找了adc转换电压源代码没有发现错误,最后意外发现错误是定义变量类型的问题:

unsigned char adc_value = 0;
float adc_volt = 0;
unsigned int smg_volt = 0;
unsigned char dat1 = 0;

以上是正确的代码,我开始写的都是unsigned char,这样会给电压读取造成错误,导致读不出正确的电压,大家一定要注意了!!

2.上期的补充

上期就是第八届省赛电子钟,我调温度转换的代码时也发现类似的问题,但最后我发现问题出现在头文件的延时函数中,因为蓝桥杯单片机的时钟和51单片机的时钟不同相差约12倍,所以延时的时候也要乘上大概十倍,才能读出正确的温度哈

3.关于PCF8591测量电压的代码如下:

void Read_PCF8591_AIN3()
{
    IIC_start();
    IIC_SendByte(0x90); 
    IIC_WaitAck();
    IIC_SendByte(0x43);
    IIC_WaitAck();
    IIC_Stop(); //等待电压转换
    Display_voltage();
    
    IIC_Start();                  
    IIC_SendByte(0x91);
    IIC_WaitAck();                 
    adc_value = IIC_RecByte(); //读取adc转换的值
    IIC_SendAck(1);                   
    IIC_Stop();

    adc_volt = adc_value * (5.0 / 255);
    smg_volt = adc_volt * 100;
}
void Set_PCF8591_DAC(unsigned char dat)
{
  IIC_Start();          
  IIC_SendByte(0x90);    
  IIC_WaitAck();  
  IIC_SendByte(0x43);   
  IIC_WaitAck();                 
  IIC_SendByte(dat);     
  IIC_WaitAck();                          
  IIC_Stop();
}

以下是这两个代码联合使用的示例:
 

if(S5 == 0)
	{
		Delay(2000);
		if(S5 == 0)
		{
			while(S5 == 0);
			if(stat2 == 0)
			{
			

					Read_PCF8591_AIN3();
					Set_PCF8591_DAC(adc_value);
					Display_voltage();	
							
					if((adc_volt>=1.5&&adc_volt<2.5)|adc_volt>=3.5)
					{
							LEDrunning(2);
					}
					else
					{
							LEDstop(2);
					}
        						
					stat2 = 1;
				
        
			}
			else
			{
	      Set_PCF8591_DAC(102);
        smg_volt = 200;
        Display_voltage();				//µçѹΪ¹Ì¶¨Öµ
				stat2 = 0;
			}
		}
	}

4.这个题目中最重要的是NE555芯片的使用,就是测量频率,其实NE555内部电路已经固定,考察的并不是它的编程部分,而是利用定时器/计数器来测量信号的频率!

注:做这个之前一定要将跳线帽接在NAL和P34两端哦!
定时器1设置为8为重装模式的计数器,定时器0为16为计时器

void Init_timer()
{
    TH1 = 0xff;
    TL1 = 0xff;
    
    TH0 =(65535-50000)/256;
    TL0 =(65535-50000)%256;
    TMOD = 0x16;
    ET1 = 1;
    ET0 = 1;
    EA = 1;
    TR0 = 1;
    TR1 = 1;
}

定时器0中断函数

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

定时器1中断函数

当count_t = 20时 到达一秒 将一秒内获得的脉冲个数count_f放到dat_f中

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

本期就到这里啦,下一期我可能会更新客观题哦,希望大家都来多多支持我,你们的支持是我学习的最大动力!

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值