蓝桥杯单片机模板底层代码总结

感谢风哥,让我能拿到30多名成绩(^_-)


代码具体讲解可以看b站up西风和左岚的视频,我在这里只是大概总结一下

这里有个链接是基于目前文章的模版编写的模块集合并运用

蓝桥杯单片机设计与开发所有模块集合并运用icon-default.png?t=N7T8https://gitee.com/MaritimeShip/IAP15_Learn_Code/tree/master/2-1%20%E6%A8%A1%E5%9D%97%E5%AD%A6%E4%B9%A0/%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%8D%95%E7%89%87%E6%9C%BA%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%BC%80%E5%8F%91%E6%89%80%E6%9C%89%E6%A8%A1%E5%9D%97%E9%9B%86%E5%90%88%E5%B9%B6%E8%BF%90%E7%94%A8


总概

第一    模板底层是比赛的基础

第二    代码逻辑是比赛拿奖的关键

第三    低频考点 ≠ 不考(超声波,串口)

           毕竟比赛的时候会不会考到谁都说不准

第四    考试时不要因为一个小的模块就丢失了整体代码的逻辑

          led没写出来也不要影响到数码管按键等模块的代码

备注:因为15届官方新出的赛点资源包有改变,所以我也修改了文章内容

           如有错误还请指出,不胜感激!

还需要注意这个引脚鼠标左键点一下就会出来具体信息


一、基础底层模板

1.1 main.c 主函数模板

现在主函数优先使用定时器1

因为这样就不用管什么题,直接无脑定时器1就行了

/* 头文件声明区 */
#include <STC15F2K60S2.H>
#include "Init.h"
#include "Key.h"
#include "Seg.h"
#include "LED.h"

/* 基础变量创建区 */
unsigned int Slow_Down;                                                 //减速扫描专用
bit Key_Slow_Flag, Seg_Slow_Flag, LED_Slow_Flag, Infor_Slow_Flag;       //按键数码管LED信息处理减速标志位
unsigned char Seg_Buf[8] = {10, 10, 10, 10, 10, 10, 10, 10};            //数码管显示缓冲区
unsigned char Seg_Point[8] = {0, 0, 0, 0, 0, 0, 0, 0};                  //数码管小数点显示缓冲区
unsigned char LED_Buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};                    //LED显示缓冲区
unsigned char i;                                                        //循环专用变量

/* 变量创建区 */


/* 按键处理函数 */
void Key_Deal()
{
    static unsigned char Key_New = 0, Key_Old = 0;    //按键获取
    static unsigned char Key_UP = 0, Key_Down = 0;    //专用变量
    
    if (Key_Slow_Flag) return;                //减速
    Key_Slow_Flag = 1;
    
    Key_New = Key_Read();                        //获取键码
    Key_UP = ~Key_New & (Key_New ^ Key_Old);     //捕获上升沿
    Key_Down = Key_New & (Key_New ^ Key_Old);    //捕获下降沿
    Key_Old = Key_New;                           //辅助扫描
    
    switch (Key_Down)
    {
        case 4:
           
        break;
    }
}

/* 数码管处理函数 */
void Seg_Deal()
{
    if (Seg_Slow_Flag) return;
    Seg_Slow_Flag = 1;
    
}

/* LED处理函数 */
void LED_Deal()
{
    if (LED_Slow_Flag) return;        //LED减速,可以不要,但题目如果出现流水灯之类的
    LED_Slow_Flag = 1;                //大家灵活应变,把减速去掉
    
}

/* 信息处理函数 */
void Infor_Deal()
{
    /* 信息输出区 */


    /* 减速 */
    if (Infor_Slow_Flag) return;
    Infor_Slow_Flag = 1;
    
    /* 信息处理区 */
    
}

/* 定时器初始化函数 */
void Timer1_Init(void)      //1毫秒@12.000MHz
{
    AUXR &= 0xBF;       //定时器时钟12T模式
    TMOD &= 0x0F;       //设置定时器模式
    TL1 = 0x18;         //设置定时初值
    TH1 = 0xFC;         //设置定时初值
    TF1 = 0;            //清除TF1标志
    TR1 = 1;            //定时器1开始计时
    EA  = 1;
    ET1 = 1;
}

