蓝桥杯总结以及部分程序

关于电子钟:
Ds1302:
自写->Ds1302_Single_Byte_Write(0x8e, 0x00);
    Ds1302_Single_Byte_Write(0x84, shi/10*16+shi%10);
    Ds1302_Single_Byte_Write(0x82, fen/10*16+fen%10);
    Ds1302_Single_Byte_Write(0x80, miao/10*16+miao%10);
    Ds1302_Single_Byte_Write(0x8e, 0x80);
    
    将BCD码转换成二进制:hour/16*10+hour%16
    将二进制转换成BCD码:shi/10*16+shi%10
    读取温度:
    temp=Read_temp();     //读温度
    读时间: hour=Ds1302_Single_Byte_Read(0x85);  //读时间
          min=Ds1302_Single_Byte_Read(0x83);
          sec=Ds1302_Single_Byte_Read(0x81);
          


关于风扇:
    在于加上一个单独的显示函数
    在switch-case语句中对于default的使用 , 如果是个循环,那么不用default
    在定时器中断中我们的定时时间为100us , flag == 1000 , 数据过大可能出现错误 , 
    因此在服务函数中用static静态变量防止数据出错
    Read_temp ;
    先初始化 , 写0xcc , 写0x44 , 延时200 , 初始化 , 写0xcc , 写0xbe , 读数据 , temp = TH<<4 | TL>> 4
    
关于温度记录器(Ds18b20 , ds1302, 数码管)
    写ds1302初始化函数
    将时间BCD码转换为数码管读取的数 hour/16 hour%16
    注意变量初识化!!!!!!!


关于EEPROM:
    写数据进去:
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(addr);
    IIC_WaitAck();
    IIC_SendByte(date);
    IIC_WaitAck();
    IIC_Stop();
    
    Delay10ms();
    
    读数据:
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(addr);
    IIC_Stop();
    Delay10ms();
    
    IIC_Start();
    IIC_SendByte(0xa1);
    IIC_WaitAck();
    
    date = IIC_RecByte();
    IIC_Ack(0);
    IIC_Stop();
    return date
    
    读取PCF8591的AD值:
    unsigned char ad;
    IIC_Start();
    IIC_SendByte(0x90);//PCF8951的地址
    IIC_WaitAck();
    IIC_SendByte(chanel);
    IIC_WaitAck();
    IIC_Stop();
    Delay10ms();//写地址结束后需要延时10ms?    
    IIC_Start();
    IIC_SendByte(0x91);
    IIC_WaitAck();
    ad=IIC_RecByte();
    IIC_Ack(0);
    IIC_Stop();
    return ad;
    
  
    unsigned char Read_Ds1302_Byte(void) 
{
    unsigned char i, dat=0;    
    for (i=0;i<8;i++)
    {    
        dat = dat >> 1;
        if (SDA_R)       //等价于if(SDA_R==1)    #define SDA_R SDA /*电平读取*/    
        {
            dat |= 0x80;
        }
        else 
        {
            dat &= 0x7F;
        }
        SCK_SET;
        SCK_CLR;
    }
    SDA_R=0;//!!!!!!!!添上去
    return dat;
    调试时一直无法显示分钟的值导致浪费一大堆时间:
    检查后发现原来例程中第一次调用Read_Ds1302_Byte后 , 没有将SDA_R 清零!!!!!!
}
    关于写进AT24C02中的数据:
    Write_AT24C02(0x00,set_shidu);为什么是0x00的地址?? 因为是写的第一个地址
    采用调用函数的方法看着更舒服
    
    间隔50ms 显示很舒服,哈哈哈.
    
    哈哈哈 , 终于知道怎么计算AD数模转换的值了;
    *adNum一定是0到255之间的一个数,因为pcf8591是8位的AD/DA芯片,所以输出的范围为00000000到11111111,即0到255*/
    adNum=Pcf8591ReadByte();   //读出数值
    /*将adNum转换成电压值,单片机的电压为5V,则电位器的电压为0到5V,用0到255表示0到5V,则每一个1代表5/255V,即0.01953V*/

    关于售水机:
    这次在Timer0中用了static , 出现错误.....
    
    关于小数点的处理暂时没有找到好的办法 , 只有在有小数点时候重新写一个数组...
    
    用if(!flag)还比较好用..
    关于温度监控器:
    从Ds18b20读温度
    
    uchar Get_temp(void)
    {
        uchar temp;
        Init_DS18B20();
        0xcc , 0x40 
        Init_DS18B20();0xcc , 0xbe , TL = Read_DS18B20();TH = Read_DS18B20();temp = (TH << 4) | (TL >> 4)
        注意写入顺序 , 以及高位左移4位 , 低位右移4位;
    }
    
    关于简易温度监控和控制系统(其实就是矩阵键盘而已 , 其他简单)
    
    矩阵键盘的key_scan()
    首先要给key初值 , key=15 , 具体思路是先接通一列的键盘 , 在识别行的键盘具体是哪个
    P3 = 0x7f;
    P42 = 1; // 还搞不清楚为什么需要控制P4口 / P36->P42  P37->P44 , 保证RD/WR的功能;
    P44 = 0;
    
    GPIO = P3;
    GPIO &= 0x0f;
    if (GPIO != 0x0f)
    {
        Delay10ms();
        GPIO = P3;
        GPIO &= 0x0f;
        if (GPIO != 0x0f)
        {
            GPIO=P3;//!!注意这里需要重新赋给GPIO值
            switch(GPIO)
            {
                case 0x7e:
                    key = 0;break;
                case 0x7d:
                    key = 3;break;
                case 0x7b:
                    key = 6;break;
                case 0x77:
                    key = 9;break;
                default:break;
            }
        }
        while (GPIO != 0x0f)//while的位置在第一个if后面
        {
            GPIO = P3;
            GPIO &= 0x0f;
        }
    }
    
    还有就是对于flag的逻辑 , 何时开启/关闭那个flag , 用!flag还是flag...
    C语言中,全局变量和局部静态变量是存储在静态存储区的,他们在分配的时候都被系统默认初始化为0;
    而局部自动变量是在栈上分配内存的,如果不对它们进行初始化,那么他们可能是任意的随机值。
    值得注意的是当我输入温度max<min时需要改正错误或者需要熄灭某些数码管是
    for ( i = 0; i < 8; i++)
    {
        DisplayDate[i] = 10;
    }
    关于超声波:
    先写一个SendWave();
    {Trig = 0;
    Delay20us();
    Trig = 1;
    Delay20us();}//产生方波
    然后用一个定时器1;
    uchar GetDistance(void)
{
    uint distance;
    Echo = 1;//接收端
    TR1 = 1;//开启定时器1
    SendWave();//发生方波
    while ((Echo == 1) && (TF1 == 0));//当未接受并且定时器没有溢出65536???
    TR1 = 0;
    if (TF1 == 1)
    {
        TF1 = 0;//如果溢出了表明太远了吧
        distance = 99;
        
    }
    else
    {
        distance = (TH1 << 8) | (TL >> 8);//16位的定时器,合成一个16位数据
        distance *=  0.017;//time*340m/s / 2 = distance; = 换算毫米单位
        
    }
    TH1 = TL1 = 0;恢复初始值
    
    return distance;


    各个外设端口:蜂鸣器->0x40 继电器——>0x10 Led->P0
    
    电位器RB2 chanel为3
    
    0.8秒为间隔表示亮0.8秒

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值