第十四届蓝桥杯单片机模拟赛3代码分享

 

 

我把ADC模块放在了iic.c中,数码管显示模块也单独生成了smg.c。

 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); 
unsigned char IIC_RecByte(void); 

unsigned char Read_V(void);

#endif

IIC.C

#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
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)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,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;  
}

//从I2C总线上接收数据
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;    
}

//读取RB2的电压
unsigned char Read_V(void)
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(0x03);
	IIC_WaitAck();	
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return temp;
}

SMG.H

#ifndef __SMG_H
#define __SMG_H

unsigned char code SMG_duanma[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void Delay_SMG(unsigned char t);
void SelectHC573(unsigned char channel);
void DisplaySMG_Bit(unsigned char pos,unsigned char dat);
void Display_all(unsigned char dat);

#endif

SMG.C

#include "STC15F2K60S2.H"

void Delay_SMG(unsigned char t)
{
	while(t--);
}

void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		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;
		case 0: P2 = (P2 & 0x1f) | 0x00; break;		
	}
}

void DisplaySMG_Bit(unsigned char pos,unsigned char dat)
{
	P0 = 0xff;
	SelectHC573(6);
	P0 = 0x01 << pos;
	SelectHC573(7);
	P0 = dat;
	SelectHC573(0);
}

void Display_all(unsigned char dat)
{
	SelectHC573(6);
	P0 = 0xff;
	SelectHC573(7);
	P0 = dat;
	SelectHC573(0);
}

main.c

#include "STC15F2K60S2.H"
#include "smg.h"
#include "iic.h"
#include "stdio.h"

unsigned int dat_noise;											//用于保存噪声数据
unsigned int dat_adc;												//用于保存电压数据
unsigned char para_noise = 65;						 	//用于保存噪声参数
unsigned char command_dat[6] = {0};					//用于保存串口接收到的数据
unsigned char temp[15] = {0};								//用于保存发送的字符串
unsigned char command;											//用于保存接受的字符个数
unsigned char i;														//用于给字符串赋值0
unsigned char flag_S12;											//用于判断S12是否按下
unsigned char count_led;										//用于判断L8闪烁间隔
unsigned char flag_L8;											//用于判断L8是否点亮

sbit R1 = P3^2;
sbit R2 = P3^3;
sbit C1 = P3^5;
sbit C2 = P3^4;
sbit L1 = P0^0;
sbit L8 = P0^7;
sbit L2 = P0^1;

//系统初始化函数
void Init_Sys()
{
	SelectHC573(4);
	P0 = 0xff;
	SelectHC573(5);
	P0 = 0x00;
	SelectHC573(0);
}
//电压读取和噪声转换函数
void Read_noise()
{
	dat_adc = Read_V() * 50.0 / 255 * 10;						//读取电压并进行范围转换
	if(dat_adc <= 500)
		dat_noise = (dat_adc / 5) * 9;
	else
		dat_noise = 900;
}
//噪声显示函数
void Display_noise()
{
	DisplaySMG_Bit(0,0xc1); Delay_SMG(100);
	DisplaySMG_Bit(1,SMG_duanma[1]); Delay_SMG(100);
	
	DisplaySMG_Bit(2,0xff); Delay_SMG(100);
	DisplaySMG_Bit(3,0xff); Delay_SMG(100);
	DisplaySMG_Bit(4,0xff); Delay_SMG(100);
	
	if(dat_noise > 99)
	{
		DisplaySMG_Bit(5,SMG_duanma[dat_noise / 100]); Delay_SMG(100);	
	}
	DisplaySMG_Bit(6,SMG_duanma[dat_noise / 10 % 10]&0x7f); Delay_SMG(100);
	DisplaySMG_Bit(7,SMG_duanma[dat_noise % 10]); Delay_SMG(100);
	
	Display_all(0xff);
}
//参数显示函数
void Display_para()
{
	DisplaySMG_Bit(0,0xc1); Delay_SMG(100);
	DisplaySMG_Bit(1,SMG_duanma[2]); Delay_SMG(100);
	
	DisplaySMG_Bit(2,0xff); Delay_SMG(100);
	DisplaySMG_Bit(3,0xff); Delay_SMG(100);
	DisplaySMG_Bit(4,0xff); Delay_SMG(100);
	DisplaySMG_Bit(5,0xff); Delay_SMG(100);
	
	if(para_noise > 9)
	{
		DisplaySMG_Bit(6,SMG_duanma[para_noise / 10]); Delay_SMG(100);	
	}
	DisplaySMG_Bit(7,SMG_duanma[para_noise % 10]); Delay_SMG(100);
	
	Display_all(0xff);
}
//显示总函数
void Display()
{
	if(flag_S12 == 1)
		Display_para();
	else
		Display_noise();
}
//串口相关函数
void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xC7;		//设定定时初值
	TH1 = 0xFE;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	
	ES = 1;
	EA = 1;
}
void Service_Uart() interrupt 4
{
	if(RI == 1)
	{
		command_dat[command++] = SBUF;
		RI = 0;
	}
}
void Timer0Init(void)		//10毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xF0;		//设置定时初值
	TH0 = 0xD8;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