/* 中断服务函数 */
void Timer1_Serve() interrupt 3
{
    if (++Slow_Down == 400) Slow_Down = Infor_Slow_Flag = 0;
    if (Slow_Down % 10 == 0) Key_Slow_Flag = 0;
    if (Slow_Down % 20 == 0) LED_Slow_Flag = 0;
    if (Slow_Down % 100 == 0) Seg_Slow_Flag = 0;
    Seg_Show(Slow_Down%8, Seg_Buf[Slow_Down%8], Seg_Point[Slow_Down%8]);
    LED_Show(Slow_Down%8, LED_Buf[Slow_Down%8]);
    
}

/* 主函数 */
void main()
{
    System_Init();
    Timer1_Init();
    
    while (1)
    {
        Infor_Deal();
        Key_Deal();
        Seg_Deal();
        LED_Deal();
    }
}

1.2 Init.c   系统底层

#include <STC15F2K60S2.H>
#include "Init.h"


void System_Init()
{
    P0 = 0x00;              //关闭蜂鸣器等
    P2 = P2 & 0x1f | 0xa0;
    P2 &= 0x1f;
    
    P0 = 0xff;              //关闭蜂鸣器等
    P2 = P2 & 0x1f | 0x80;
    P2 &= 0x1f;
}




1.3 Key.c   按键底层

#include <STC15F2K60S2.H>
#include "Key.h"

/* 矩阵按键KBD */
unsigned char Key_Read()
{
    unsigned char temp = 0;
    ET0 = 0;
    P34 = 0; P35 = 1; P42 = 1; P44 = 1;
    if (P30 == 0) temp = 19;
    if (P31 == 0) temp = 18;
    if (P32 == 0) temp = 17;
    if (P33 == 0) temp = 16;
    P34 = 1; P35 = 0; P42 = 1; P44 = 1;
    if (P30 == 0) temp = 15;
    if (P31 == 0) temp = 14;
    if (P32 == 0) temp = 13;
    if (P33 == 0) temp = 12;
    P34 = 1; P35 = 1; P42 = 0; P44 = 1;
    if (P30 == 0) temp = 11;
    if (P31 == 0) temp = 10;
    if (P32 == 0) temp = 9;
    if (P33 == 0) temp = 8;
    P34 = 1; P35 = 1; P42 = 1; P44 = 0;
    if (P30 == 0) temp = 7;
    if (P31 == 0) temp = 6;
    if (P32 == 0) temp = 5;
    if (P33 == 0) temp = 4;
    P3 = 0xff;
    ET0 = 1;
    return temp;
}

/* 独立按键BTN */
/*
unsigned char Key_Read()
{
    unsigned char temp = 0;
    if (P30 == 0) temp = 7;
    if (P31 == 0) temp = 6;
    if (P32 == 0) temp = 5;
    if (P33 == 0) temp = 4;
    return temp;
}
*/

1.4 Seg.c  数码管底层

#include <STC15F2K60S2.H>
#include "Seg.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
    0xff, //熄灭
    0xbf, //-
    0x88, //A
    0x83, //b
    0xc6, //C
    0xa1, //d
    0x86, //E
    0x8e  //F
};

void Seg_Show(unsigned char addr, Table, Point)
{
    P0 = 0xff;                  //消影
    P2 = P2 & 0x1f | 0xe0;
    P2 &= 0x1f;
    
    P0 = 0x01 << addr;          //位选
    P2 = P2 & 0x1f | 0xc0;
    P2 &= 0x1f;
    
    P0 = Seg_Table[Table];      //段选
    if (Point)
        P0 &= 0x7f;             //小数点
    P2 = P2 & 0x1f | 0xe0;
    P2 &= 0x1f;
}

1.5 LED.c  LED底层

注意LED不要和蜂鸣器继电器共用变量

#include <STC15F2K60S2.H>
#include "LED.h"

/* LED显示函数 */
void LED_Show(unsigned char addr, enable)
{
    static unsigned char temp_new_LED = 0x00;
    static unsigned char temp_old_LED = 0xFF;
    
    if (enable)
        temp_new_LED |= 0x01 << addr;
    else
        temp_new_LED &= ~(0x01 << addr);
    
    if (temp_new_LED != temp_old_LED)
    {
        P0 = ~temp_new_LED;
        P2 = P2 & 0x1f | 0x80;
        P2 &= 0x1f;
        temp_old_LED = temp_new_LED;
    }
}


