12届蓝桥杯单片机省赛(第一场代码)

该代码主要展示了使用STC15F2K60S2单片机通过IIC协议与DS18B20温度传感器交互,以及控制LED、步进电机、继电器等硬件模块的C语言实现。同时,还包括了单总线通信函数和延时函数,用于读取和显示温度数据。
摘要由CSDN通过智能技术生成

main.c

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "iic.h"
#include "onewire.h"
/********************宏定义区域**************/
#define ui unsigned int
#define uc unsigned char
#define Y0   0
#define Y4     4
#define Y5     5
#define Y6      6
#define Y7     7

#define ON     1 
#define OFF     0

#define LED_ON  0
#define LED_OFF 1
#define LED1 1
#define LED2 2
#define LED3 3
#define LED4 4
#define LED5 5
#define LED6 6
#define LED7 7
#define LED8 8

sbit H1=P3^0;
sbit H2=P3^1;
sbit H3=P3^2;
sbit H4=P3^3;
sbit L1=P3^4;
sbit L2=P3^5;
sbit L3=P4^2;
sbit L4=P4^4;

ui temp;
uc temp1,temp2;    
uc adc_sz;
uc jm;
uc zt=0;
uc wd_kz;
uc code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9,-,关闭,C
uc code tac[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uc code tad[]={0xc6,0x8e,0x8C,0xC1,0x86,0xbf,0x88}; //C,F,P,U,E,-
uc  tae;
/****************控制 步进电机,继电器,直流电机,蜂鸣器*********************/
typedef union{
    uc Other_Data; //8位数据,控制 步进电机,继电器,直流电机,蜂鸣器
    struct
    {                          
        uc com:4;      
        uc com_R:1;
        uc com_M:1;
        uc com_B:1;
        uc com_S:1;
    }stOther;
}_TD5COM;
static xdata _TD5COM  s_data;

/***********************************LED的共用体*******************************/
typedef union{
    uc byLED_Data; //8位数据,表示LED灯的数据    byLED_Data = 0x03
    struct
    {                          
        uc bLED1:1;       // 0000 0011       stLED.bL1 = 1      stLED.bL2 = 1
        uc bLED2:1;
        uc bLED3:1;
        uc bLED4:1;
        uc bLED5:1;
        uc bLED6:1;
        uc bLED7:1;
        uc bLED8:1;
    }stLED;
}_unLEDType;
static xdata _unLEDType s_unLED_data;
/************************************延时函数区********************************/
void Delay1ms()        //@12.000MHz
{
    unsigned char i, j;

    i = 12;
    j = 169;
    do
    {
        while (--j);
    } while (--i);
}

//延时Nms
void  DelayNms(ui _Nms)
{
    ui i = 0;

    for(i = 0;i < _Nms;i++)
    {
       Delay1ms();
    }
}
void hc138(ui n)//138锁存器打开
{
    switch(n)
    {
    case 0:P2=P2&0X1F;break;
    case 4:P2=P2&0X1F|0x80;break;
    case 5:P2=P2&0X1F|0xA0;break;
       case 6:P2=P2&0X1F|0xC0;break;
    case 7:P2=P2&0X1F|0xE0;break;
    }
}
/*************************LED灯独立控制函数*****************/
void LED_contr(uc led_x)
{
  hc138(Y4);
  P0=led_x;
}
void LEDx_Contr(uc _LEDx,uc _on_off)
{
    switch(_LEDx)
    {
        case LED1:s_unLED_data.stLED.bLED1 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED2:s_unLED_data.stLED.bLED2 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED3:s_unLED_data.stLED.bLED3 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED4:s_unLED_data.stLED.bLED4 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED5:s_unLED_data.stLED.bLED5 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED6:s_unLED_data.stLED.bLED6 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED7:s_unLED_data.stLED.bLED7 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
        case LED8:s_unLED_data.stLED.bLED8 = (_on_off == LED_ON)? LED_ON:LED_OFF; break;
    }
    LED_contr(s_unLED_data.byLED_Data);
}
/****************各个模块的控制********************/
void Other_Contr(uc Other_x)
{
    hc138(Y5);
    P0=Other_x;

}
void Buzzer_ON_OFF(uc _no_off)
{
    s_data.stOther.com_B = _no_off;    //_no_off = 1 开  0 关
    Other_Contr(s_data.Other_Data);
}
void Relay_ON_OFF(uc _no_off)
{
    s_data.stOther.com_R = _no_off;    //_no_off = 1 开  0 关
    Other_Contr(s_data.Other_Data);
}
/*************************数码管显示函数***********************/
void OutputP2(uc add,uc dat)//输出函数
{
  hc138(add);
  P0=dat;
}
void OutputSMG(uc g,uc y)
{
  OutputP2(6,0x01<<g);
  OutputP2(7,y);
  DelayNms(2);
}
/********************************按键状态读取**********************************/
void keycan()
{
 H4=0;
 H2=H1=H3=1;
 L1=L2=L3=L4=1;
 if(L3==0&&jm==2)
 {Delay1ms();wd_kz--;while(L3==0); }//s8
 H4=0;
 H1=H3=H2=1;
 L1=L2=L3=L4=1;
 if(L4==0)
 {Delay1ms();jm++;if(jm>2){jm=0;}while(L4==0);}//s4
 H3=0;
 H1=H2=H4=1;
 L1=L2=L3=L4=1;
 if(L4==0)
 {Delay1ms();zt++;if(zt>1){zt=0;}while(L4==0);}//s5
 H3=0;
 H2=H1=H4=1;
 L1=L2=L3=L4=1;
 if(L3==0&&jm==2)
 {Delay1ms(); wd_kz++;while(L3==0);}//s16
}
/******************************温度数码管显示函数******************************/
void smg_xs_wd(void)
{
    temp=rd_temperature();
    temp2=temp&0x000f;
    temp1=temp>>4;
    OutputSMG(0,tad[0]);
    OutputSMG(4,tab[temp1/10]);
    OutputSMG(5,tac[temp1%10]);
    OutputSMG(6,tab[temp2/10]);
    OutputSMG(7,tab[temp2%10]);
}
/******************************温度数码管显示函数******************************/
void smg_xs_wd1()
{
    temp1=25;
    temp1=temp1+wd_kz;
    OutputSMG(0,tad[2]);
    OutputSMG(6,tab[temp1/10]);
    OutputSMG(7,tab[temp1%10]);
    tae=temp1;
}
/******************************数码管显示函数******************************/
void SMG_AD()//数码管功能
{
   uc com;
    OutputSMG(0,tad[6]);
    temp=rd_temperature();
    temp1=temp>>4;
    if(20<temp1<40 )
    {com=temp1*15-200;}
    if(temp1>40 )
    {com=500;}
    if(temp1<=20 )
    {com=100;}
    adc_sz=com/1.96+1;
    IIC_Write(adc_sz);
    OutputSMG(5,tac[com/100]);
    OutputSMG(6,tab[com/10%10]);
    OutputSMG(7,tab[com%10]);     
}
/******************************数码管显示函数******************************/
void SMG_AD1()//数码管功能
{
    ui com;
    uc wd_cs;
    wd_cs=tae;
    OutputSMG(0,tad[6]);
    temp=rd_temperature();
    temp1=temp>>4;
    if(temp1>wd_cs )
    {com=498;}
    if(wd_cs>=temp1 )
    {com=0;}
    adc_sz=com/1.96+1;
    IIC_Write(adc_sz);
    OutputSMG(5,tac[com/100]);
    OutputSMG(6,tab[com/10%10]);
    OutputSMG(7,tab[com%10]);     
}
void led_xs()
{
  if(zt==0)
  {LEDx_Contr(LED1,LED_ON);}
   else
  {LEDx_Contr(LED1,LED_OFF);}
  if(jm==0)
  {LEDx_Contr(LED2,LED_ON);}
   else
  {LEDx_Contr(LED2,LED_OFF);}
  if(jm==1)
  {LEDx_Contr(LED3,LED_ON);}
   else
  {LEDx_Contr(LED3,LED_OFF);}    
  if(jm==2)
  {LEDx_Contr(LED4,LED_ON);}
   else
  {LEDx_Contr(LED4,LED_OFF);}

}
/*********************************初始函数**************************/
void csh_system()
  {
    
       LED_contr(0xff);//LED灯全关闭
    Buzzer_ON_OFF(OFF);//关闭蜂鸣器
    Relay_ON_OFF(OFF);//关闭继电器
    s_data.Other_Data = 0;//关闭所有设备
}
void ad_ms()
{
   switch(zt)
   {
    case 0:SMG_AD1(); break;
    case 1:SMG_AD();  break;
   }
}
/*************************界面切换函数***********************************/
void jm_xs()
{
   switch(jm)
   {
    case 0:smg_xs_wd(); break;
    case 1: smg_xs_wd1(); break;
    case 2:ad_ms();break;
   }
}

void main()
{
csh_system();
rd_temperature();
DelayNms(750);
while(1)
{
keycan();
led_xs();
  jm_xs();
}
}

ds1bb20.c

#include "STC15F2K60S2.H"
#include "onewire.h"

sbit DQ = P1^4;

单总线延时函数
void Delay_OneWire(unsigned int t)  
{
    unsigned char i;
    while(t--){
        for(i=0;i<12;i++);
    }
}

void Delay_us(void)
{
    unsigned char i;

    i = 30;
    while (--i);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        DQ = dat&0x01;
        Delay_OneWire(5);
        DQ = 1;
        dat >>= 1;
    }
    Delay_OneWire(5);

}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
    unsigned char i;
    unsigned char dat;
