蓝桥杯单片机刷题——E2PROM记录开机次数

设计要求

使用E2PROM完成数据记录功能,单片机复位次数记录到E2PROM的地址0中。每复位一次数值加1,按下按键S4,串口发送复位次数。串口发送格式如下:

Number:1

备注:

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

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

串口通信波特率设置为 9600。

代码:

sys.h

cpp 复制代码
#ifndef __SYS_H__
#define __SYS_H__

#include <STC15F2K60S2.H>
#include "intrins.h"
sbit scl=P2^0;
sbit sda=P2^1;
extern bit flag_send;//用于标明是否发送数据
extern bit flag_set;//用于标明是否重置数据(非题意)
void init74hc138(unsigned char n);
void init();
void w_eeprom(unsigned char addr,unsigned char date);
unsigned char r_eeprom(unsigned char addr);
void Key_Loop();

#endif

main.c

cpp 复制代码
#include "sys.h"
unsigned char eeprom_count=0;//EEPROM中的计数值
unsigned char *str = "Number: ";
bit flag_key=0;
void UartInit(void)		//9600bps@12.000MHz
{
	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;
}
//发送一个字节数据到串口
void send_uart_date(unsigned char date){
	SBUF=date;
	while(TI==0);
	TI=0;
}
//发送字符串到串口
void send_uart_str(unsigned char *str){
	while(*str!='\0'){
		send_uart_date(*str++);
	}
}
//将数字转换为字符串
void num_transt_str(unsigned char num){
	if(num>=100)send_uart_date(num/100+'0');
	if(num>=10)send_uart_date((num%100)/10+'0');
	send_uart_date(num%10+'0');
}
void Timer0_Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x50;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA=1;
}
void main(){
	init();
	eeprom_count=r_eeprom(0x00);
	eeprom_count++;
	w_eeprom(0x00,eeprom_count);
	UartInit();
	Timer0_Init();
	while(1){
		if(flag_key){
			flag_key=0;
			Key_Loop();
		}
		if(flag_send){
			flag_send=0;
			send_uart_str(str);//发送Number:
			num_transt_str(eeprom_count);//发送计数器数值
			send_uart_str("\r\n");//换行
		}
		if(flag_set){//重置
			flag_set=0;
			eeprom_count=0;
			w_eeprom(0x00,eeprom_count);
		}
	}
}
void uart() interrupt 4
{
	if(RI){
		RI=0;
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned char count=0;
	count++;
	if(count==50){
		count=0;
		flag_key=1;
	}
}

sys.c

cpp 复制代码
#include "sys.h"
unsigned char keyval,keyold,keydown,keyup;
bit flag_send=0;
bit flag_set=0;
void init74hc138(unsigned char n){
	P2=(P2&0x1f)|(n<<5);
	P2&=0x1f;
}
void init(){
	P0=0x00;
	init74hc138(5);
	P0=0xff;
	init74hc138(4);
}
void Key_Loop(){
	keyval=0;
	if(P33==0)keyval=1;
	if(P32==0)keyval=2;
	keydown=keyval&(keyold^keyval);
	keyup=~keyval&(keyold^keyval);
	if(keyval==1&&keyold!=keyval)flag_send=1;
	if(keyval==2&&keyold!=keyval)flag_set=1;
	keyold=keyval;
}

iic.c

cpp 复制代码
#include "sys.h"

#define DELAY_TIME	5
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);
}
//向EEPROM中写入一个字节数据
void w_eeprom(unsigned char addr,unsigned char date){
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(date);
	I2CWaitAck();
	I2CStop();
}
//从EEPROM中读取一个字节数据
unsigned char r_eeprom(unsigned char addr){
	unsigned char temp;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	temp=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return temp;
}

测试结果

相关推荐
来自晴朗的明天1 小时前
13、NMOS 电源防反接电路
单片机·嵌入式硬件·硬件工程
芯岭技术2 小时前
PY32MD310单片机:高性能、低功耗的32位电机控制微控制器
单片机·嵌入式硬件
_OP_CHEN3 小时前
【算法基础篇】(五十六)容斥原理指南:从集合计数到算法实战,解决组合数学的 “重叠难题”!
算法·蓝桥杯·c/c++·组合数学·容斥原理·算法竞赛·acm/icpc
小龙报3 小时前
【51单片机】深度解析 51 串口 UART:原理、配置、收发实现与工程化应用全总结
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·51单片机
Lester_110110 小时前
STM32 高级定时器PWM互补输出模式--如果没有死区,突然关闭PWM有产生瞬间导通的可能吗
stm32·单片机·嵌入式硬件·嵌入式软件
小李独爱秋12 小时前
“bootmgr is compressed”错误:根源、笔记本与台式机差异化解决方案深度指南
运维·stm32·单片机·嵌入式硬件·文件系统·电脑故障
进击的小头14 小时前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
宵时待雨18 小时前
STM32笔记归纳8:时钟
笔记·stm32·单片机·嵌入式硬件
JJRainbow19 小时前
SN75176 芯片设计RS-232 转 RS-485 通信模块设计原理图
stm32·单片机·嵌入式硬件·fpga开发·硬件工程
宁静致远202119 小时前
STM32模拟IIC读取PCF8563
stm32·单片机·嵌入式硬件