蓝桥杯流转呼吸灯

#include "STC15F2K60S2.h"
#include <math.H>

#define uchar unsigned char
#define uint unsigned int

 uchar LED1[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //模式1
 uchar LED2[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //模式2
 uchar LED3[4]={0x7e,0xbd,0xdb,0xe7}; //模式3
 uchar LED4[4]={0xe7,0xdb,0xbd,0x7e}; //模式4
 uchar LED;
 bit pwmFlag =  0; 
 uint pwm_t = 0;
 uint gap;

 uchar num;
 uchar led_mode;
 uchar cylc;
 uint pwm_duty = 0;   //cycle(周期)-pwm_duty==高电平时间,
                      //Pwm_duty越大,高电平时间越少,低电平时间越长led越亮
void Timer0Init(void) //1毫秒@12.000MHz T0 12T 
{
	AUXR &= 0x7F;		
	TMOD &= 0xF0;		
	TL0 = 0x18;		
	TH0 = 0xFC;		
	TF0 = 0;		
	TR0 = 1;		
	EA = 1; ET0=1;
}

void  setled()
{
	switch(led_mode)
			{
			case 1:if(num>=8)num=0;LED=LED1[num];break;//led1
			case 2:if(num>=8)num=0;LED=LED2[num];break;//led2
			case 3:if(num>=4)num=0;LED=LED3[num];break;//led3
			case 4:if(num>=4)num=0;LED=LED4[num];break;//led4
			}
	
}
void ServiceTimer0() interrupt 1
{

	  pwm_t++;
   if(pwm_t<=cylc)
	  {
		 if(pwm_t<=pwm_duty)//低电平---pwm_duty(高电平),led亮,led熄灭  
                           // 通过pwm_duty调节来改变亮度
          setled();        //点亮led
          else             //pwm_duty(高电平)---100,led熄灭  
		  LED=0xff;
	  }

  else
   {			 
      pwm_t=0;		 //(0-100)周期结束重新定时

		if(pwm_duty==cylc)      //100-pwm_duty==高电平时间,低电平为100,完全点亮
		    pwmFlag=1;         //开始渐灭标志位

		if(pwm_duty==0)         //100-pwm_duty==高电平时间,低电平为0,完全熄灭
		{ pwmFlag=0; num++;  } //开始渐亮标志位,下一个led灯
		
		if(pwmFlag==0)
			pwm_duty++;         //cylc-pwm_duty==高电平时间,高电平减少,低电平增加,渐亮

		else if(pwmFlag==1)
			pwm_duty--;         //cylc-pwm_duty==高电平时间,高电平增加,低电平减少,渐灭
	 }
}

void main()
{
	Timer0Init();
    led_mode=2;    //流转模式
	gap=1000;      //流转间隔ms
    cylc=sqrt(gap/2); // 流转间隔ms(gap)=2(改变标志位时间)*周期(亮)*周期(灭)
                     // cylc= sqrt(gap/2)            
                   	//数学太菜。公式可能不太准欢迎大神指导
	while(1)
	{	
		P2=0x80;
		P0 = LED;
	}
}

### 单片机蓝桥杯比赛中流转间隔的增加实现方法 在单片机开发中,通过修改底层驱动代码可以调整设备的行为逻辑。对于蓝桥杯比赛中的具体需求——将流转间隔保存并通过 IIC 接口传输数据[^1],以下是详细的实现方式。 #### 修改 IIC 驱动以支持自定义功能 为了满足题目要求,可以通过扩展现有的 IIC 底层驱动来完成操作。通常情况下,IIC 的读写函数已经封装好,开发者只需调用这些接口即可完成通信。然而,如果需要额外的功能(如存储流转间隔并延迟执行),则需进一步定制化: 1. **设置变量用于存储流转间隔时间** 定义全局变量或局部静态变量以保存当前计算得到的时间差值。 ```c static uint16_t flow_interval; // 存储流转间隔时间 (单位: ms) ``` 2. **更新加减运算后的结果至该变量** 当程序运行完加法和减法之后,立即将所得的结果赋给 `flow_interval` 变量。 3. **利用定时器模块引入固定延时** 使用硬件定时器或者软件循环等待的方式实现精确的 5ms 延迟效果。这里推荐采用 HAL 或者标准外设库提供的 API 函数简化编程复杂度。 ```c void delay_ms(uint16_t time){ __HAL_TIM_SET_COUNTER(&htimX,0); // 清零计数寄存器 while(__HAL_TIM_GET_COUNTER(&htimX)<time*SystemCoreClock/1000); } ``` 4. **编写新的 IIC 发送子程序** 创建专门负责发送上述参数值的新版 IIC 写入过程,确保每次都能成功传递最新版本的数据包内容出去。 #### 结合实际案例分析 根据往届赛事经验分享可知,在处理类似任务时往往还需要考虑其他方面因素的影响,比如电源电压波动可能引起通讯错误等问题[^2]。因此建议采取如下措施加以防范: - 加强信号线屏蔽防护; - 合理配置上拉电阻大小范围; - 对异常情况进行妥善捕获与恢复机制设计; 最终形成一套稳定可靠的解决方案应用于竞赛环境当中去实践验证其有效性。 ```c // 示例:完整的流程控制框架结构 void main(){ init_hardware(); // 初始化所有必要的硬件资源 while(1){ calculate_flow_diff(); // 执行核心算法获取最新的流量变化数值 save_to_variable(flow_interval); // 将结果暂存在指定位置备用 send_via_iic(flow_interval);// 经由串行总线向外广播共享此信息 delay_ms(5); // 主动加入短暂休眠周期减少功耗消耗 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值