//    unsigned char index = 0;
             
    for(i=0;i<8;i++)
    {
        DQ = 0;
        dat >>= 1;
        DQ = 1; 
           Delay_us();

        if(DQ)  
        {
            dat |= 0x80;
        }        
        Delay_OneWire(5);
    }
    return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
      bit initflag = 0;
      
      DQ = 1;
      Delay_OneWire(12);
      DQ = 0;

      Delay_OneWire(80); // 延时大于480us
      DQ = 1;
      Delay_OneWire(10);  // 14
      initflag = DQ;     // initflag等于1初始化失败
      Delay_OneWire(5);
  
      return initflag;
}

//缺失自己写
//DS18B20温度采集程序:整数
unsigned int rd_temperature()
{
//   unsigned int temp;
   unsigned char L,H;
   init_ds18b20();
   Write_DS18B20(0xcc);//跳过ROM指令
   Write_DS18B20(0x44);//转换温度指令
   Delay_OneWire(80); // 延时大于480us
   init_ds18b20();
   Write_DS18B20(0xcc);//跳过ROM指令
   Write_DS18B20(0xbe);//读温度指令

   L = Read_DS18B20();
   H = Read_DS18B20();
//   temp = H<<4;
//   temp|=(L>>4);

   return (H<<8)+L;
}