/* 蜂鸣器继电器专用 */
unsigned char temp_new = 0x00;
unsigned char temp_old = 0xFF;

//  0-关闭   1-开启
/* 蜂鸣器控制函数 */   
void Beep(unsigned char flag)
{
    if (flag)
        temp_new |= 0x40;
    else
        temp_new &= ~(0x40);
    
    if (temp_new != temp_old)
    {
        P0 = temp_new;
        P2 = P2 & 0x1f | 0xa0;
        P2 &= 0x1f;
        temp_old = temp_new;
    }
}
/* 继电器控制函数 */
void Relay(unsigned char flag)
{
    if (flag)
        temp_new |= 0x10;
    else
        temp_new &= ~(0x10);
    
    if (temp_new != temp_old)
    {
        P0 = temp_new;
        P2 = P2 & 0x1f | 0xa0;
        P2 &= 0x1f;
        temp_old = temp_new;
    }
}

二、模块内容

2.0 模块总概

我这里只有我们需要自己编写的函数

在15届的底层驱动代码的有点改变但是不多,对于我们的底层代码是不需要改变的

官方在驱动代码中并没有给出对应模块的.h和引脚定义

所以在比赛时我们需要自己写一个.h文件,

而引脚定义因为15届原理图的改变可以很方便的找到对应引脚

但我们需要注意超声波的引脚定义,这里不用像15届之前的原理图一样和对应的相反

我在下面超声波板块会详细说明


2.1 DS1302 时钟芯片(十进制版)

这样写底层,在主程序中就就可以定义10进制的时钟数组eg:Rtc[3] = {23, 59, 55};

/*	# 	DS1302代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/								
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "ds1302.h"

sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;

//
void DS1302_Write_Rtc(unsigned char *pRtc)
{
    unsigned char i = 0;            //循环专用变量
    unsigned char temp = 0x00;      //写入中间变量
    Write_Ds1302_Byte(0x8e, 0x00);  //关闭写保护
    for(i = 0; i < 3; i++)
    {
        temp = ((pRtc[i]/10) << 4) | (pRtc[i] % 10);//转化为16进制
        Write_Ds1302_Byte(0x84 - 2*i, temp);//写入时钟
    }
    Write_Ds1302_Byte(0x8e, 0x80);  //开启写保护
}
//
void DS1302_Read_Rtc(unsigned char *pRtc)
{
    unsigned char i = 0;            //循环专用变量
    for(i = 0; i < 3; i++)
        pRtc[i] = (Read_Ds1302_Byte(0x85-2*i)/16*10) + (Read_Ds1302_Byte(0x85-2*i)%16);//读取时间,转化为10进制   
}

2.2 DS18B20 温度转换芯片

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include "onewire.h"

sbit DQ = P1^4;

float DS18B20_Read_T()
{
    unsigned char low, high;
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0xbe);
    low = Read_DS18B20();
    high = Read_DS18B20();
    
    return (((high << 8) | low) / 16.0);
}

2.3 PCF8591 AD-DA转换

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "iic.h"

sbit sda = P2^1;
sbit scl = P2^0;

//
unsigned char AD_Read(unsigned char addr)
{
    unsigned char Temp;
    I2CStart();
    I2CSendByte(0x90);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CStart();
    I2CSendByte(0x91);
    I2CWaitAck();
    Temp = I2CReceiveByte();
    I2CSendAck(1);
    I2CStop();
    return Temp;
}
//
void DA_Write(unsigned char dat)
{
    I2CStart();
    I2CSendByte(0x90);
    I2CWaitAck();
    I2CSendByte(0x41);
    I2CWaitAck();
    I2CSendByte(dat);
    I2CWaitAck();
    I2CStop();
}

2.4 NE555 频率测量

ne555会用到定时器0,所以当考到ne555的时候,主程序要选择其他定时器使用

还有要注意用跳线帽将P34和SIGNAL连接,顺便提醒一下大家,如果将P34和SIGNAL连接了

那按键的S16,S17,S18,S19是不能用的,所以题目也不会这样出,大家注意一点就好

当考到NE555的时候,我们需要将Key.c内,对P34操作为0的那一行屏蔽掉

2.4.1 定时器0初始化

我们只需要stc-isp生成一个定时器0 12MHz,1ms,16位自动重装载值代码,12T

然后将TL0和TH0都赋为0x00,并加上 TMOD |= 0x05

而我们只是需要用到它的计数功能,用不上中断,

所以不用加上EA = 1; ET0 = 1;

/* 定时器初始化函数 */
void Timer0_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x05;			//设置定时器模式
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0x00;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

