蓝桥杯单片机刷题——通过按键触发串口传输电压值

设计要求

通过内部ADC完成电位器RB2的输出电压检测,并显示在数码管上;

通过串口向PC端返回当前检测的电压值。

按键"S4"定义为发送按键,按下按键S4,串口向PC端发送当前检测的电压值。

串口发送格式:

U:1.25V\r\n

数码管显示格式如下图所示:

电压为1.25V(数码管最高位显示标识符U)

备注

单片机IRC振荡器频率设置为12MHz。

按键模式:BTN;扩展方式:IO模式。

串口波特率:9600。

代码

sys.h

cpp 复制代码
#ifndef __SYS_H__
#define __SYS_H__

#include <STC15F2K60S2.H>
//sys.c
extern bit flag_send;
extern float Vrb2;
void init74hc138(unsigned char n);
void init();
//seg_key.c
void Key_Loop();
void Seg_Loop();
void ui();
//iic.c
float get_Vrb2();
#endif 

main.c

cpp 复制代码
#include "sys.h"
#include "stdio.h"
bit flag1=0;
bit flag2=0;
bit flag3=0;
void Timer0_Init(void)		//100微秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x9C;				//设置定时初始值
	TH0 = 0xFF;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
void UartInit(void)		//[email protected]
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;			//设置定时初始值
	TH1 = 0xFE;			//设置定时初始值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
	ES = 1;
	EA = 1;
}
char putchar(char ch){
	SBUF=ch;
	while(!TI);
	TI=0;
	return ch;
}
void main(){
	init();
	Timer0_Init();
	UartInit();
	while(1){
		if(flag1){
			flag1=0;
			Seg_Loop();
		}
		if(flag2){
			flag2=0;
			Key_Loop();
		}
		if(flag3){
			flag3=0;
			Vrb2=get_Vrb2();
			ui();
		}
		if(flag_send){
			flag_send=0;
			printf("U:%.2fV\r\n",Vrb2);
		}
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned char count1=0;
	static unsigned char count2=0;
	static unsigned int count3=0;
	count1++;count2++;count3++;
	if(count1==2){
		count1=0;
		flag1=1;
	}
	if(count2==50){
		count2=0;
		flag2=1;
	}
	if(count3==1000){
		count3=0;
		flag3=1;
	}
}
void uart() interrupt 4
{
	if(RI){
		RI=0;
	}
}

sys.c

cpp 复制代码
#include "sys.h"
bit flag_send=0;
float Vrb2;
void init74hc138(unsigned char n){
	P2=(P2&0x1f)|(n<<5);
	P2&=0x1f;
}
void init(){
	P0=0x00;
	init74hc138(5);
	P0=0xff;
	init74hc138(4);
}

seg_key.c

cpp 复制代码
#include "sys.h"
code unsigned char Seg_Table[]={
	0xc0,//0
	0xf9,//1
	0xa4,//2
	0xb0,//3
	0x99,//4
	0x92,//5
	0x82,//6
	0xf8,//7
	0x80,//8
	0x90,//9
	0xc1,//U 10
	0xff //熄灭 11
};
unsigned char Seg_Buff[8]={11,11,11,11,11,11,11,11};
unsigned char keyval,keyold,keyup,keydown;
void Key_Loop(){
	if(P33==0)keyval=4;
	keydown=keyval&(keyold^keyval);
	keyup=~keyval&(keyold^keyval);
	if(keyval==4&&keyold!=4) flag_send=1;
	keyold=keyval;
	keyval=0;
}
void seg(unsigned char addr,num){
	P0=0xff;
	init74hc138(7);
	P0=0x01<<addr;
	init74hc138(6);
	P0=Seg_Table[num];
	if(addr==5) P0&=0x7f;
	init74hc138(7);
}
void Seg_Loop(){
	static unsigned char i=0;
	seg(i,Seg_Buff[i]);
	i++;
	if(i==8) i=0;
}
void ui(){
	Seg_Buff[7]=(int)(Vrb2*100+0.5)%10;
	Seg_Buff[6]=(int)(Vrb2*10+0.05)%10;
	Seg_Buff[5]=(int)(Vrb2+0.005)%10;
	Seg_Buff[4]=11;
	Seg_Buff[3]=11;
	Seg_Buff[2]=11;
	Seg_Buff[1]=11;
	Seg_Buff[0]=10;
}

iic.c

cpp 复制代码
#include "sys.h"
#include "intrins.h"
#define DELAY_TIME	10
sbit scl=P2^0;
sbit sda=P2^1;
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}
unsigned char adc(unsigned char addr){
	unsigned char temp;
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	EA=1;
	return temp;
}
float get_Vrb2(){
	return (float)adc(3)/255*5.0;
}

测评结果

相关推荐
Ray-国20 分钟前
2025蓝桥杯JavaB组
java·职场和发展·蓝桥杯
傍晚冰川44 分钟前
【STM32点灯大师】定时器实现非阻塞式程序-按键控制LED
笔记·stm32·单片机·嵌入式硬件·学习
&Cheems1 小时前
ZYNQ笔记(七):程序固化(QSPI Flash)
单片机·嵌入式硬件
森焱森4 小时前
单片机领域中哈希表
c语言·人工智能·单片机·嵌入式硬件·算法
又熟了4 小时前
定时器介绍及简单应用
c语言·单片机·嵌入式硬件·msp430
zd8451015005 小时前
51单片机 光敏电阻5506与ADC0832驱动程序
单片机·嵌入式硬件·51单片机
渣渣灰95877 小时前
Keil创建自定义的STM32标准库工程
stm32·单片机·嵌入式硬件
路过刷题8 小时前
第16届蓝桥杯c++省赛c组个人题解
c语言·c++·蓝桥杯
nanxl19 小时前
07_Z-Stack多节点组网及终端消息上报
c语言·单片机·cc2530
星仔_X9 小时前
STM32 HAL库之USART示例代码
arm开发·stm32·单片机·嵌入式硬件