iic.c

/*#include "iic.h"

//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    somenop;
    SDA = 0;
    somenop;
    SCL = 0;    
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    somenop;
    SDA = 1;
}

//应答位控制
void IIC_Ack(unsigned char ackbit)
{
    if(ackbit) 
    {    
        SDA = 0;
    }
    else 
    {
        SDA = 1;
    }
    somenop;
    SCL = 1;
    somenop;
    SCL = 0;
    SDA = 1; 
    somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
    SDA = 1;
    somenop;
    SCL = 1;
    somenop;
    if(SDA)    
    {   
        SCL = 0;
        IIC_Stop();
        return 0;
    }
    else  
    { 
        SCL = 0;
        return 1;
    }
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {   
        if(byt&0x80) 
        {    
            SDA = 1;
        }
        else 
        {
            SDA = 0;
        }
        somenop;
        SCL = 1;
        byt <<= 1;
        somenop;
        SCL = 0;
    }
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char da;
    unsigned char i;
    
    for(i=0;i<8;i++)
    {   
        SCL = 1;
        somenop;
        da <<= 1;
        if(SDA) 
        da |= 0x01;
        SCL = 0;
        somenop;
    }
    return da;
}*/
/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include "STC15F2K60S2.H"
#include "intrins.h"
#include <iic.h>

#define DELAY_TIME 5 //somenop函数用延时代替

//#define SlaveAddrW 0xA0
//#define SlaveAddrR 0xA1ATc02的读写地址

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)//延时函数
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;    
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    if(ackbit)         // 0:应答,1:非应答
    {SDA = 0;}    
    else     
    {SDA = 1;}
 IIC_Delay(DELAY_TIME);
    SCL = 1;
 IIC_Delay(DELAY_TIME);
    SCL = 0;
    SDA = 1; 
 IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
    
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}
//(写入函数代码)
void IIC_Write(unsigned char dat)
{
     IIC_Start();
    IIC_SendByte(0x90);
    IIC_WaitAck();
    IIC_SendByte(0x43);
    IIC_WaitAck();
    IIC_SendByte(dat);
    IIC_WaitAck();
    IIC_Stop(); 
}
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
        SCL = 1;
    IIC_Delay(DELAY_TIME);
    da <<= 1;
    if(SDA) da |= 1;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    }
    return da;    
}

//读取函数代码
unsigned char IIC_Read(unsigned char add)
{
    unsigned char temp;
    IIC_Start(); //启动
    IIC_SendByte(0x90);//调用PCF8591,并且为写操作
    IIC_WaitAck();//等待
    IIC_SendByte(add); //add的值决定通道0x01是光敏电阻,0x30是滑动变阻器
    IIC_WaitAck();//等待

    IIC_Stop();//停止

    IIC_Start();//再次启动
    IIC_SendByte(0x91);     //调用PCF8591,并且为读操作
    IIC_WaitAck();//等待

    temp=IIC_RecByte();//把读取出的数据给temp
    IIC_Stop();//停止

    return temp;//返回temp

}

ds18b20.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H


//函数声明 全部声明
void Delay_OneWire();
void Delay_us();
void Write_DS18B20();
unsigned char Read_DS18B20();
bit init_ds18b20();
unsigned int rd_temperature();
 
#endif

iic.h

#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
void IIC_Write(unsigned char dat);
unsigned char IIC_RecByte(void); 
unsigned char IIC_Read(unsigned char dat);
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐诗宋詞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值