2.4.2 NE555在main.c内的程序

注意用的是unsigned int!!!不要用成char了

#include <STC15F2K60S2.H>

unsigned int Freq, Timer1_1000ms;                   //实时频率测量, 定时器1000ms计时专用变量

/* 定时器初始化函数 */
void Timer0_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x05;			//设置定时器模式
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0x00;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}
void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
    ET1 = 1;
    EA  = 1;
}

/* 定时器中断服务函数 */
void Timer1_Serve() interrupt 3
{
    if (++Timer1_1000ms == 1000) //1秒计时
    {
        Freq = (TH0 << 8) | TL0;    //获取频率
        Timer1_1000ms = TH0 = TL0 = 0;
    }

}

2.5 AT24C02   EEPROM写入读取

为了防止在第一次上电时读出数据错误,则可以加一个PIN验证

这个是我写第九届国赛前面的PIN验证,算是实例了

虽然i2c的底层驱动代码有点变化,但是咱的底层是不用改变的

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include <intrins.h>
#include "iic.h"

sbit sda = P2^1;
sbit scl = P2^0;


//
void EEPROM_Write(unsigned char *pAT, addr, num)
{
    I2CStart();
    I2CSendByte(0xA0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    while(num--)
    {
        I2CSendByte(*pAT++);
        I2CWaitAck();
        I2C_Delay(200);
    }
    I2CStop();
}
//
void EEPROM_Read(unsigned char *pAT, addr, num)
{
    I2CStart();
    I2CSendByte(0xA0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    
    I2CStart();
    I2CSendByte(0xA1);
    I2CWaitAck();
    while(num--)
    {
        *pAT++ = I2CReceiveByte();
        if(num) I2CSendAck(0);
        else I2CSendAck(1);
    }
    I2CStop();
}

2.6 超声波(PCA)

2.6.1 引脚定义(P10,P11)

注意15届原理图是在这个位置给的是对我们用户来说的

所以超声波的引脚对应对应不用再和之前一样要tx对rx

即引脚对应为


2.6.2 超声波底层代码(Uwave.c)

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

sbit Tx = P1^0;
sbit Rx = P1^1;

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}

void Uwave_Init()
{
    unsigned char i = 0;
    for (i = 0; i < 8; i++)
    {
        Tx = 1;
        Delay12us();
        Tx = 0;
        Delay12us();
    }
}

unsigned char Uwave_Read()
{
    unsigned int time = 0;
    CMOD = 0x00;
    CH = CL = 0;//计数清零
    Uwave_Init();
    CR = 1; //开始计数
    while ((Rx == 1) && (CF == 0));
    CR = 0; //停止计数
    if (CF == 1)
    {
        CF = 0;
        return 0;
    }
    else
    {
        time = (CH << 8) | CL;
        return (unsigned char)(time * 0.017);
    }
}

2.7 Uart串口(重定向版)

串口使用重定向

在main.c中就只需要使用printf函数即和打印数据

但是一定要把串口中断写出来

不管你是否要接收数据,否则在打印之后程序卡死


2.7.1 Uart.c

#include <STC15F2K60S2.H>
#include "Uart.h"
#include <stdio.h>

void Uart_Init(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xE6;			//设置定时初始值
	T2H = 0xFF;			//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
    ES = 1;             //串口中断开启
    EA = 1;             //总中断开启
}

/* 重定向 */
extern char putchar (char ch)
{
    SBUF = ch;
    while(TI == 0);
    TI = 0;
    return ch;
}

2.7.2 main.c

/* 变量创建区 */
unsigned char Uart_Rx_Index;                //串口接收指针
unsigned char Uart_Rx_Buf[20];              //串口接收缓冲区
unsigned char Uart_Ticks;                   //串口计时
bit Uart_Rx_Flag;                           //串口接收数据标志位

/* 串口处理函数 */
void Uart_Deal()
{
    if (!Uart_Rx_Index) return;
    
    if (Uart_Ticks > 10)
    {
        Uart_Ticks = Uart_Rx_Flag = 0;
        /* 逻辑处理区 */


        
        /* 逻辑处理结束 */
        memset(Uart_Rx_Buf, 0, Uart_Rx_Index);
        Uart_Rx_Index = 0;
    }
}

/* 中断服务函数 */
//定时器1中断服务函数
void Timer1_Serve() interrupt 3
{
    if (++Slow_Down == 400) Slow_Down = Infor_Slow_FLag = 0;
    if (Slow_Down % 10 == 0) Key_Slow_FLag = 0;
    if (Slow_Down % 20 == 0) LED_Slow_FLag = 0;
    if (Slow_Down % 100 == 0) Seg_Slow_FLag = 0;
    Seg_Show(Slow_Down%8, Seg_Buf[Slow_Down%8], Seg_Point[Slow_Down%8]);
    LED_Show(Slow_Down%8, LED_Buf[Slow_Down%8]);
    
    //串口空闲处理
    if (Uart_Rx_Flag && ++Uart_Ticks > 10)
        Uart_Ticks = 11;
}
//串口中断服务函数
void Uart_Serve() interrupt 4
{
    /* 数据接收区 */
    if (RI == 1)
    {
        Uart_Ticks = RI = 0;
        Uart_Rx_Flag = 1;
        Uart_Rx_Buf[Uart_Rx_Index++] = SBUF;
    }
    /* 数据接收错误处理 */
    if (Uart_Rx_Index > 15)    //最好是比数组的小,以防越界访问
    {
        memset(Uart_Rx_Buf, 0, 20);
        /* 接收错误处理区 */
        
        /* 处理结束 */
        Uart_Rx_Index = 0;
        Uart_Ticks = Uart_Rx_Flag = 0;
    }
}
  • 64
    点赞
  • 204
    收藏
    觉得还不错? 一键收藏
  • 31
    评论
以下是单片机LCD1602的代码: ```c #include <reg52.h> // 导入STC单片机头文件 #define LCD1602_DB P0 // LCD1602数据线所在的P0口 sbit LCD1602_RS = P2 ^ 0; // LCD1602的RS引脚所在的P2.0口 sbit LCD1602_RW = P2 ^ 1; // LCD1602的RW引脚所在的P2.1口 sbit LCD1602_E = P2 ^ 2; // LCD1602的E引脚所在的P2.2口 void delay(unsigned int i) // 延时函数 { while (i--) ; } void write_com(unsigned char com) // 写指令函数 { LCD1602_RS = 0; // 将RS引脚置为0,表示写入指令 LCD1602_RW = 0; // 将RW引脚置为0,表示写入模式 LCD1602_DB = com; // 将指令写入数据线 LCD1602_E = 1; // 将E引脚置为1,表示允许写入 delay(100); // 延时一段时间(至少50ns) LCD1602_E = 0; // 将E引脚置为0,表示禁止写入 } void write_data(unsigned char dat) // 写数据函数 { LCD1602_RS = 1; // 将RS引脚置为1,表示写入数据 LCD1602_RW = 0; // 将RW引脚置为0,表示写入模式 LCD1602_DB = dat; // 将数据写入数据线 LCD1602_E = 1; // 将E引脚置为1,表示允许写入 delay(100); // 延时一段时间(至少50ns) LCD1602_E = 0; // 将E引脚置为0,表示禁止写入 } void init() // 初始化函数 { write_com(0x38); // 设置显示模式为2行,5*7点阵 write_com(0x0c); // 设置显示模式为开,光标不显示,不闪烁 write_com(0x06); // 设置输入方式为移动光标,不移动屏幕 write_com(0x01); // 清屏 } void main() { init(); // 执行初始化 write_data('H'); // 写入字符'H' write_data('e'); // 写入字符'e' write_data('l'); // 写入字符'l' write_data('l'); // 写入字符'l' write_data('o'); // 写入字符'o' write_data(','); // 写入字符',' write_data('W'); // 写入字符'W' write_data('o'); // 写入字符'o' write_data('r'); // 写入字符'r' write_data('l'); // 写入字符'l' write_data('d'); // 写入字符'd' while (1) // 主循环 ; } ``` 以上代码使用STC单片机,通过P0口连接1602液晶屏,实现在液晶屏上显示"Hello, World"的功能。其中,`write_com()`函数用于写入指令,`write_data()`函数用于写入数据,`init()`函数用于初始化。在`main()`函数中,先执行初始化,然后逐个写入字符。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值