当前位置: 首页 > news >正文

做航模的网站智能自助建站系统源码

做航模的网站,智能自助建站系统源码,iis的网站登录没反应,企业seo哪些公司好前言 一、决赛题目 1.比赛题目 2.题目解读 二、功能实现 1.关于定时器资源 1#xff09;超声波和NE555需要的定时器资源 2#xff09;定时器2 2.单位切换 3.数据长度不足时#xff0c;高位熄灭 4.AD/DA多通道的处理 5.PWM输出 6.长按功能的实现 三、完整代码演…前言 一、决赛题目 1.比赛题目 2.题目解读 二、功能实现 1.关于定时器资源 1超声波和NE555需要的定时器资源 2定时器2 2.单位切换 3.数据长度不足时高位熄灭 4.AD/DA多通道的处理 5.PWM输出 6.长按功能的实现 三、完整代码演示 main.c iic.c iic.h 前言 之前一直吐槽第十四届省赛已经赶上国赛水平了现在我感觉我错了还是国赛更难一些。但是也不排除今年省赛会出前几年国赛考过的知识点这里还是多给大家分享一些。重复分享某一个知识点的话确实有些繁琐所以这里分享十三届决赛代码的同时更多的还是分享一些前边没有提到的知识点给出我的处理方法供大家参考以应对赛场上的各种突发情况。 另外今年的赛点的资料好像已经发了回头我会在比对一下跟去年的有没有区别考虑是近两年底层驱动才不给.h文件的后续我也会分享一下.h文件应该怎么写底层的.c文件应该怎么修改前边每一篇文章底层的.c 都是我自己修改过后的.h文件都是我自己写的 一、决赛题目 1.比赛题目 2.题目解读 首先可能会很让人头大的一个点就是这里不仅仅需要读取超声波还要读取NE555这两个就要各占一个定时器资源以我们之前写的代码来看定时器资源是不够的。 其次这里用到的AD和DA而AD和DA都是通过PCF8591来控制的之前从来没有遇到过同时控制两路PCF8591的情况。 再次这个题目还要求输出PWM这个对有单片机基础的人来说不是什么难事但是要是你根本不知道PWM是什么那省赛的时候你绝对难受的要死。 当然省赛的话绝对不会这么复杂但也不排除考国赛的某个知识点的可能。下边都会一一介绍 二、功能实现 1.关于定时器资源 1超声波和NE555需要的定时器资源 之前我们已经介绍过如何读取超声波和NE555了。之前写的代码都是定时器0来完成扫描数码管等其他主要的工作定时器1用来为超声波计数或者使用定时器1的外部中断来读取NE555.你如果要问用定时器1同时来为超声波计数和读取NE555可以不可以那当然不可以一个需要定时器工作在计时模式一个需要定时器工作在计数模式这样使用肯定冲突。 所以他俩每个都需要独占一个定时器资源我们需要把定时器0分给超声波用来给超声波计时定时器1的外部中断模式用于读取NE555. 那数码管还有其他计时工作怎么办呢其实STC15F2系列单片机还有一个定时器2可以使用 2定时器2 跟常规的定时器一样我们可以直接在STC-ISP生成定时器2的初始化函数。 如果你赛点的stc不是新版的没有使能定时器中断的选项那你可得提前记一下了定时器0使能中断使用的是ET01定时器1是ET1 1定时器2可不是ET2 1而是IE2 | 0x04;  定时器2的中断号是12。完整的代码如下 void Timer2_Isr(void) interrupt 12 { } void Timer2_Init(void)        //1毫秒12.000MHz {     AUXR | 0x04;            //定时器时钟1T模式     T2L 0x20;                //设置定时初始值     T2H 0xD1;                //设置定时初始值     AUXR | 0x10;            //定时器2开始计时     IE2 | 0x04;            //使能定时器2中断 }   定时器2的初始化函数跟我们常用的定时器0和1也不太一样我们也不方便使用定时器2来给超声波计时所以我一般选择定时器0给超声波计时定时器2扫描数码管了。 2.单位切换 对于这次的单位切换我选择采取简单粗暴的方式——把显示不同单位的菜单直接定义成不同的菜单比如频率界面可以按按键切换单位我直接定义两个菜单显示不同单位的频率这样切换单位就变成了切换菜单简单粗暴。不过这样的话那就得写7个菜单了不过还好菜单里面需要显示的东西并不复杂。 3.数据长度不足时高位熄灭 前几篇文章应该也提到过这里在简单介绍一下。 定义一个数据为dat如果它的长度小于3位也就是dat/1000为0时那么倒数第三位数码管就熄灭如果他的长度大于2位则正常显示dat/100%10;我们可以使用三木运算符来实现这里以显示菜单1的频率为例 if(mod0)//显示频率 {     Nixie_num[0]21,//F     Nixie_num[1]20,     Nixie_num[2]fre/1000000 ? fre/100000%10 : 20;     Nixie_num[3]fre/100000 ? fre/10000%10 : 20;     Nixie_num[4]fre/10000 ? fre/1000%10 : 20;     Nixie_num[5]fre/1000 ? fre/100%10 : 20;     Nixie_num[6]fre/100 ? fre/10%10 : 20;     Nixie_num[7]fre/10 ? fre/1%10 : 20; }   当然前提是你得知道什么是三目运算符。 4.AD/DA多通道的处理 首先为什么要处理呢 答案如果你不处理的话如果要读取两个通道的AD值那可能读取第二个通道的AD值时读取到的还是第一个通道。 当然上边只是对于多通道处理的一种情况哈总之就是第二个通道可能出现意想不到的结果。老师咋讲的现在我已经忘完了都具体读和写的哪些情况组合会出现问题我也记不清了但是我咱们可以使用一种一劳永逸的办法那就是连续读取两次比如我需要读取通道0和3那我就这样写 unsigned char AD0; unsigned char AD1; AD0read_pcf(0);AD0read_pcf(0); AD1read_pcf(1);AD1read_pcf(1); 如果它还读取不到期望的值的话那我们就在中间加几个Delay。 5.PWM输出 提到PWM就得顺带着占空比一块提一下占空比就是上文提到的duty。 PWM是一种常用的信号控制和转换技术。简单来说PWM通过调节脉冲信号的宽度来模拟一个连续变化的信号通常用于控制直流DC电动机、LED亮度调节、声音的调节以及其他需要精确控制输入信号的应用。 比如高电平电压为5V低电平电压为0V我现在定义PWM为1KHz也就是说一个周期一个高电平一个低电平时1ms如果定义精度为10%也就是十分之一个周期。如果一个周期的前50%是高电平后50%是低电平这样就记为的50%占空比。刚才又说高电平为5V低电平为0V而一个周期有一半时间是高电平那么此时输出的电压应该是高电平的一半也就是5V。对于其他占空比同理。 因此我们可以通过测量电压来测量占空比是多少。 题目要求输出1KHz的两种占空比的PWM信号分别为80%占空比和20%占空比的。 我们当然可以使用一个0.1ms的定时器定时器计数前八次输出高电平后两次输出低电平这样就可以实现80%占空比输出了20%也同理。 但是现在我们的定时器资源急缺唯一一个用来计时的定时器也设置的1ms而我又不想修改怎么办呢我们直接延时其实也可以。输出高电平延时800us输出低电平延时200us同样也输出了80%占空比1Khz的PWM信号然后我们再在main的while循环运行这串输出代码即可当然main函数里不可以有延时。 至于如何输出高电平如何输出低电平其实就跟控制继电器和蜂鸣器一样毕竟都是ULN芯片控制的前边也介绍过ULN芯片了可以看这篇文章中关于继电器开启与关闭的部分 蓝桥杯第十三届电子类单片机组程序设计-CSDN博客 只是开关继电器我们控制的事N RELAY引脚的高低电平现在我们需要控制N MOTOR引脚的高低电平而已。 输出80%和20%占空比1KHz信号的代码如下 #define MOTOR_ON()        ULN|0x20;    P0ULN;P2|0xA0;P20xBF;P20x1F; #define MOTOR_OFF()        ULN0xDF;    P0ULN;P2|0xA0;P20xBF;P20x1F; void Delay800us(void)    //12.000MHz {     unsigned char data i, j;     i 10;     j 83;     do     {         while (--j);     } while (--i); } void Delay200us(void)    //12.000MHz {     unsigned char data i, j;     i 3;     j 82;     do     {         while (--j);     } while (--i); } void PWM_out_80(void)//输出duty为80的PWM {     MOTOR_ON()     Delay800us();     MOTOR_OFF();     Delay200us(); } void PWM_out_20(void)//输出duty为20的PWM {     MOTOR_ON()     Delay200us();     MOTOR_OFF();     Delay800us(); } 6.长按功能的实现 虽然之前提到过这里还是介绍一下我个人的思路吧。 题目上要求的是长按1s那我也以长按1s为例介绍如何判断长按1s吧。 首先定义一个标志位is_1s在定时器里检查is_1s如果is_1s0则开始数数定时器每1s进一次数够1000了就让is_1s置为1如果检测到is_1s已经是1了则清零数数。注意初始状态下is_1s应为1. bit is_1s1; unsigned int count_1000ms0;//为长按按键数数 void Timer2_Isr(void) interrupt 12 {     if(is_1s0)//1s数数主要服务于长按S7 1秒     {         if(count_1000ms1000)         {             is_1s1;             count_1000ms0;         }     }     else     {         count_1000ms0;     } } 现在就需要我们利用这个is_1s来判断长按是否达到1s了。其实对于长按1s我一直有两种理解最开始的时候我理解的是长按达到1s后松开则触发效果不过现在感觉这样理解的不对应该是长按1S之后就算没松开按键也应该产生长按1s的现象了。我们在按下按键后第一个Delay5ms消抖之后加上is_1s0来开始计时在whileP300里判断is_1s的值如果is_1s为1了也就是说从上一次清零即按下按键之后到现在已经过来1s此时就判定为长按1s了处理长按1s并跳出while循环。具体代码如下 P30xFF; if(P300) {     Delay5ms();     is_1s0;//is_1s置为0的1s之后会被定时器置为1通过检查is_1s就可以判断是否长按了1S     while(P300)     {         if(is_1s1mod2)//如果检测到长按1s了并且此时处在湿度界面         {             write_at(0,0);//则重置计数             break;         }     }     is_1s1;     Delay5ms();     key_value7; }   三、完整代码演示 首先我要说明因为PWM输出需要持续修改ULN的值可能会导致数据窜位进而导致蜂鸣器和继电器条一下。之前在LED处理时就提到过应该避免重复开关控制某个外设的锁存器LED也进行了相关处理但是这个PWM没办法不得不重复开关它的锁存器。这是代码中没有解决的问题之一。 另外由于LED灯需要100ms闪烁刚才提到的PWM输出可以放在main的while循环里但是循环里不能有延时如果while循环不加延时全用定时器数数的话真的太麻烦了。所以我就把while里面的延时留下不过延时的同时输出PWM了具体可以看代码。 代码还有很多不足的地方不过内容基本实现了。 后续还是老老实实做省赛的题目吧...... main.c #include stc15.h #include intrins.h #include iic.h code unsigned char Seg_Table[] { 0xc0, //0 0xf9, //1 0xa4, //2 0xb0, //3 0x99, //4 0x92, //5 0x82, //6 0xf8, //7 0x80, //8 0x90, //9 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10, 0xFF,//熄灭 20 0x8E, //F 21 0x89,//H 22 0x88, //A 23 0x8C, //P 24 };volatile unsigned char Led_Num0xFF; volatile unsigned char ULN0x00; #define LED_ON(x) Led_Num~(0x01x);P0Led_Num;P2|0x80;P20x9F;P20x1F; #define LED_OFF(x) Led_Num|0x01x; P0Led_Num;P2|0x80;P20x9F;P20x1F; #define LED_OFF_ALL() Led_Num0xFF; P0Led_Num;P2|0x80;P20x9F;P20x1F;#define NIXIE_CHECK() P2|0xC0;P20xDF;P20x1F; #define NIXIE_ON() P2|0xE0;P20xFF;P20x1F;#define MOTOR_ON() ULN|0x20; P0ULN;P2|0xA0;P20xBF;P20x1F; #define MOTOR_OFF() ULN0xDF; P0ULN;P2|0xA0;P20xBF;P20x1F;#define RELAY_ON() ULN|0x10; P0ULN;P2|0xA0;P20xBF;P20x1F; #define RELAY_OFF() ULN0xEF; P0ULN;P2|0xA0;P20xBF;P20x1F;void get_key(void); void Delay100ms(void); //12.000MHz void Delay5ms(void); //12.000MHz void Timer0_Init(void); void Timer1_Init(void); //1毫秒12.000MHz void Timer2_Init(void); //1毫秒12.000MHz void send_wave(void); void read_remote(void); void read_ne555(void); void show_menu(void); void run(void); void PWM_out_80(void); void PWM_out_20(void); void Led_run(void); void relay_run(void);unsigned char location; unsigned char key_value0; unsigned char Nixie_num[]{20,20,20,20,20,20,20,20}; unsigned char AD0; sbit TXP1^0; sbit RXP1^1; bit is_read_remote0; bit is_read_5550; unsigned int remote0; unsigned int fre0; unsigned char mod0; unsigned char fre_canshu90;//频率参数的单位是0.1KHz unsigned char shidu_canshu40; unsigned char remote_canshu6; unsigned char shidu0; unsigned char count_relay0; bit relay_is_on0; void main() {unsigned char count_1000;//中间变量记录100个1ms循环LED_OFF_ALL();//关闭LED灯RELAY_OFF();//关闭继电器count_relayread_at(0);//读取继电器闭合次数Delay100ms();Timer0_Init();Timer1_Init();Timer2_Init();EA1;while(1){get_key();//读取按键run();while(1)//一个100ms的延时延时的同时输出PWM驱动电机{//迫不得已的做法主要LED灯闪烁哪里太需要这个100ms的延时了if(count_100100)//100ms后跳出while(1)循环下边的PWM输出一次刚好1ms{count_1000;break;}//在此延时100ms的循环内输出PWM1KHz的PWM周期刚好是1ms//注意频率参数的单位是0.1KHzif(fre/100fre_canshu)//如果频率大于频率参数的话PWM_out_80();//就输出duty为80的PWMelse if(fre/100fre_canshu)//如果频率小于频率参数的话PWM_out_20();//就输出duty为20的PWM}} } void run() {unsigned char DA0;//定义一个中间变量用于记录待输出的DA值read_remote();//超声波测距read_ne555();//读取NE555show_menu();//显示菜单Led_run();//控制LED灯运行relay_run();//控制继电器ADread_pcf(3);ADread_pcf(3);//读取电位计因为下边还要DA输出这里重复读取两次是为了防止读取不出来数据shiduAD*0.3921;//湿度值AD/255*100DA(shidu-shidu_canshu)*4/(80-shidu_canshu)1;//根据曲线拟合出的函数DADA5 ? 5 : DA;//限制输出幅值DADA1 ? 1 :DA;write_pcf(DA*51);write_pcf(DA*51);//同上连续输出两次。输出待输出电压/5*255 } bit is_1s1; unsigned int count_500ms; unsigned int count_1s0; unsigned int count_1000ms0;//为长按按键数数 void Timer2_Isr(void) interrupt 12 {P00x01location;NIXIE_CHECK();//数码管扫描P0Seg_Table[Nixie_num[location]];NIXIE_ON();if(location8)location0;if(is_read_remote0)//每500ms读取一次超声波{if(count_500ms500){is_read_remote1;count_500ms0;}}if(is_read_5550)//每过1s读取一次Ne555{if(count_1s1000){is_read_5551;count_1s0;}}if(is_1s0)//1s数数主要服务于长按S7 1秒{if(count_1000ms1000){is_1s1;count_1000ms0;}}else{count_1000ms0;} } void Timer0_Init(void) {AUXR 0x80; //定时器0为1T模式TMOD 0x04; //设置定时器0为16位自动重装载外部记数模式TH0 TL0 0x00; //设置定时器0初始值TR0 1; //定时器0开始工作//ET0 1; //开定时器0中断 } void Timer1_Init(void) //1毫秒12.000MHz {AUXR | 0x40; //定时器时钟1T模式TMOD 0x0F; //设置定时器模式TL1 0x20; //设置定时初始值TH1 0xD1; //设置定时初始值TF1 0; //清除TF1标志//TR1 1; //定时器1开始计时 } void Timer2_Init(void) //1毫秒12.000MHz {AUXR | 0x04; //定时器时钟1T模式T2L 0x20; //设置定时初始值T2H 0xD1; //设置定时初始值AUXR | 0x10; //定时器2开始计时IE2 | 0x04; //使能定时器2中断 } void Delay100ms(void) //12.000MHz {unsigned char data i, j, k;_nop_();_nop_();i 5;j 144;k 71;do{do{while (--k);} while (--j);} while (--i); }void Delay5ms(void) //12.000MHz {unsigned char data i, j;i 59;j 90;do{while (--j);} while (--i); } void get_key(void) {unsigned char key_P3P3;P30xFF;if(P300){Delay5ms();is_1s0;//is_1s置为0的1s之后会被定时器置为1通过检查is_1s就可以判断是否长按了1Swhile(P300){run();if(is_1s1mod2)//如果检测到长按1s了并且此时处在湿度界面{write_at(0,0);//则重置计数break;}}is_1s1;Delay5ms();key_value7;}else if(P310){Delay5ms();while(P310){run();}Delay5ms();key_value6;}else if(P320){Delay5ms();while(P320){run();}Delay5ms();key_value5;}else if(P330){Delay5ms();while(P330){run();}Delay5ms();key_value4;}//S4菜单切换if(key_value4){if(mod0||mod1)mod2;else if(mod2)mod3;else if(mod3||mod4)mod5;else if(mod5||mod6||mod7)mod0;}//S5在三个参数界面之间切换else if(key_value5){if(mod5)mod6;else if(mod6)mod7;else if(mod7)mod5;}//S6 在参数界面加 在距离界面切换距离单位else if(key_value6){if(mod5)fre_canshufre_canshu120 ? fre_canshu5 : 10;//限幅下同else if(mod6)shidu_canshushidu_canshu60 ? shidu_canshu10 : 10;else if(mod7)remote_canshuremote_canshu12 ? remote_canshu1 : 1;if(mod3)mod4;else if(mod4)mod3;}//S7 在参数界面减 在频率界面切换频率单位 长按功能在上边读取按键那里else if(key_value7){if(mod5)fre_canshufre_canshu10 ? fre_canshu-5 : 120;//限幅else if(mod6)shidu_canshushidu_canshu10 ? shidu_canshu-10 : 60;else if(mod7)remote_canshuremote_canshu1 ? remote_canshu-1 : 12;if(mod0)mod1;else if(mod1)mod0;}key_value0;P3key_P3; }void Delay14us(void) //12.000MHz {unsigned char data i;_nop_();_nop_();i 47;while (--i); }void send_wave(void) {unsigned char i0;for(;i8;i){TX0;Delay14us();TX1;Delay14us();} } void read_remote(void) {unsigned int url_t0;//记录超声波来回的时间注意没有单位if(is_read_remote1)//没过一段时间读取一次超声波避免连续发送读取时相互干扰{is_read_remote0;send_wave();//发送超声波TR11;//开始计时while(RX1TF10);//如果检测到返回的超声波或者定时器超时TR10;//停止计时if(RX0)//如果检测到了返回的超声波{//则记录来回的时间url_tTH1;url_t8;url_t|TL1;}else//如果超声波超时{ url_t0;}//实际的时间url_t/12000000秒//实际的距离url_t/12000000*340*100/2 厘米remote(unsigned int)(url_t*0.001417);url_t0;//为下次读取超声波清零所有数据。下同TL10;TH10;TF10;} } void read_ne555(void) {if(is_read_5551)//每隔1s读取一次NE555读出来的数据就刚好是频率{is_read_5550;TR00;freTH0;//读取频率fre8;fre|TL0;TH00;//清零相关数据TL00;TF00;TR01;} } void show_menu(void) {if(mod0)//显示频率{Nixie_num[0]21,//FNixie_num[1]20,Nixie_num[2]fre/1000000 ? fre/100000%10 : 20;Nixie_num[3]fre/100000 ? fre/10000%10 : 20;Nixie_num[4]fre/10000 ? fre/1000%10 : 20;Nixie_num[5]fre/1000 ? fre/100%10 : 20;Nixie_num[6]fre/100 ? fre/10%10 : 20;Nixie_num[7]fre/10 ? fre/1%10 : 20;}else if(mod1)//显示频率单位KHz{Nixie_num[0]21,Nixie_num[1]20,Nixie_num[2]fre/100000000 ? fre/10000000%10 : 20;Nixie_num[3]fre/10000000 ? fre/1000000%10 : 20;Nixie_num[4]fre/1000000 ? fre/100000%10 : 20;Nixie_num[5]fre/100000 ? fre/10000%10 : 20;Nixie_num[6]fre/10000 ? fre/1000%1010 : 10;//显示带小数点的数字Nixie_num[7]fre/1000 ? fre/100%10 : 0;}else if(mod2)//显示湿度{Nixie_num[0]22,Nixie_num[1]20,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]20;Nixie_num[6]shidu/100 ? shidu/10%10 : 20;Nixie_num[7]shidu/10 ? shidu/1%10 : 0;; }else if(mod3)//显示距离{Nixie_num[0]23,Nixie_num[1]20,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]remote/1000 ? remote/100%10 : 20;Nixie_num[6]remote/100 ? remote/10%10 : 20;Nixie_num[7]remote/10 ? remote/1%10 : 0; }else if(mod4)//显示距离单位m{Nixie_num[0]23,Nixie_num[1]20,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]remote/1000 ? remote/100%1010 : 10;Nixie_num[6]remote/100 ? remote/10%10 : 0;Nixie_num[7]remote/10 ? remote/1%10 : 0;}else if(mod5)//显示频率参数{Nixie_num[0]24,Nixie_num[1]1,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]fre_canshu/1000 ? fre_canshu/100%10 : 20;Nixie_num[6]fre_canshu/100 ? fre_canshu/10%1010 : 10;Nixie_num[7]fre_canshu/10 ? fre_canshu/1%10 : 0;}else if(mod6)//显示湿度参数{Nixie_num[0]24,Nixie_num[1]2,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]20;Nixie_num[6]shidu_canshu/10%10;Nixie_num[7]shidu_canshu/1%10;}else if(mod7)//显示距离参数{Nixie_num[0]24,Nixie_num[1]3,Nixie_num[2]20;Nixie_num[3]20;Nixie_num[4]20;Nixie_num[5]20;Nixie_num[6]remote_canshu/10%1010;Nixie_num[7]remote_canshu/1%10;} } void Delay800us(void) //12.000MHz {unsigned char data i, j;i 10;j 83;do{while (--j);} while (--i); } void Delay200us(void) //12.000MHz {unsigned char data i, j;i 3;j 82;do{while (--j);} while (--i); }void PWM_out_80(void)//输出duty为80的PWM {MOTOR_ON()Delay800us();MOTOR_OFF();Delay200us(); } void PWM_out_20(void)//输出duty为20的PWM {MOTOR_ON()Delay200us();MOTOR_OFF();Delay800us(); } void Led_run(void) {static bit L1_is_on0;static bit L2_is_on0;static bit L3_is_on0;static bit L4_is_on0;static bit L5_is_on0;static bit L6_is_on0;//配合主函数里的100ms延时即可达到每次运行Led_run切换一次灯的状态完成闪烁if(mod0||mod1)//在频率界面L1闪烁{if(L1_is_on0)//如果L1没有点亮则点亮{LED_ON(0);L1_is_on1;}else if(L1_is_on1)//否则熄灭。{LED_OFF(0);L1_is_on0;}}else if(mod2)//在湿度界面L2闪烁{if(L2_is_on0){LED_ON(1);L2_is_on1;}else if(L2_is_on1){LED_OFF(1);L2_is_on0;}}else if(mod3||mod4)//在距离界面L3闪烁{if(L3_is_on0){LED_ON(2);L3_is_on1;}else if(L3_is_on1){LED_OFF(2);L3_is_on0;}}//下面为退出某个模式但是刚好闪烁到LED点亮的状态则关闭不该点亮的LEDif(!(mod0||mod1)L1_is_on1)//如果不在频率界面并且L1点亮了{//则熄灭。。下边都一样LED_OFF(0);L1_is_on0;}else if(!(mod2)L2_is_on1){LED_OFF(1);L2_is_on0;}else if(!(mod3||mod4)L3_is_on1){LED_OFF(2);L3_is_on0;}//如果频率大于频率参数并且L4没有点亮if(fre/100fre_canshuL4_is_on0)//注意频率参数的单位是0.1KHz{//则点亮LED_ON(3);L4_is_on1;}else if((!(fre/100fre_canshu))L4_is_on1)//如果频率小于频率参数并且L4还没西梅{//则熄灭。。下同LED_OFF(3);L4_is_on0;}if(shidushidu_canshuL5_is_on0)//{LED_ON(4);L5_is_on1;}else if(!(shidushidu_canshu)L5_is_on1){LED_OFF(4);L5_is_on0;}if(remote/10remote_canshuL6_is_on0){LED_ON(5);L6_is_on1;}else if(!(remote/10remote_canshu)L6_is_on1){LED_OFF(5);L6_is_on0;} } void relay_run(void) {if((remote/10remote_canshu)(relay_is_on0))//如果距离大于距离参数并且继电器没有打开{//则打开继电器relay_is_on1;RELAY_ON();write_at(0,count_relay);}else if((!(remote/10remote_canshu))(relay_is_on1))//如果距离小于距离参数并且继电器打开了{//则熄灭relay_is_on0;RELAY_OFF();} } iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求进行代码调试和修改。 */ #include stc15.h #include intrins.h #include iic.h sbit sdaP2^1; sbit sclP2^0; #define DELAY_TIME 5// static void I2C_Delay(unsigned char n) {do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); }while(n--); }// void I2CStart(void) {sda 1;scl 1;I2C_Delay(DELAY_TIME);sda 0;I2C_Delay(DELAY_TIME);scl 0; }// void I2CStop(void) {sda 0;scl 1;I2C_Delay(DELAY_TIME);sda 1;I2C_Delay(DELAY_TIME); }// void I2CSendByte(unsigned char byt) {unsigned char i;for(i0; i8; i){scl 0;I2C_Delay(DELAY_TIME);if(byt 0x80){sda 1;}else{sda 0;}I2C_Delay(DELAY_TIME);scl 1;byt 1;I2C_Delay(DELAY_TIME);}scl 0; }// unsigned char I2CReceiveByte(void) {unsigned char da;unsigned char i;for(i0;i8;i){ scl 1;I2C_Delay(DELAY_TIME);da 1;if(sda) da | 0x01;scl 0;I2C_Delay(DELAY_TIME);}return da; }// unsigned char I2CWaitAck(void) {unsigned char ackbit;scl 1;I2C_Delay(DELAY_TIME);ackbit sda; scl 0;I2C_Delay(DELAY_TIME);return ackbit; }// void I2CSendAck(unsigned char ackbit) {scl 0;sda ackbit; I2C_Delay(DELAY_TIME);scl 1;I2C_Delay(DELAY_TIME);scl 0; sda 1;I2C_Delay(DELAY_TIME); }void write_pcf(unsigned char add) {I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x40);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop(); } unsigned char read_pcf(unsigned char add) {unsigned char ad0;I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0x91);I2CWaitAck();adI2CReceiveByte();I2CSendAck(1);I2CStop();return ad; } void write_at(unsigned char add,dat) {I2CStart();I2CSendByte(0xA0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop(); } unsigned char read_at(unsigned char add) {unsigned char at0;I2CStart();I2CSendByte(0xA0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xA1);I2CWaitAck();atI2CReceiveByte();I2CSendAck(1);I2CStop();return at; } iic.h #ifndef _IIC_H_ #define _IIC_H_void write_pcf(unsigned char add); unsigned char read_pcf(unsigned char add); void write_at(unsigned char add,dat); unsigned char read_at(unsigned char add);#endif
http://www.sczhlp.com/news/163694/

