常用需记忆处 蜂鸣器
P2 = 0xa0;
//选通触发器
buzzer = 0;
//蜂鸣器不叫//sbit buzzer = P0^6;
P2 = 0x00 //不选通触发器
流水灯
P2 = 0x80;
//使能Y4C
P0 = ~(0x01<
蜂鸣器、继电器
P2 = 0xa0;
P0 = 0x40;
//开蜂鸣器 //P0 = 0x00;
//关蜂鸣器
P2 = 0x00;
P2 = 0xa0;
P0 = 0x10;
//开蜂鸣器 //P0 = 0x00;
//关蜂鸣器
P2 = 0x00;
【蓝桥杯国赛备赛】继电器和蜂鸣器最好一起操作,一个好的解决方法如下:设置连个人标志位,然后根据flag不同情况,写出四个函数放在while1的最后面
//bit buzzer_flag=0,relay_flag=0;
//定义好变量
if(buzzer_flag==1 && relay_flag==1)
{
P2 = 0xa0;
P0 = 0x10;
P2 = 0x00;
//
P2 = 0xa0;
buzzer = 1;
P2 = 0x00;
}
if(buzzer_flag==0 && relay_flag==0)
{
P2 = 0xa0;
P0 = 0x00;
P2 = 0x00;
//
P2 = 0xa0;
buzzer = 0;
P2 = 0x00;
}
if(buzzer_flag==1 && relay_flag==0)
{
P2 = 0xa0;
P0 = 0x00;
P2 = 0x00;
//
P2 = 0xa0;
buzzer = 1;
P2 = 0x00;
}
if(buzzer_flag==0 && relay_flag==1)
{
P2 = 0xa0;
P0 = 0x10;
P2 = 0x00;
//
P2 = 0xa0;
buzzer = 0;
P2 = 0x00;
}
独立按键
/*
* 独立按键驱动函数
*/
unsigned char read_control_key(void)
{
unsigned char return_key_val=0;
unsigned char key_press;
static char key_state = key_state_0;
//错过这里,未定义成静态变量
key_press = P3&0x0f;
switch(key_state)
{
case key_state_0:
{
if(key_press != 0x0f) //错过这里,错写0xff,误当为矩阵键盘
{
key_state = key_state_1;
}
}
break;
case key_state_1:
{
if(key_press != 0x0f)//错过这里,错写0xff,误当为矩阵键盘
{
if(key_press == 0x0e)return_key_val = 7;
//S7
if(key_press == 0x0d)return_key_val = 6;
//S6
if(key_press == 0x0b)return_key_val = 5;
//S5
if(key_press == 0x07)return_key_val = 4;
//S4
key_state = key_state_2;
}
else
key_state = key_state_0;
}
break;
case key_state_2:
{
if(key_press == 0x0f)//错过这里,错写0xff,误当为矩阵键盘
{
key_state = key_state_0;
}
}
break;
}
return return_key_val;
}
矩阵键盘 P4.2替代P3.6
P4.4替代P3.7
程序结构 1、定时器0:1ms中断一次
2、状态机消抖矩阵键盘函数
3、按键10ms中断
4、数码管3ms中断
#include "STC15F2K60S2.h"//不用再包含reg51.h
#defineu8 unsigned charu8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
//0-9
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
#define KEY P3
#define NO_KEY0xff//无按键按下
#define KEY_STATE00//判断按键按下
#define KEY_STATE11//确认按键按下
#define KEY_STATE22//释放
unsigned char Key_Scan()
{
static unsigned char key_state=KEY_STATE0;
u8 key_value=https://www.it610.com/article/0,key_temp;
u8 key1,key2;
P30=0;
P31=0;
P32=0;
P33=0;
P34=1;
P35=1;
P42=1;
P44=1;
if(P44==0) key1=0x70;
if(P42==0) key1=0xb0;
if(P35==0) key1=0xd0;
if(P34==0) key1=0xe0;
if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1)) key1=0xf0;
//没有按键
P30=1;
P31=1;
P32=1;
P33=1;
P34=0;
P35=0;
P42=0;
P44=0;
if(P30==0) key2=0x0e;
if(P31==0) key2=0x0d;
if(P32==0) key2=0x0b;
if(P33==0) key2=0x07;
if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1)) key2=0x0f;
key_temp=key1|key2;
switch(key_state)
{
case KEY_STATE0:
if(key_temp!=NO_KEY)
{
key_state=KEY_STATE1;
//第一次确定有按键按下时后,给key_state赋值进入下一检查阶段
}
break;
case KEY_STATE1:
if(key_temp==NO_KEY)
{
key_state=KEY_STATE0;
//第二次检测没按下
}
else
{
switch(key_temp)
{
case 0x77: key_value=4;
break;
case 0x7b: key_value=5;
break;
case 0x7d: key_value=6;
break;
case 0x7e: key_value=7;
break;
case 0xb7: key_value=8;
break;
case 0xbb: key_value=9;
break;
case 0xbd: key_value=10;
break;
case 0xbe: key_value=11;
break;
case 0xd7: key_value=12;
break;
case 0xdb: key_value=13;
break;
case 0xdd: key_value=14;
break;
case 0xde: key_value=15;
break;
case 0xe7: key_value=16;
break;
case 0xeb: key_value=17;
break;
case 0xed: key_value=18;
break;
case 0xee: key_value=19;
break;
}
key_state=KEY_STATE2;
}
break;
case KEY_STATE2:
if(key_temp==NO_KEY)
{
key_state=KEY_STATE0;
}
break;
}
return key_value;
}void Timer_Init(void) //1ms
{
AUXR |= 0x80;
//1T timer
TMOD &= 0xF0;
// 16bit
TL0 = 0xCD;
TH0 = 0xD4;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA=1;
}bit key_flag;
void main(void)
{
u8 key_val=NO_KEY;
//检测的按键值
P2=0xa0;
P0=0x00;
P2=0x00;
// close buzzer and relay
Timer_Init();
//1ms
while(1)
{
if(key_flag)//10ms,每进一次中断key_flag加一,1ms中断进10次就是10ms
{
key_flag=0;
key_val=Key_Scan();
switch(key_val)
{
case 4:break;
case 5:break;
case 6:break;
case 7:break;
case 8:break;
case 9:break;
case 10: break;
case 11: break;
case 12: break;
case 13: break;
case 14: break;
case 15: break;
case 16: break;
case 17: break;
case 18: break;
case 19: break;
}
}
}
}void timer0() interrupt 1using 1
{
static int key_count=0,smg_count=0,i=0;
key_count++;
smg_count++;
if(key_count==10)//10ms
{
key_count=0;
key_flag=1;
}
if(smg_count==3)//3ms
{
smg_count=0;
P2=0xc0;
P0=0;
P2=0;
//消影
P2=0xe0;
P0=~smg_du[i];
P2=0;
P2=0xc0;
P0=smg_wei[i];
P2=0;
i++;
if(i==8) i=0;
}
}
经验 //数码管显示小数,例如显示8.,直接在显示之前让这个东西|0x80
//u8 float小数的位数
//u8范围是0~255,9999应该定义成unsigned int型
//ADC读取和发送时最好关闭中断,例如不关的话小灯会频繁的乱闪烁
ADC转化是除255,注意类型转换,humidity=(u8)(read_adc(0x03)/2.57f);
set_sfm(8,30,57); //在定时器初始化之前写,怕中断打扰
shi=Ds1302_Single_Byte_Read(0x85); //DS1302读取的是BCD,所以要除以16
1、u8 mode模式选择让变量为0,按下case7后让mode++;
if(mode==2)mode=0;
让0和1切换
2、蜂鸣器和继电器需要一起操作,不然会受影响。假如要在一个情形下一个程序操作蜂鸣器,一个操作继电器,则最好定义relay_flag和buzzer_flag(1开0关)。写四个类似if(relay_flag==1 && buzzer_flag==1){}在while最后面
3、定义的显示界面数组是不用条件判断,直接在while循环里赋值就行,需要判断的中断函数里的显示数组选哪个。
4、数组不变的部分可以定义在while外
看省赛“程序思路对比”
关于仿真 因为按键会设计P30和P31所以会影响到仿真,只要把用了P30和P31的函数关掉就好了,就是注释掉key_temp=Read_Key(); 这一句即可
IIC 24c02讲解的很详细:
http://www.cnblogs.com/whik/p/6650092.html
关于以前读ad值出现的问题及分析 现象:
省赛时读Ad值时使用0x03控制,读AIN3通道三时只会出0/64/128或者旋转电位器数值不变,而改变成0x43时候就可以正常显示了
分析:
文章图片
区别在bit2,自动增量使能位,如果自动增量(auto-increment)标志置1,每次A/D 转换后通道号将自动增加,原因就是没有修改IIC驱动里的延时时间,官方驱动适合12T单片机,而比赛板是1T,故延时函数应该改为原来的12倍才行,但现在没变,即速度太快,auto-increment置1后自动切换通道,4个通道为一组,看起来速度就慢了一些,勉强符合时序要求,于是显示成功
ad转换 #define fun(x) (int)(5x/255.0100+0.5) //数字电压x转换为模拟电压的公式
加0.5是可以让四舍五入,因为C里会舍弃小数部分
推荐阅读
- python蓝桥杯|python蓝桥杯基础练习 十六进制转八进制
- 刷题记录|【蓝桥必胜】试题 算法训练 kAc给糖果你吃-贪心排序
- Python|蓝桥杯 平面切割 Python
- Python|Python 每日一练 二分查找 搜索旋转排序数组 详解
- 遇见蓝桥遇见你|小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题
- 遇见蓝桥遇见你|小唐开始刷蓝桥(三)2018年第九届C/C++ B组蓝桥杯省赛真题
- C语言单链表的创建,修改,插入等
- 蓝桥信用卡号验证 JAVA纯暴力破解
- Java基础|信用卡校验
- 算法训练 一元三次方程求解 蓝桥杯