蓝桥杯单片机:13届省赛模拟

该程序实现了一个微控制器系统,包括系统初始化、定时器配置和中断处理。主要功能有:读取ADC数据、显示频率和电压、按键控制页面切换、LED状态控制。定时器0用于微秒级计数,定时器1和2分别用于毫秒级计数和数据刷新。此外,程序还包含一个简单的按键扫描函数,用于检测用户输入并更新显示内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

main.c

#include "mycode.h"
unsigned short int Timer1_count=0,Timer2_count=0,Timer0_count=0;//timer0计数
unsigned short int Timer_count=0;
unsigned char key_value=0;//key键值获取
unsigned char LED_status=1;//LED灯指示灯功能开启
unsigned short int  Save_hz=0;//保存的hz
unsigned short int 	Save_ad=0;//保存的电压值
void main()
{
	Systeam_Init();//系统初始化
	Timer0Init();
	Timer1Init();
	EA = 1;
	while(1)
	{
		
	if(ad_flag==1)
	{dat1=(int)Read_AD(chanl)/51.0*100;ad_flag=0;}
	
			key_value=Key_scan();
			switch(key_value)
			{
				case SW_4_press:page_flag++;if(page_flag>=4) page_flag=1;break;
				case SW_5_press:if(chanl==1) chanl=3;else chanl=1;break;
				case SW_6_press:Save_ad=dat1;break;
				case SW_7_press:Save_hz=Hz;break;
			}	key_value=0;
			
			if(LED_status==1)//LED灯指示灯功能开启
			{
				switch(page_flag)
				{
					case 1:LATCH(4,0xfb);break;
					case 2:LATCH(4,0xf7);break;
					case 3:LATCH(4,0xef);break;
				}
				if(chanl==3)
				if(Save_ad<dat1) {P2=(P2&0x1F|(4<<5));LED1=0;}
				
				if(Save_hz<Hz) {P2=(P2&0x1F|(4<<5));LED2=0;}
			}
			if(LED_status==0)//LED灯指示灯功能关闭
			{
				LATCH(4,0xff);//LED灯全关			
			}
			
	}
}

void Timer0() interrupt 1
{
	Timer0_count++;
}
void Timer1_1() interrupt 3
{
	
	Timer1_count++;
	if(Timer1_count>=20)//刷新数码管
	{
		Timer1_count=0;
	}
	
	
	Timer2_count++;
	if(Timer2_count%250==0)
		ad_flag=1;
	if(Timer2_count>=500)//1ms频率  500ms刷新一次
	{
		Timer2_count=0;
		Hz=Timer0_count*2;
		Timer0_count=0;
	}
	
	if(LED_flag==1)
	{
		Timer_count++;
		if(Timer_count>=1000)
		{
			LED_status=!LED_status;
			
		}
	}
}

mycode.c

#include "mycode.h"
unsigned char code smg_d[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
///.. 11  F
0x7f,0xff,0x8e,0xc8,0xc1,0xbf
};
bit ad_flag=0;
unsigned int Hz=0;//频率数据
unsigned int Us=0;//周期数据
unsigned char chanl=1;
unsigned char page_flag=1;//页面标志
bit LED_flag=0;
	unsigned int dat1=0;//电压值
void Smg_show(void)
{
		switch(page_flag)
		{
			case 1:page_1();break;
			case 2:page_2();break;
			case 3:page_3();break;
		}
}
void page_1(void)
{
	unsigned char len=0;
	unsigned int  t;
	display(0,12);//显示F
	t=Hz;
	while(t)
	{	t/=10;	len++;}//计算数据长度
	while(len)
	{
		display(8-len,Hz%((int)pow(10,len))/((int)pow(10,len-1)));
		len--;
	}
	if(Hz==0) display(7,0);

	LATCH(COM,0xFF);
	LATCH(SEG,0xFF);
}