//发送字符
void Send_Byte(unsigned char dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}
//发送字符串
void Send_Strings(unsigned char *str)
{
	while(*str != '\0')
		Send_Byte(*str++);
}
//发送数据函数
void Working()
{
	if(TF0 == 1)
	{
		TF0 = 0;
		if(command != 6)
		{
			for(i = 0; i<7;i++)
				command_dat[i] = '0';
			command = 0;
		}
		else
		{
			command_dat[command] = '\0';
			if(command_dat[0] == 'R' && command_dat[1] == 'e' && command_dat[2] == 't' && command_dat[3] == 'u' && command_dat[4] == 'r' && command_dat[5] == 'n')
			{
				sprintf(temp,"Noises:%d.%ddB\r\n",dat_noise / 10,dat_noise % 10);
				Send_Strings(temp);
				command = 0;
				for(i = 0; i<7;i++)
					command_dat[i] = '0';
			}
		}	
	}
}
//按键相关函数
void Delay_Key(unsigned char t)
{
	while(t--);
}
void Scan_Key()
{
	//S12界面切换
	R1 = R2 = 1;
	C1 = 0;C2 = 1;
	if(R2 == 0)
	{
		Delay_Key(100);	
		if(R2 == 0)
		{
			while(R2 == 0)
				Display();
			flag_S12++;
			if(flag_S12 == 2)
				flag_S12 = 0;
		}
	}
	//S16参数加5
	R1 = R2 = 1;
	C1 = 1;C2 = 0;
	if(R2 == 0)
	{
		Delay_Key(100);	
		if(R2 == 0)
		{
			while(R2 == 0)
				Display();
			if(flag_S12 == 1)
			{
				para_noise = para_noise + 5;
				if(para_noise > 90)
					para_noise = 90;			
			}
		}
	}
	//S17参数减5
	if(R1 == 0)
	{
		Delay_Key(100);	
		if(R1 == 0)
		{
			while(R1 == 0)
				Display();
			if(flag_S12 == 1)
			{
				para_noise = para_noise - 5;
				if(para_noise == -5)
					para_noise = 0;		
			}
		}
	}
}
//led工作模块
void Timer2Init(void)		//10毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xF0;		//设置定时初值
	T2H = 0xD8;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	
	IE2 |= 0x04;
	EA = 1;
}
void Uart_Timer2() interrupt 12
{
	count_led++;
	if(count_led == 10)
	{
		count_led = 0;
//		flag_L8++;
//		if(flag_L8 == 2)
//			flag_L8 = 0;
		flag_L8 = !flag_L8;
	}
}
void led()
{
	if(flag_S12 == 0)
	{
		SelectHC573(4);
		L1 = 0;
		L2 = 1;
		SelectHC573(0);
	}
	else
	{
		SelectHC573(4);
		L1 = 1;
		L2 = 0;
		SelectHC573(0);	
	}
	if(dat_noise / 10 > para_noise)
	{
		SelectHC573(4);
		if(flag_L8 == 0)
			L8 = 0;
		else
			L8 = 1;
		SelectHC573(0);			
	}
}
void main()
{
	Init_Sys();
	UartInit();
	Timer0Init();
	Timer2Init();
	while(1)
	{
		Read_noise();
		Display();
		Scan_Key();
		Working();
		led();
	}
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zz耳机

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

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

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

打赏作者

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

抵扣说明:

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

余额充值