相关文章:

  • 做网站这么做做视频网站要多少钱
  • 网站建设策划书5000字域名格式是什么
  • 资源网站都有哪些军事网站大全军事网
  • 网站后台模版打开网站访问慢
  • 网站建设推广平台有哪些一个虚拟主机可以放几个网站
  • 印刷网站源码网站设计制作一条龙
  • pip list 可以查到某个包,但是,import某个包,出现 ModuleNotFoundError: No module named
  • 详细介绍:conda使用指南
  • 2025-10-04 60S读世界
  • 高端网站建设公司推荐山东省最新消息今天
  • 最专业的网站建设组织wordpress更换本地主题
  • 微山县建设.局网站邯郸吧
  • 个人性质网站能做论坛吗学校微网站模板下载
  • 做网站空间不给账号密码西安免费建网站制作
  • 代码命名 网站icp备案添加网站
  • 营销型网站案例制作微信网页的网站吗
  • 用多说的网站网站规划的案例
  • 网站安全建设方案例文建设网站哪些好
  • 有域名后续怎么做网站长沙网站运营外包公司
  • 广州科 外贸网站建设网页截图快捷键设置
  • 平面设计案例网站wordpress表单收集
  • 做网站的作用快速seo优化
  • 江苏seo技术教程东莞市网络seo推广企业
  • 淮安住房与城乡建设部网站网站建设是什么
  • 个体工商户备案网站备案哈尔滨专业网站制作公司
  • 酒店 手机网站模板购卡链接网站怎么做
  • 移动网站专业装修超市的装修公司
  • 常州网站推搜狗关键词排名此会zjkwlgs
  • 广州seo网站排名优化什么关键词可以搜到那种
  • 宁波网站建设官网免费推广网站大全