void page_2(void)
{
	unsigned char len=0;
	unsigned int  t;
	display(0,13);//显示N
	Us=100000/Hz;
	t=Us;
	while(t)
	{	t/=10;	len++;}//计算数据长度
	while(len)
	{
		display(8-len,Us%((int)pow(10,len))/((int)pow(10,len-1)));
		len--;
	}
	if(Us==0) display(7,0);
	
	LATCH(COM,0xFF);
	LATCH(SEG,0xFF);
}

void page_3(void)
{
	display(0,14);//显示N
	display(1,15);//显示_
	display(2,chanl);//显示通道
	
	display(5,dat1/100);
	display(5,10);//显示小数点
	display(6,dat1%100/10);
	display(7,dat1%10);
	
	LATCH(COM,0xFF);
	LATCH(SEG,0xFF);
}


void display(unsigned char c,unsigned char dat)
{
	LATCH(SEG,0xff);
	LATCH(COM,1<<c);
	LATCH(SEG,smg_d[dat]);
	delay_ms(1);
}

unsigned char Key_scan(void)
{
	unsigned char key_v=0;
	if(!SW_4)
	{
		delay_ms(10);
		if(!SW_4)
		{
			while(!SW_4) Smg_show();
			return SW_4_press;
		}
	}
	if(!SW_5)
	{
		delay_ms(10);
		if(!SW_5)
		{
			while(!SW_5) Smg_show();
			return SW_5_press;
		}
	}
	if(!SW_6)
	{
		delay_ms(10);
		if(!SW_6)
		{
			while(!SW_6) Smg_show();
			return SW_6_press;
		}
	}
	if(!SW_7)
	{
		delay_ms(10);
		if(!SW_7)
		{
			while(!SW_7) {Smg_show();LED_flag=1;}
			Timer_count=0;
			LED_flag=0;
			return SW_7_press;
		}
	}
	Smg_show();
	return 0;
}

void Timer0Init(void)		//1微秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x04;		
	TL0 = 0xFF;		//设置定时初始值
	TH0 = 0xFF;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
}


void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初始值
	TH1 = 0xD1;		//设置定时初始值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
}



void Systeam_Init(void)
{

	LATCH(4,0xff);//LED灯全关
	LATCH(5,0x00);//ULN2003 关闭
	
	LATCH(0,0x00);
}









void delay_us(unsigned int t)		//@12.000MHz
{
	while(t--){
	_nop_();
	_nop_();
	_nop_();
	_nop_();}
}

void delay_ms(unsigned int t)		//@12.000MHz
{
	unsigned char i, j;
	while(t--){
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);}
}



mycode.h

#ifndef __MYCODE_H__
#define __MYCODE_H__
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#include <string.h>
#include <math.h>
#include "iic.h"

sfr AUXR = 0x8e;
#define COM			6
#define SEG			7
#define LATCH(x,y) {P2=(P2&0x1F|(x<<5)); P0=y;}
sbit SW_4=P3^3;
sbit SW_5=P3^2;
sbit SW_6=P3^1;
sbit SW_7=P3^0;
sbit LED1=P0^0;
sbit LED2=P0^1;
extern bit LED_flag;
extern bit ad_flag;
extern unsigned short int Timer_count;
extern 	unsigned int dat1;//电压值
#define SW_4_press  1
#define SW_5_press  2
#define SW_6_press  3
#define SW_7_press  4
extern unsigned int Hz;//频率数据
extern unsigned int Us;//周期数据
extern unsigned char page_flag;//页面标志
extern unsigned char chanl;//采集通道

void page_1(void);
void page_2(void);
void page_3(void);
unsigned char Key_scan(void);
void display(unsigned char c,unsigned char dat);
void delay_us(unsigned int t);		//@12.000MHz
void delay_ms(unsigned int t);		//@12.000MHz
void Systeam_Init(void);
void Timer0Init(void);		//1毫秒@12.000MHz
void Timer1Init(void)	;
void Smg_show(void);
#endif


iic.c

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
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;  					
    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;    
}

unsigned char Read_AD(unsigned char chanl)
{
	unsigned char dat;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(chanl);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return dat;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

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

sbit SDA = P2^1;
sbit SCL = P2^0;

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_AD(unsigned char chanl);
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值